An example on how to read raw data

Dependencies:   mbed

main.cpp

Committer:
ElectronicsSanta
Date:
2017-07-20
Revision:
0:fb4503358bc7

File content as of revision 0:fb4503358bc7:

#include "mbed.h"
#include <algorithm> // for min, max functions

#define MAGN_I2C_ADDRESS (0x1E << 1)

#define LSM303_REGISTER_MAG_OUT_X_H_M 0x03 
#define LSM303_REGISTER_MAG_OUT_X_L_M 0x04 
#define LSM303_REGISTER_MAG_OUT_Z_H_M 0x05 
#define LSM303_REGISTER_MAG_OUT_Z_L_M 0x06 
#define LSM303_REGISTER_MAG_OUT_Y_H_M 0x07 
#define LSM303_REGISTER_MAG_OUT_Y_L_M 0x08

#define LSM303_REGISTER_MAG_CRA_REG_M    0x00
#define LSM303_REGISTER_MAG_CRB_REG_M    0x01
#define LSM303_REGISTER_MAG_MR_REG_M     0x02
#define LSM303_REGISTER_MAG_OUT_X_H_M    0x03
#define LSM303_REGISTER_MAG_OUT_X_L_M    0x04
#define LSM303_REGISTER_MAG_OUT_Z_H_M    0x05
#define LSM303_REGISTER_MAG_OUT_Z_L_M    0x06
#define LSM303_REGISTER_MAG_OUT_Y_H_M    0x07
#define LSM303_REGISTER_MAG_OUT_Y_L_M    0x08
#define LSM303_REGISTER_MAG_SR_REG_Mg    0x09
#define LSM303_REGISTER_MAG_IRA_REG_M    0x0A
#define LSM303_REGISTER_MAG_IRB_REG_M    0x0B
#define LSM303_REGISTER_MAG_IRC_REG_M    0x0C
#define LSM303_REGISTER_MAG_TEMP_OUT_H_M 0x31
#define LSM303_REGISTER_MAG_TEMP_OUT_L_M 0x32

                                            // MD1 MD0
#define LSM303_REGISTER_MAG_MR_REG_CCM 0x00 //   0   0 = continuous-conversion mode
#define LSM303_REGISTER_MAG_MR_REG_SCM 0x01 //   0   1 = single-conversion mode
#define LSM303_REGISTER_MAG_MR_REG_SM  0x02 //   0   1 = sleep-mode. device is placed in sleep-mode

#define LSM303_REGISTER_MAG_CRA_REG_M_0_75HZ (0 << 2) // 0.75 Hz
#define LSM303_REGISTER_MAG_CRA_REG_M_1_5HZ  (1 << 2) // 1.5 Hz
#define LSM303_REGISTER_MAG_CRA_REG_M_3_0HZ  (2 << 2) // 3.0 Hz
#define LSM303_REGISTER_MAG_CRA_REG_M_7_5HZ  (3 << 2) // 7.5 Hz
#define LSM303_REGISTER_MAG_CRA_REG_M_15HZ   (4 << 2) // 15 Hz
#define LSM303_REGISTER_MAG_CRA_REG_M_30HZ   (5 << 2) // 30 Hz
#define LSM303_REGISTER_MAG_CRA_REG_M_75HZ   (6 << 2) // 75 Hz
#define LSM303_REGISTER_MAG_CRA_REG_M_220HZ  (7 << 2) // 220 Hz

#define LSM303_MULTIPLE_REGISTER_READS (1 << 7) // MSB set to 1 in the command is telling the LSM303 to increment the register pointer after each read/write (https://www.pololu.com/product/1268)

Serial serial(SERIAL_TX, SERIAL_RX);
I2C i2c(I2C_SDA, I2C_SCL); // PB_9, PB_8
Timer elapsed_time;

int16_t x;
int16_t y;
int16_t z;
bool magn_found = false;

uint8_t i2c_read8_reg(uint8_t address, int8_t reg) {
    char i2cBuffer[1];
    i2cBuffer[0] = reg;
    i2c.write(address, i2cBuffer, 1);

    i2c.read(address, i2cBuffer, 1);

    return (uint8_t)i2cBuffer[0];
}

void i2c_write8_reg(uint8_t address, int8_t reg, int8_t value) {
    char i2cBuffer[2];
    i2cBuffer[0] = reg;
    i2cBuffer[1] = value;
    i2c.write(address, i2cBuffer, 2);
}

void read_magn() {
    char i2cBuffer[1];

    i2cBuffer[0] = LSM303_REGISTER_MAG_OUT_X_H_M;
    i2c.write(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    i2c.read(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    x = (i2cBuffer[0] << 8);

    i2cBuffer[0] = LSM303_REGISTER_MAG_OUT_X_L_M;
    i2c.write(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    i2c.read(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    x |= i2cBuffer[0];

    i2cBuffer[0] = LSM303_REGISTER_MAG_OUT_Y_H_M;
    i2c.write(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    i2c.read(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    y = (i2cBuffer[0] << 8);

    i2cBuffer[0] = LSM303_REGISTER_MAG_OUT_Y_L_M;
    i2c.write(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    i2c.read(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    y |= i2cBuffer[0];

    i2cBuffer[0] = LSM303_REGISTER_MAG_OUT_Z_H_M;
    i2c.write(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    i2c.read(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    z = (i2cBuffer[0] << 8);

    i2cBuffer[0] = LSM303_REGISTER_MAG_OUT_Z_L_M;
    i2c.write(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    i2c.read(MAGN_I2C_ADDRESS, i2cBuffer, 1);
    z |= i2cBuffer[0];
}

int main() {
    serial.baud(115200);
    i2c.frequency((uint32_t)100e3);

    serial.printf("LSM303DLHC magnetometer example...\n");

    // set the magnetometer data output rate (Hz)
    i2c_write8_reg(MAGN_I2C_ADDRESS, LSM303_REGISTER_MAG_CRA_REG_M, LSM303_REGISTER_MAG_CRA_REG_M_3_0HZ);

    // read the magnetometer register for the value we set above
    uint8_t default_val = i2c_read8_reg(MAGN_I2C_ADDRESS, LSM303_REGISTER_MAG_CRA_REG_M);

    if (default_val == LSM303_REGISTER_MAG_CRA_REG_M_3_0HZ) {
        magn_found = true;
        serial.printf("magn found\n");
    } else {
        serial.printf("magn NOT found\n");
    }

    if (magn_found) {
        // enable the magnetometer
        i2c_write8_reg(MAGN_I2C_ADDRESS, LSM303_REGISTER_MAG_MR_REG_M, LSM303_REGISTER_MAG_MR_REG_CCM);

        elapsed_time.start();

        while (true) {
            if (elapsed_time.read_ms() > 200) { // print every x ms
                read_magn();
                elapsed_time.reset();
                serial.printf("x: %d; y: %d; z: %d\n", x, y, z);
                serial.printf("**************************\n");
            }
        }
    }
}