LSM303DLHC 3D accelerometer, 3D magnetometer and thermometer

Dependents:   MAPLEminiA MAPLEminiA

LSM303DLHC is 3D accelerometer and 3D magnetometer module

このチップのライブラリは既にいくつかあるみたいですが、どれも方位取得に特化していて加速度計だけのデータを得ることが面倒(しかもI2Cアドレスが間違ってたりする)なのと内蔵の温度計の値を得ることが出来なかったので、新たに作ってみました。
方位の計算部分は既存のライブラリの物を流用しています。

LSM303DLHC.h

Committer:
jk1lot
Date:
2016-06-12
Revision:
0:e5bf52560a0c

File content as of revision 0:e5bf52560a0c:

#ifndef LSM303DLHC_H
#define LSM303DLHC_H

#include "mbed.h"

//! LSM303DLHC 3D accelerometer and 3D magnetometer
class LSM303DLHC {
    typedef struct vector {float x, y, z;} vector;
    static void vector_cross(const vector *a, const vector *b, vector *out);
    static float vector_dot(const vector *a,const vector *b);
    static void vector_normalize(vector *a);
public:
    //! @param obj pointer to I2C object
    LSM303DLHC(I2C *obj);
    //! measure accelerometer value
    void getAccel(void) {read(ACCEL_SAD, OUT_A, _accel, 6);}
    //! extract X-axis value from mesured accelerometer
    int16_t accelX(void) {return (_accel[1]<<8)|_accel[0];}
    //! extract Y-axis value from mesured accelerometer
    int16_t accelY(void) {return (_accel[3]<<8)|_accel[2];}
    //! extract Z-axis value from mesured accelerometer
    int16_t accelZ(void) {return (_accel[5]<<8)|_accel[4];}

    //! mesure magnetometer value
    void getMagnet(void) {read(MAGNET_SAD, OUT_M, _magnet, 6);}
    //accelと magnetでは Highと Lowの順序が逆になってる変な仕様
    //しかもMagnetは X,Z,Y の順番
    //! extract X-axis value from mesured magnetometer
    int16_t magnetX(void) {return (_magnet[0]<<8)|_magnet[1];}
    //! extract Z-axis value from mesured magnetometer
    int16_t magnetZ(void) {return (_magnet[2]<<8)|_magnet[3];}
    //! extract Y-axis value from mesured magnetometer
    int16_t magnetY(void) {return (_magnet[4]<<8)|_magnet[5];}

    float heading(vector from);
    //! @return orientation(direction) value, expressed in degrees(0~360)
    float orientation(void);
    //! @return Temperature value, expressed in degrees Celsius
    float temperature(void);
protected:
    //! write 1byte
    //! @param sad I2C address
    //! @param reg register address
    //! @param data data
    void write(char sad, char reg, char data);
    //! read data
    //! @param sad I2C address
    //! @param reg register address start from here and auto incriment
    //! @param data pointer to data storage
    //! @param length how many bytes to read
    void read(char sad, char reg, char *data, int length=1);

    I2C *i2c;
    static const int8_t ACCEL_SAD = 0x32;
    static const int8_t MAGNET_SAD = 0x3C;
    enum accel_regs {
        CTRL_REG1_A=0x20,
        CTRL_REG2_A=0x21,
        CTRL_REG3_A=0x22,
        CTRL_REG4_A=0x23,
        CTRL_REG5_A=0x24,
        CTRL_REG6_A=0x25,
        REFERENCE_A=0x26,
        STATUS_REG_A=0x27,
        OUT_A=0x28, //6bytes
        FIFO_CTRL_REG_A=0x2E,
        FIFO_SRC_REG_A=0x2F,
        INT1_A=0x30, //4bytes
        INT2_A=0x34, //4bytes
        CLICK_A=0x38, //3bytes
        TIME_LIMIT_A=0x3B,
        TIME_LATENCY_A=0x3C,
        TIME_WINDOW_A=0x3D
    };
    static const int INT_CFG=0;
    static const int INT_SRC=1;
    static const int INT_THS=2;
    static const int INT_DURATION=3;
    enum magnet_regs {
        CRA_REG_M=0x00,
        CRB_REG_M=0x01,
        MR_REG_M=0x02,
        OUT_M=0x03, //6bytes
        SR_REG_M=0x09,
        IRA_REG_M=0x0A,
        IRB_REG_M=0x0B,
        IRC_REG_M=0x0C,
        TEMP_OUT_M=0x31 //2bytes
    };
private:
    char _accel[6];
    char _magnet[6];
};

#endif