0
\$\begingroup\$

I've was trying all afternoon yesterday to get some data out of my LSM303DLHC using an STM32L152 Nucleo board.

Finally I got all the I2C stuff down, managed to set some registers, verify their contents, etc. so I turned my attention to the data coming out.

No matter what I do it seems, the data is stuck at the same values. When I power cycle the sensor I get changes in the magnetometer values, but then they stay the same until I cycle it again. The outputs from the 3 accelerometer axes are always zero.

I've done a read of the 'block update' register and confirmed the IC it set to do continuous updates.

I have verified on a scope that what I'm receiving is correct to the protocol.

I'm using this breakout board: http://www.aliexpress.com/item/1-pcs-GY-511-LSM303DLHC-Module-E-Compass-3-Axis-Accelerometer-3-Axis-Magnetometer-Module-Sensor/1956617486.html

Any idea anyone? What am I doing wrong here?

#include "mbed.h"

#define ACC_ADDR 0x32
#define MAG_ADDR 0x3C

// ACC registers //
#define CTRL_REG1_A 0x20

#define ACC_X_L 0x28
#define ACC_X_H 0x29
#define ACC_Z_L 0x2C
#define ACC_Z_H 0x2D

// MAG registers //

#define CRA_REG_M 0x00 

#define MAG_X_H 0x03
#define MAG_X_L 0x04

#define MAG_TEMP_H 0x31 
#define MAG_TEMP_L 0x32

//------------------------------------
// Hyperterminal configuration
// 9600 bauds, 8-bit data, no parity
//------------------------------------

Serial pc(SERIAL_TX, SERIAL_RX);

DigitalOut led(LED1);
InterruptIn btn(USER_BUTTON);
I2C i2c(PB_9, PB_8);



int main()
{

    char data_write[2];
    char data_read[6] = {0,0};

    /* Turn on temp sensor */
    data_write[0] = CRA_REG_M ;
    data_write[1] = 0x90;
    int status = i2c.write(MAG_ADDR, data_write, 2, 0);
    if (status != 0) { // Error
        while (1) {
            led = !led;
            wait(0.2);
        }
    }

    int i = 0;
    int bytes = 6;
    int j;

    while (1) {


        // Read acceleromter data registers
        data_write[0] = ACC_X_L;
        i2c.write(ACC_ADDR, data_write, 1, 1); // no stop
        i2c.read(ACC_ADDR, data_read, bytes, 0);

        printf("\f");
        // Display result
        for(j=0;j<bytes;j++){
            printf("d: %x\n", data_read[j]);
        }
        printf("---- (%d)", i++);        

        led = 1;


        wait(0.1);

    }

}
\$\endgroup\$
1
\$\begingroup\$

Here is a snippet of my code that sets up the LSM303DLHC

void Sensors::power_up_compass_max_speed()
{
    //Acc 1344Hz ODR, high power, all on
    compass.writeAccReg(LSM303_CTRL_REG1_A, 0b10010111);
    //Acc high res
    compass.writeAccReg(LSM303_CTRL_REG4_A, 0b00001000);
    //Mag continuous conversion
    compass.writeMagReg(LSM303_MR_REG_M, 0x00);
    //Enable mag 220Hz update
    compass.writeMagReg(LSM303_CRA_REG_M, 0b00011100);
}

Port that and see if it works.

\$\endgroup\$
  • \$\begingroup\$ That seemed to do something. The accelerometer data I'm getting now though is pretty much nonsense. Just cycling between a few values and every axis is putting out the same. I think the magnetometer is working okay though. \$\endgroup\$ – Sensors May 28 '15 at 14:56
  • \$\begingroup\$ That is weird. The values come out low byte first and then high byte, so the low byte jumps around alot. You could try slowing down the acc, this does 8Hz compass.writeAccReg(LSM303_CTRL_REG1_A, 0b00100111); \$\endgroup\$ – geometrikal May 30 '15 at 3:08
  • \$\begingroup\$ Also could make sure status reg is set before reading: (LSM303_STATUS_REG_A & 0x0f) == 0x0f \$\endgroup\$ – geometrikal May 30 '15 at 3:09
  • \$\begingroup\$ BTW, Pololu has a LSM303 library for Arduino: github.com/pololu/lsm303-arduino \$\endgroup\$ – geometrikal May 30 '15 at 3:17
1
\$\begingroup\$

Perhaps this suggestion is too late, but it might help others.

I've found that whenever I am implementing a I2c design with a system I have not previously implanted I2C on, it is very helpful to start the development using a serial memory device. This makes testing of the I2C interface much easier.

When testing an I2c interface with a device such as an accelerometer, it is sometimes difficult to tell if the values you read make sense.

With a memory device, you can program a known pattern into the device, then test your I2C read functions by comparing what you read to the pattern you programmed into it.

I've tested my I2C functions by saving a pattern to the memory device, then reading from it for hours at a time ... it gave me much more confidence that my routines were error proof.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.