grove_compass
grove_compass.cpp
- Committer:
- JackyZhangFromSeeed
- Date:
- 2015-06-09
- Revision:
- 0:609518794a5d
File content as of revision 0:609518794a5d:
#include "suli2.h" #include "grove_compass.h" //local functions static void grove_compass_getxyz_raw(I2C_T *i2c, int16_t *x, int16_t *y, int16_t *z); static int setScale(I2C_T *i2c, float gauss); static void setMeasurementMode(I2C_T *i2c, uint8_t mode); //local variables static float m_Scale; static unsigned char cmdbuf[2]; static unsigned char databuf[6]; void grove_compass_init(I2C_T *i2c, int pinsda, int pinscl) { suli_i2c_init(i2c, pinsda, pinscl); } bool grove_compass_write_setup(I2C_T *i2c) { uint8_t regValue = 0x00; //setScale(i2c, (float)1.3); // Set the scale of the compass. regValue = 0x01; m_Scale = 0.92; // Setting is in the top 3 bits of the register. regValue = regValue << 5; //write(CONFIGURATION_REGISTERB, regValue); cmdbuf[0] = CONFIGURATION_REGISTERB; cmdbuf[1] = regValue; suli_i2c_write(i2c, HMC5883L_ADDRESS, cmdbuf, 2); setMeasurementMode(i2c, MEASUREMENT_CONTINUOUS); // Set the measurement mode to Continuous return true; } static void grove_compass_getxyz_raw(I2C_T *i2c, int16_t *x, int16_t *y, int16_t *z) { cmdbuf[0] = DATA_REGISTER_BEGIN; suli_i2c_write(i2c, HMC5883L_ADDRESS, &cmdbuf[0], 1); suli_i2c_read(i2c, HMC5883L_ADDRESS, databuf, 6); *x = (databuf[0] << 8) | databuf[1]; *y = (databuf[2] << 8) | databuf[3]; *z = (databuf[4] << 8) | databuf[5]; } bool grove_compass_getxyz_scaled(I2C_T *i2c, float *cx, float *cy, float *cz) { int16_t x,y,z; grove_compass_getxyz_raw(i2c, &x,&y,&z); *cx = (float)x * m_Scale; *cy = (float)y * m_Scale; *cz = (float)z * m_Scale; return true; } bool grove_compass_getheading(I2C_T *i2c, float *heading) { float cx, cy, cz; grove_compass_getxyz_scaled(i2c, &cx, &cy, &cz); float head = atan2(cy, cx) - 0.0457; // Correct for when signs are reversed. if(heading < 0) head += 2*PI; // Check for wrap due to addition of declination. if(head > 2*PI) head -= 2*PI; // Convert radians to degrees for readability. *heading = head * 180 / PI; return true; } static int setScale(I2C_T *i2c, float gauss) { uint8_t regValue = 0x00; if(gauss == 0.88) { regValue = 0x00; m_Scale = 0.73; } else if(gauss == 1.3) { regValue = 0x01; m_Scale = 0.92; } else if(gauss == 1.9) { regValue = 0x02; m_Scale = 1.22; } else if(gauss == 2.5) { regValue = 0x03; m_Scale = 1.52; } else if(gauss == 4.0) { regValue = 0x04; m_Scale = 2.27; } else if(gauss == 4.7) { regValue = 0x05; m_Scale = 2.56; } else if(gauss == 5.6) { regValue = 0x06; m_Scale = 3.03; } else if(gauss == 8.1) { regValue = 0x07; m_Scale = 4.35; } else return -1; // Setting is in the top 3 bits of the register. regValue = regValue << 5; //write(CONFIGURATION_REGISTERB, regValue); cmdbuf[0] = CONFIGURATION_REGISTERB; cmdbuf[1] = regValue; suli_i2c_write(i2c, HMC5883L_ADDRESS, &cmdbuf[0], 2); return true; } static void setMeasurementMode(I2C_T *i2c, uint8_t mode) { //write(MODE_REGISTER, mode); cmdbuf[0] = MODE_REGISTER; cmdbuf[1] = mode; suli_i2c_write(i2c, HMC5883L_ADDRESS, cmdbuf, 2); }