Skip to content

Commit

Permalink
enable high res mode on DLHC by default
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin-pololu committed Mar 15, 2013
1 parent 70c5b7a commit a438e4f
Showing 1 changed file with 31 additions and 28 deletions.
59 changes: 31 additions & 28 deletions LSM303/LSM303.cpp
Expand Up @@ -4,7 +4,7 @@


// Defines //////////////////////////////////////////////////////////////// // Defines ////////////////////////////////////////////////////////////////


// The Arduino two-wire interface uses a 7-bit number for the address, // The Arduino two-wire interface uses a 7-bit number for the address,
// and sets the last bit correctly based on reads and writes // and sets the last bit correctly based on reads and writes
#define MAG_ADDRESS (0x3C >> 1) #define MAG_ADDRESS (0x3C >> 1)
#define ACC_ADDRESS_SA0_A_LOW (0x30 >> 1) #define ACC_ADDRESS_SA0_A_LOW (0x30 >> 1)
Expand All @@ -18,7 +18,7 @@ LSM303::LSM303(void)
// a calibration be done for your particular unit. // a calibration be done for your particular unit.
m_max.x = +540; m_max.y = +500; m_max.z = 180; m_max.x = +540; m_max.y = +500; m_max.z = 180;
m_min.x = -520; m_min.y = -570; m_min.z = -770; m_min.x = -520; m_min.y = -570; m_min.z = -770;

_device = LSM303_DEVICE_AUTO; _device = LSM303_DEVICE_AUTO;
acc_address = ACC_ADDRESS_SA0_A_LOW; acc_address = ACC_ADDRESS_SA0_A_LOW;


Expand All @@ -44,7 +44,7 @@ unsigned int LSM303::getTimeout()
} }


void LSM303::init(byte device, byte sa0_a) void LSM303::init(byte device, byte sa0_a)
{ {
_device = device; _device = device;
switch (_device) switch (_device)
{ {
Expand All @@ -56,12 +56,12 @@ void LSM303::init(byte device, byte sa0_a)
acc_address = ACC_ADDRESS_SA0_A_HIGH; acc_address = ACC_ADDRESS_SA0_A_HIGH;
else else
acc_address = (detectSA0_A() == LSM303_SA0_A_HIGH) ? ACC_ADDRESS_SA0_A_HIGH : ACC_ADDRESS_SA0_A_LOW; acc_address = (detectSA0_A() == LSM303_SA0_A_HIGH) ? ACC_ADDRESS_SA0_A_HIGH : ACC_ADDRESS_SA0_A_LOW;
break; break;

case LSM303DLHC_DEVICE: case LSM303DLHC_DEVICE:
acc_address = ACC_ADDRESS_SA0_A_HIGH; acc_address = ACC_ADDRESS_SA0_A_HIGH;
break; break;

default: default:
// try to auto-detect device // try to auto-detect device
if (detectSA0_A() == LSM303_SA0_A_HIGH) if (detectSA0_A() == LSM303_SA0_A_HIGH)
Expand All @@ -87,7 +87,10 @@ void LSM303::enableDefault(void)
// 0x27 = 0b00100111 // 0x27 = 0b00100111
// Normal power mode, all axes enabled // Normal power mode, all axes enabled
writeAccReg(LSM303_CTRL_REG1_A, 0x27); writeAccReg(LSM303_CTRL_REG1_A, 0x27);


if (_device == LSM303DLHC_DEVICE)
writeAccReg(LSM303_CTRL_REG4_A, 0x08); // DLHC: enable high resolution mode

// Enable Magnetometer // Enable Magnetometer
// 0x00 = 0b00000000 // 0x00 = 0b00000000
// Continuous conversion mode // Continuous conversion mode
Expand All @@ -107,14 +110,14 @@ void LSM303::writeAccReg(byte reg, byte value)
byte LSM303::readAccReg(byte reg) byte LSM303::readAccReg(byte reg)
{ {
byte value; byte value;

Wire.beginTransmission(acc_address); Wire.beginTransmission(acc_address);
Wire.write(reg); Wire.write(reg);
last_status = Wire.endTransmission(); last_status = Wire.endTransmission();
Wire.requestFrom(acc_address, (byte)1); Wire.requestFrom(acc_address, (byte)1);
value = Wire.read(); value = Wire.read();
Wire.endTransmission(); Wire.endTransmission();

return value; return value;
} }


Expand All @@ -131,7 +134,7 @@ void LSM303::writeMagReg(byte reg, byte value)
byte LSM303::readMagReg(int reg) byte LSM303::readMagReg(int reg)
{ {
byte value; byte value;

// if dummy register address (magnetometer Y/Z), use device type to determine actual address // if dummy register address (magnetometer Y/Z), use device type to determine actual address
if (reg < 0) if (reg < 0)
{ {
Expand All @@ -151,32 +154,32 @@ byte LSM303::readMagReg(int reg)
break; break;
} }
} }

Wire.beginTransmission(MAG_ADDRESS); Wire.beginTransmission(MAG_ADDRESS);
Wire.write(reg); Wire.write(reg);
last_status = Wire.endTransmission(); last_status = Wire.endTransmission();
Wire.requestFrom(MAG_ADDRESS, 1); Wire.requestFrom(MAG_ADDRESS, 1);
value = Wire.read(); value = Wire.read();
Wire.endTransmission(); Wire.endTransmission();

return value; return value;
} }


void LSM303::setMagGain(magGain value) void LSM303::setMagGain(magGain value)
{ {
Wire.beginTransmission(MAG_ADDRESS); Wire.beginTransmission(MAG_ADDRESS);
Wire.write(LSM303_CRB_REG_M); Wire.write(LSM303_CRB_REG_M);
Wire.write((byte) value); Wire.write((byte) value);
Wire.endTransmission(); Wire.endTransmission();
} }


// Reads the 3 accelerometer channels and stores them in vector a // Reads the 3 accelerometer channels and stores them in vector a
void LSM303::readAcc(void) void LSM303::readAcc(void)
{ {
Wire.beginTransmission(acc_address); Wire.beginTransmission(acc_address);
// assert the MSB of the address to get the accelerometer // assert the MSB of the address to get the accelerometer
// to do slave-transmit subaddress updating. // to do slave-transmit subaddress updating.
Wire.write(LSM303_OUT_X_L_A | (1 << 7)); Wire.write(LSM303_OUT_X_L_A | (1 << 7));
last_status = Wire.endTransmission(); last_status = Wire.endTransmission();
Wire.requestFrom(acc_address, (byte)6); Wire.requestFrom(acc_address, (byte)6);


Expand All @@ -188,7 +191,7 @@ void LSM303::readAcc(void)
return; return;
} }
} }

