GithubHelp home page GithubHelp logo

bmi323_sensorapi's Introduction

BMI3 Sensor API

This package contains SensorAPIs for BMI323 Sensor

Sensor Overview

The BMI323 is a highly integrated, low power inertial measurement unit (IMU) that combines precise acceleration and angular rate (gyroscopic) measurement with intelligent on-chip motion-triggered interrupt features. Feature set can be optimized for wearable, hearable and mobile applications via API

##BMI323 This sensor will work on smart phone, wearable and hearable(Context parameter)

The following are the features listed in BMI323:

  • Any motion
  • No motion
  • Alternate configurations
  • Flat
  • I3C sync
  • Orientation
  • Self-test
  • Self-calibration
  • Step counter
  • Step detector
  • Tilt
  • Significant motion
  • Tap
    • Single tap
    • Double tap
    • Triple tap

bmi323_sensorapi's People

Contributors

bst-github-admin avatar kegov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

bmi323_sensorapi's Issues

Extremely low gyroscope sensitivity

Hi, I'm using 01/03/2023 drivers over BMI323 and am facing extremely low gyroscope sensitivity.

I'm using the below code on my c# project to catch ReadingChanged events. Right now, I have to make large movements with my device to get any events to raise.

var sensor = Gyrometer.GetDefault();
sensor.ReadingChanged += ReadingChanged;

image

Limited range with Arduino implementation

Hello,
I'm working on a Shuttle Board 3.0 BMI323 associated with an Arduino Uno R3. My problem is when I read X, Y or Z axis, the return value sould be between 0 and 65535 (2^16). But my usable range is from 49152 to 16384 (around 2^15), the other part (from 16385 to 49151) is never returned, do you know why ? Here is my last version of code:

#include <Wire.h>
#include <DAC7574.h>

typedef enum{
  ouput45     = 0b00,
  ouput90     = 0b01,
  ouputRotab  = 0b10,
  autre       = 0b11
}OutputType;


//DAC
#define DAC_ADDRESS 0x4C
//Inclino
#define INC_ADDRESS 0x68
#define ACC_CONF  0x20  //Page 91
#define GYR_CONF  0x21  //Page 93
#define CMD       0x7E  //Page 65

/*! Earth's gravity in m/s^2 */
#define GRAVITY_EARTH  (9.80665f)

uint16_t x, y, z;
uint16_t gyr_x, gyr_y, gyr_z;
uint16_t gyro_angle_x, gyro_angle_y, gyro_angle_z;
uint16_t combined_x, combined_y, combined_z;
float roll, pitch, yaw = 0.f;

uint16_t  temperature = 0;
float     temperatureInDegree = 0.f;

//DAC
DAC7574 dac;

float angle45 = 0;
float angle45f = 0;
double xAngle = 0;
float angle90 = 0;
float angle90f = 0;
uint32_t analogAngle45 = 0;
uint32_t analogAngle90 = 0;

int angle_90 = 180;
int outputMaxValue90 = 3680;  //3600
int outputMinValue90 = 395;   //395
float angle_45_min = -51.f;
float angle_45_max = 51.f;
float angle_45 = abs(angle_45_min) + abs(angle_45_max);

///int outputMaxValue45 =  3725;//3844; //3807;  //3600
///int outputMinValue45 =  232;//241;  //234;   //395

int outputMaxValue45 =  3725;
int outputMinValue45 =  232;

float analogMiddle45  = (outputMaxValue45-outputMinValue45)*0.5 + outputMinValue45;    
float analogMiddle90  = (outputMaxValue90-outputMinValue90)*0.5 + outputMinValue90;  

unsigned long timer = 0;
int divider = 1;

float print_ms = 200;

void setup(void) {  
  Serial.begin(115200); 
  //Accelerometer
  Wire.begin();  
  //Wire.setClock(400000);      // I2C Fast Mode (400kHz)  
  timer = millis();
  print_ms = millis();
  softReset();  
  /*
   * Acc_Conf P.91
   * ODR:         0x000B  -> 800Hz
   * range:       0x0000  -> 2G
   * filtering:   0x0000  -> ODR/2
   * average:     0x0600  -> 64 sample
   * mode:        0x7000  -> High
   * Total:       0x760B
   * 0111000000001011
   */
  writeRegister16(ACC_CONF,0x760B);//Setting accelerometer  
  /*
   * Gyr_Conf P.93
   * mode:        0x7000  -> High
   * average:     0x0600  -> 64
   * filtering:   0x0000  -> ODR/2
   * range:       0x0000  -> 125kdps
   * ODR:         0x000B  -> 800Hz
   * Total:       0x760B
   */
  writeRegister16(GYR_CONF,0x760B);//Setting gyroscope    

  delay(50);    
  
  //DAC
  dac.begin(DAC_ADDRESS);
}

void softReset(){  
  writeRegister16(CMD, 0xDEAF);
  delay(50);    
}

