LSM303AGR mems reading problems.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-05-30 2: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 #read- Labels:
-
Accelerometers
-
I2C
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-05-30 4:19 AM
Can you share your source code?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-05-30 5: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++; }}- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-01 3: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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2017-06-01 4:11 AM
Thank you very much,
I was going crazy
only for twobrackets
!Thank you, problem solved!