byte xla = Wire.read(); byte xla = Wire.read();
byte xha = Wire.read(); byte xha = Wire.read();
byte yla = Wire.read(); byte yla = Wire.read();
Expand Down Expand Up @@ -223,9 +226,9 @@ void LSM303::readMag(void)


byte xhm = Wire.read(); byte xhm = Wire.read();
byte xlm = Wire.read(); byte xlm = Wire.read();

byte yhm, ylm, zhm, zlm; byte yhm, ylm, zhm, zlm;

if (_device == LSM303DLH_DEVICE) if (_device == LSM303DLH_DEVICE)
{ {
// DLH: register address for Y comes before Z // DLH: register address for Y comes before Z
Expand Down Expand Up @@ -266,8 +269,8 @@ int LSM303::heading(void)


// Returns the number of degrees from the From vector projected into // Returns the number of degrees from the From vector projected into
// the horizontal plane is away from north. // the horizontal plane is away from north.
// //
// Description of heading algorithm: // Description of heading algorithm:
// Shift and scale the magnetic reading based on calibration data to // Shift and scale the magnetic reading based on calibration data to
// to find the North vector. Use the acceleration readings to // to find the North vector. Use the acceleration readings to
// determine the Down vector. The cross product of North and Down // determine the Down vector. The cross product of North and Down
Expand All @@ -293,7 +296,7 @@ int LSM303::heading(vector from)
vector_cross(&m, &temp_a, &E); vector_cross(&m, &temp_a, &E);
vector_normalize(&E); vector_normalize(&E);
vector_cross(&temp_a, &E, &N); vector_cross(&temp_a, &E, &N);

// compute heading // compute heading
int heading = round(atan2(vector_dot(&E, &from), vector_dot(&N, &from)) * 180 / M_PI); int heading = round(atan2(vector_dot(&E, &from), vector_dot(&N, &from)) * 180 / M_PI);
if (heading < 0) heading += 360; if (heading < 0) heading += 360;
Expand Down

0 comments on commit a438e4f

Please sign in to comment.