Carter John
/
LSM303DLHC_magnetometer_example
An example on how to read raw data
Diff: main.cpp
- Revision:
- 0:fb4503358bc7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Jul 20 08:41:07 2017 +0000 @@ -0,0 +1,139 @@ +#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"); + } + } + } +} \ No newline at end of file