void loop() {
  static float deltat = 0;  //loop time in seconds
  static unsigned long now = 0, last = 0; //micros() timers

  if(readRegister16(0x02) == 0x00) {
    //Read ChipID
    //Serial.print("ChipID:");
    //Serial.print(readRegister16(0x00));       
    convertToAngle();

    if(millis() - print_ms > 0){
      print_ms = millis();
      //*
      Serial.print("x:");
      Serial.print(x);
      Serial.print(" \ty:");
      Serial.print(y);
      Serial.print(" \tz:");
      Serial.print(z);
      Serial.print(" \tangle45f:");
      Serial.print(angle45f);
      //*/
     
      Serial.println();
    }
  }
  
  //Write to DAC
  dac.setVoltage(analogAngle45, ouput45);
  dac.setVoltage(analogAngle90, ouput90);
}

//Write data in 16 bits
void writeRegister16(uint16_t reg, uint16_t value) {
  Wire.beginTransmission(INC_ADDRESS);
  Wire.write(reg);
  //Low 
  Wire.write((uint16_t)value & 0xff);
  //High
  Wire.write((uint16_t)value >> 8);
  Wire.endTransmission();
}

//Read data in 16 bits
uint16_t readRegister16(uint8_t reg) {
  Wire.beginTransmission(INC_ADDRESS);
  Wire.write(reg);
  Wire.endTransmission(false);
  int n = Wire.requestFrom(INC_ADDRESS, 4);  
  uint16_t data[20];
  int i =0;
  while(Wire.available()){
    data[i] = Wire.read();
    i++;
  }  
  return (data[3]   | data[2] << 8);
}

//Read all axis
void readAllAccel() {
  Wire.beginTransmission(INC_ADDRESS);
  Wire.write(0x03);
  Wire.endTransmission();
  Wire.requestFrom(INC_ADDRESS, 16);
  uint16_t data[16];
  int i =0;
  while(Wire.available()){
    data[i] = Wire.read();
    i++;
  }

  //Offset = 2 because the 2 first bytes are dummy (useless)
  int offset = 2;  
  
  //*
  x =             ((uint16_t) (data[offset + 1] << 8   | (uint16_t) data[offset + 0]));  //0x03
  y =             ((uint16_t) (data[offset + 3] << 8   | (uint16_t) data[offset + 2]));  //0x04
  z =             ((uint16_t) (data[offset + 5] << 8   | (uint16_t) data[offset + 4]));  //0x05
  //*/
  
  gyr_x =         ((uint16_t) data[offset + 7] << 8   | (uint16_t) data[offset + 6]);  //0x06
  gyr_y =         ((uint16_t) data[offset + 9] << 8   | (uint16_t) data[offset + 8]);  //0x07
  gyr_z =         ((uint16_t) data[offset + 11] << 8  | (uint16_t) data[offset + 10]); //0x08
  temperature =   ((uint16_t) data[offset + 13] << 8  | (uint16_t) data[offset + 12]); //0x09
}

void convertToAngle(){
  double offsetAngle = 1.00;  //Arround 6% less (ex: 42° for 45°)
  analogAngle45 = 0;
  analogAngle90 = 0;
  divider = 50;
  for(int i = 0; i < divider; i++){
    readAllAccel();             // read all accelerometer/gyroscope/temperature data  
    angle45f  = (atan2(-(double)lsb_to_mps2(x, 2, 16),(double)lsb_to_mps2(z, 2, 16) )*180/PI)*offsetAngle;
    angle90f  = (atan2(-(double)lsb_to_mps2(y, 2, 16),(double)lsb_to_mps2(z, 2, 16) )*180/PI)*offsetAngle;

    //*
    if(angle45f >= angle_45_max){ //angle_45*0.51){
      angle45f = angle_45_max;
    }else if (angle45f <= angle_45_min){ //-angle_45*0.5){
      angle45f = angle_45_min;
    }//*/
  
    if(angle90f > angle_90*0.5){
      angle90f = angle_90*0.5;
    }else if (angle90f < -angle_90*0.5){
      angle90f = -angle_90*0.5;
    }

    //Analog: 3725 | 1960 | 232
    //  Réel: 3806 | 2001 | 234
    float angleToAnalog45 = (outputMaxValue45 - outputMinValue45)/(angle_45);// 17.805/° pour 90°; 35.61/° pour 45°  
    float angleToAnalog90 = (outputMaxValue90 - outputMinValue90)/(angle_90);// 17.805/° pour 90°; 35.61/° pour 45°  
    float correctif = 0.06f;
    float smoother45 = angle45f*(1-correctif) + angle45f*correctif;
    float smoother90 = angle90f*(1-correctif) + angle90f*correctif;
    analogAngle45 += ((smoother45 * angleToAnalog45) + analogMiddle45);//
    analogAngle90 += ((smoother90 * angleToAnalog90) + analogMiddle90);// 
    //analogAngle45 += ((angle45f * angleToAnalog45) + analogMiddle45);//
    //analogAngle90 += ((angle90f * angleToAnalog90) + analogMiddle90);// 
  }
  analogAngle45 = analogAngle45/divider;
  analogAngle90 = analogAngle90/divider;
}

/*!
 * @brief This function converts lsb to meter per second squared for 16 bit accelerometer at
 * range 2G, 4G, 8G or 16G.
 */
static float lsb_to_mps2(int16_t val, int8_t g_range, uint8_t bit_width){
    double power = 2;
    float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f));
    return (GRAVITY_EARTH * val * g_range) / half_scale;
}

I'm also using a DAC with I²C communication but I've tried without it and nothing changed.
Do you know how can I get the full output from 0 to 65535 for every axis/data ?
Thanks for your help ! 🙏

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.