0

I would like to read some register from a LSM6DSO32 captor. But I've a problem for me tha values I got are strange. I user Atmel SAMD21 Cortex M0 and i2C for communicate with the captor. First off all I set my captor to 8g and 500° for gyroscope like that

#define DSO_ADDRESS 0x6A

void setup() {
  SerialUSB.begin(115200);
  while(!SerialUSB);

  Wire.begin(); 

 //gyro 500°
 Wire.beginTransmission(DSO_ADDRESS);
 Wire.write(0x11);                   
 Wire.write(0x44);                   
 Wire.endTransmission();     

 //accel 8g
 Wire.beginTransmission(DSO_ADDRESS);
 Wire.write(0x10);                   
 Wire.write(0x48);                   
 Wire.endTransmission();  
 }

For me this is works beceause if I read 0x10 after I get 0x48 value, and if I try to read who i am register I get the good value 0x6C.

After that I try to read registers value, my readSensor function

//gloabl variables to store values
int temperature;
int gyro_raw[3] = {0, 0, 0};
int acc_raw[3] = {0 , 0 , 0};

void readSensor(){
  Wire.beginTransmission(DSO_ADDRESS);
  Wire.write(0x20);                                     
  Wire.endTransmission();   
   Wire.requestFrom(DSO_ADDRESS, 14);

  uint8_t buff[14];   
  Wire.readBytes(buff, 14);

  temperature = buff[1] << 8 | buff[0];

  gyro_raw[X] = buff[3] << 8 | buff[2];
  gyro_raw[Y] = buff[5] << 8 | buff[4];
  gyro_raw[Z] = buff[7] << 8 | buff[6];

  acc_raw[X] = buff[9] << 8 | buff[8];
  acc_raw[Y] = buff[11] << 8 | buff[10];
  acc_raw[Z] = buff[13] << 8 | buff[12];
}

So if I called this function 2000 times for exemple to get an offset I got very strange values

long gyro_offset[3] = {0, 0, 0};
int max_samples = 500;

for (int i = 0; i < max_samples; i++) {
   readSensor();

   gyro_offset[X] += gyro_raw[X];
   gyro_offset[Y] += gyro_raw[Y];
   gyro_offset[Z] += gyro_raw[Z];

   delay(50);
}

gyro_offset[X] /= max_samples;
gyro_offset[Y] /= max_samples;
gyro_offset[Z] /= max_samples;

X Y and Z are defined by value 0,1 and 2. So if I print gyro_offset[X] I get value 23 for me this is normal, but for gyro_offset[Y] and gyro_offset[Z] I got a big value around 65514 and for me these aren't good no ?

simon
  • 1,180
  • 3
  • 12
  • 33
  • Maybe we need to convert the two raw bytes into a *signed* integer? Here: `gyro_raw[X] = buff[3] << 8 | buff[2]`. Or convert the resulting `gyro_offset` to signed? (i.e. 65535 means -1, so 65514 means -22). – aMike Mar 28 '21 at 15:38
  • Yes maybe you've right, I'll try to cast it like that for example : gyro_raw[X] = (int)buff[3] << 8 | (int)buff[2]; @aMike – simon Mar 28 '21 at 17:42
  • I've just try to cast result but I got the same result, I did it : ``gyro_raw[X] = ((int)buff[3] << 8) | (int)buff[2];`` but the result is same 65513 for Y and 65521 for Z, maybe these values are good but I doubt... If I move the captor while I calibrate the captor, the values change, for exemple I got 32879 32847 and 31311 – simon Mar 28 '21 at 18:06
  • 1
    The new casting isn't changing anything because the operands are super-sized into ints before the operation (since they're being assigned to an int). So... pseudo-code `if x > 65535 then x = x - 65536` Or bit test and subtract, or sign extend the high byte before the joining, or ... :-) – aMike Mar 29 '21 at 04:41
  • Ok great I'll try it, but for my own information how do sign extend the high byte before the joining ? @aMike – simon Mar 29 '21 at 06:26
  • Same kind of trick, or test the top bit and if set, OR in 0xFF00 (int) or 0xFFFFFF00 (long). There's probably some fun bit-op dances that do it automatically, too... And I just noticed a bug in my suggestion above - it should be `if x > 32767 then x -= 65536` Sorry 'bout that! – aMike Mar 29 '21 at 15:34

0 Answers0