2017-05-30 02:39 AM
I'm working on LSM303AGR mems and I've some reading problems: when I read x, y, z accelerometer registers in 'normal mode' I get lots of 0 and sometimes a correct value (z value have to be about 1G, not 0), when I set 'low-power' mode everything works good.
Any ideas?
Thank you.
NF
P.S. Attached I leave two example: work.png is in 'low-power mode', the other is in 'normal mode'.
#mems #i2c #accelerometer #sensor #lsm303agr #read2017-05-30 04:19 AM
Can you share your source code?
2017-05-30 05:19 PM
Here the code:
int main() {
uint64_t i = 0; int16_t dx = 0, dy = 0, dz = 0; byte data = 0x00, b = 0x00, hx = 0x00, lx = 0x00, hy = 0x00, ly = 0x00, hz = 0x00, lz = 0x00; double fx = 0., fy = 0., fz = 0.;single_write(LSM303AGR_ACC_CTRL_REG1, 0x27); //write single byte on register
single_write(LSM303AGR_ACC_CTRL_REG2, 0x00); single_write(LSM303AGR_ACC_CTRL_REG3, 0x00); single_write(LSM303AGR_ACC_CTRL_REG4, 0x80); wait(1); while(1){ b = single_read(LSM303AGR_ACC_STATUS_REG2); if(b&0x01) { lx = single_read(LSM303AGR_ACC_OUT_X_L); hx = single_read(LSM303AGR_ACC_OUT_X_H); dx = (int16_t)((uint16_t)(((uint16_t)hx)<<8+((uint16_t)lx))); fx = (double)(2. / 32768.) * (double)dx; pc.printf('\tX READY: x=%d\t\t\tfx=%lf\r\n', dx, fx); } if(b&0x02) { ly = single_read(LSM303AGR_ACC_OUT_Y_L); hy = single_read(LSM303AGR_ACC_OUT_Y_H); dy = (int16_t)((uint16_t)(((uint16_t)hy)<<8+((uint16_t)ly))); fy = (double)(2. / 32768.) * (double)dy; pc.printf('\tY READY: y=%d\t\t\tfy=%lf\r\n', dy, fy); } if(b&0x04) { lz = single_read(LSM303AGR_ACC_OUT_Z_L); hz = single_read(LSM303AGR_ACC_OUT_Z_H); dz = (int16_t)((uint16_t)(((uint16_t)hz)<<8+((uint16_t)lz))); fz = (double)(2. / 32768.) * (double)dz; pc.printf('\tZ READY: z=%d\t\t\tfz=%lf\r\n', dz, fz); } wait(0.01); i++; }}2017-06-01 03:11 AM
The problem is in the following line
dx = (int16_t)((uint16_t)(((uint16_t)hx)<<8+((uint16_t)lx))); brackets are missing around the shift. So if the lx, ly, lz is not zero, which is the case of 'normal mode' you shift the value out of the int16 range.
Use following code
dx = (int16_t)((uint16_t)((((uint16_t)hx)<<8)+((uint16_t)lx)));
or much simpler
dx = ((int16_t)hx<<8)+(uint16_t)lx;
2017-06-01 04:11 AM
Thank you very much,
I was going crazy
only for twobrackets
!Thank you, problem solved!