Shop OBEX P1 Docs P2 Docs Learn Events
Scaling Accelerometer Output — Parallax Forums

Scaling Accelerometer Output

SRLMSRLM Posts: 5,045
edited 2014-10-13 06:06 in Propeller 1
I have an LSM303DLHC accelerometer (product page), and it has a built in three axis accelerometer. I can successfully read it, and I get the following values (taken from a selection on the bus, as told by reading the I2C bus with a logic analyzer):

z: 0000010101100000 = 1376 decimal
z: 0000010100110000 = 1328
x: 1111111111010000 = -48
z: 0000010101110000 = 1392
x: 0000000000010000 = 16
y: 0000000000000000 = 0
z: 0000010101110000 = 1392

The accelerometer is resting flat on the table, so the X and Y axes should be 0, while the Z axis should be 1 g. The accelerometer is in high resolution +-16g mode.

The datasheet says that there is a sensitivity of 12 mg/LSB (in +- 16 g mode). So, if I multiply the reading that I expect to be ~1.0g, then I get

1376 * 0.012g = 16.512g

Which is obviously too much. What is the algorithm to get the reading more reasonable?

Comments

  • John AbshierJohn Abshier Posts: 1,116
    edited 2013-03-09 19:15
    I think g stands for acceleration of gravity not grams. 1g - 32.2 feet/sec^2. 16.5i2 feet/sec^2 is about half of what I would expect. At least that is just a simple number (2) from what you want.

    John Abshier
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-03-09 19:48
    Did you see section 2.6.1?
    It suggests taking two readings with the accelerometer rotated 180 to establish 1g and also to measure its sensitivity.

    So maybe your supposed to use the technique to come up with your own conversion factor?

    BTW, Wouldn't the +-2g mode be higher resolution than the the +-16g mode? You'd of course loose range of detection by using the 2g mode but I'd think 16-bits over a 4g range (-2 to +2) would offer more precision that the same 16-bits over a 32g range.
  • SRLMSRLM Posts: 5,045
    edited 2013-03-28 12:14
    Ok, I think I have figured it out. The LSM303DLHC uses a 12 bit ADC on board, and stores the result in the upper 12 bits of the 16 bit output word. So, the value 1392(decimal) needs to be right shifted by 4, resulting in 87(decimal). 87*0.012 => 1.044g, which is exactly what I'm looking for.

    I'm basing this on the sample Arduino code from Pololu: https://github.com/pololu/LSM303/blob/master/LSM303/LSM303.cpp
    byte xla = Wire.read();
      byte xha = Wire.read();
      byte yla = Wire.read();
      byte yha = Wire.read();
      byte zla = Wire.read();
      byte zha = Wire.read();
    
      // combine high and low bytes, then shift right to discard lowest 4 bits (which are meaningless)
      // GCC performs an arithmetic right shift for signed negative numbers, but this code will not work
      // if you port it to a compiler that does a logical right shift instead.
      a.x = ((int16_t)(xha << 8 | xla)) >> 4;
      a.y = ((int16_t)(yha << 8 | yla)) >> 4;
      a.z = ((int16_t)(zha << 8 | zla)) >> 4;
    

    I couldn't find any documentation on this feature, but it seems to work.

    re High Resolution Mode: the CTRL_REG4_A (23h) register has a bit that enables high resolution mode. What does that mean? I have no idea: it's not documented anywhere in the datasheet. But, I think I'd prefer high resolution, so I enabled it.

    And, my guess is that the +-16g mode does not use the full 12 bit range of values. This is from the linear acceleration sensitivity table:
    FS bit set to 00           1 mg/LSB
    FS bit set to 01           2
    FS bit set to 10           4
    FS bit set to 11           12
    

    For each of the first three levels, the +-g count doubles and the resolution halves. For the +-16 level, the +-g range doubles but the resolution is less than 1/2 the previous. In any case, just an interesting note.
  • pgbpsupgbpsu Posts: 460
    edited 2014-10-12 19:46
    SRLM-
    Did you ever get spin code working for this device? If so, do you mind posting it? I've got the same device and I've not been able to get it working. I'm pretty sure it's my implementation of the I2C stuff, but I'm using Mike Green's object and it still doesn't work. It's be nice to test it with some code that is known to work before concluding there's a hardware problem.

    Thanks,
    Peter
  • SRLMSRLM Posts: 5,045
    edited 2014-10-12 20:09
    @pgbpsu

    I never tried for Spin code. Instead, I went for libpropeller C++ code. That's open source, and can be found here: https://github.com/libpropeller/libpropeller/blob/master/libpropeller/lsm303dlhc/lsm303dlhc.h
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-10-13 06:06
    Pgbpsu, are you getting any sort of response from the chip? Included in this archive is a I2C poller routine that'll display the 7-bit address of everything on the I2C bus. The accelerometer should show up at address %001_1001, and the magnetometer at %001_1110. Mke Green's drivers require the 8-bit address--the 7-bit address shifted left one with a read/write bit appended--so %0011_0010 for the accelerometer and %0011_1100 for the magnetometer.

    The only oddity I notice in this chip is that bit-7 of the register address needs to be set in order to auto-increment.

    See if this gets any readings:
    LSM303DLHC demo - Archive.zip

    Chris
Sign In or Register to comment.