inertia sensor

Dependents:  

Fork of LSM9DS0 by LDSC_Robotics_TAs

Files at this revision

API Documentation at this revision

Comitter:
roger5641
Date:
Thu Aug 25 06:14:12 2016 +0000
Parent:
4:29f3711f5f59
Commit message:
ver2; add DC motor

Changed in this revision

LSM9DS0.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 29f3711f5f59 -r 472542e91734 LSM9DS0.cpp
--- a/LSM9DS0.cpp	Sat Jul 23 13:40:51 2016 +0000
+++ b/LSM9DS0.cpp	Thu Aug 25 06:14:12 2016 +0000
@@ -5,28 +5,28 @@
 Jim Lindblom @ SparkFun Electronics
 Original Creation Date: February 14, 2014 (Happy Valentines Day!)
 https://github.com/sparkfun/LSM9DS0_Breakout
-
+ 
 This file implements all functions of the LSM9DS0 class. Functions here range
 from higher level stuff, like reading/writing LSM9DS0 registers to low-level,
 hardware reads and writes. Both SPI and I2C handler functions can be found
 towards the bottom of this file.
-
+ 
 Development environment specifics:
     IDE: Arduino 1.0.5
     Hardware Platform: Arduino Pro 3.3V/8MHz
     LSM9DS0 Breakout Version: 1.0
-
+ 
 This code is beerware; if you see me (or any other SparkFun employee) at the
 local, and you've found our code helpful, please buy us a round!
-
+ 
 Distributed as-is; no warranty is given.
 ******************************************************************************/
-
+ 
 #include "LSM9DS0.h"
 #include "mbed.h"
-
+ 
 //I2C i2c(D14,D15);
-//SPI spi(D4,D5,D8);
+//SPI spi(D4,D5,D3);
 //****************************************************************************//
 //
 //  LSM9DS0 functions.
@@ -40,8 +40,8 @@
 //  For SPI, construct LSM6DS3 myIMU(SPI_MODE, D9, D6);
 //
 //=================================
-
-LSM9DS0::LSM9DS0(interface_mode interface, uint8_t gAddr, uint8_t xmAddr) : interfaceMode(SPI_MODE), spi_(D4,D5,D3), i2c_(I2C_SDA,I2C_SCL), csG_(D9), csXM_(D6)
+ 
+LSM9DS0::LSM9DS0(interface_mode interface, uint8_t gAddr, uint8_t xmAddr) : interfaceMode(SPI_MODE), spi_(D4,D5,D3), i2c_(I2C_SDA,I2C_SCL), csG_(D12), csXM_(D6)
 {
     // interfaceMode will keep track of whether we're using SPI or I2C:
     interfaceMode = interface;
@@ -51,7 +51,7 @@
     gAddress = gAddr;
     xmAddress = xmAddr;
 }
-
+ 
 uint16_t LSM9DS0::begin(gyro_scale gScl, accel_scale aScl, mag_scale mScl, 
                         gyro_odr gODR, accel_odr aODR, mag_odr mODR)
 {
@@ -94,13 +94,13 @@
     setMagScale(mScale); // Set the magnetometer's range.
     
     setGyroOffset(0,0,0);
-    setAccelOffset(-936,-491,265);
+    setAccelOffset(0,0,0);
     setMagOffset(0,0,0);
     
     // Once everything is initialized, return the WHO_AM_I registers we read:
     return (xmTest << 8) | gTest;
 }
-
+ 
 void LSM9DS0::initGyro()
 {
     /* CTRL_REG1_G sets output data rate, bandwidth, power-down and enables
@@ -160,7 +160,7 @@
     // Temporary !!! For testing !!! Remove !!! Or make useful !!!
     configGyroInt(0x2A, 0, 0, 0, 0); // Trigger interrupt when above 0 DPS...
 }
-
+ 
 void LSM9DS0::initAccel()
 {
     /* CTRL_REG0_XM (0x1F) (Default value: 0x00)
@@ -205,7 +205,7 @@
     // Accelerometer data ready on INT1_XM (0x04)
     xmWriteByte(CTRL_REG3_XM, 0x00); 
 }
-
+ 
 void LSM9DS0::initMag()
 {   
     /* CTRL_REG5_XM enables temp sensor, sets mag resolution and data rate
@@ -258,7 +258,7 @@
         0=disable, 1=enable) */
     xmWriteByte(INT_CTRL_REG_M, 0x09); // Enable interrupts for mag, active-low, push-pull
 }
-
+ 
 // This is a function that uses the FIFO to accumulate sample of accelerometer and gyro data, average
 // them, scales them to  gs and deg/s, respectively, and then passes the biases to the main sketch
 // for subtraction from all subsequent data. There are no gyro and accelerometer bias registers to store
@@ -280,14 +280,14 @@
   wait_ms(1000);  // delay 1000 milliseconds to collect FIFO samples
   
   samples = (gReadByte(FIFO_SRC_REG_G) & 0x1F); // Read number of stored samples
-
+ 
   for(ii = 0; ii < samples ; ii++) {            // Read the gyro data stored in the FIFO
     gReadBytes(OUT_X_L_G,  &data[0], 6);
     gyro_bias[0] += (((int16_t)data[1] << 8) | data[0]);
     gyro_bias[1] += (((int16_t)data[3] << 8) | data[2]);
     gyro_bias[2] += (((int16_t)data[5] << 8) | data[4]);
   }  
-
+ 
   gyro_bias[0] /= samples; // average the data
   gyro_bias[1] /= samples; 
   gyro_bias[2] /= samples; 
@@ -301,23 +301,23 @@
   wait_ms(20);
   gWriteByte(FIFO_CTRL_REG_G, 0x00);   // Enable gyro bypass mode
   
-
+ 
   //  Now get the accelerometer biases
   c = xmReadByte(CTRL_REG0_XM);
   xmWriteByte(CTRL_REG0_XM, c | 0x40);      // Enable accelerometer FIFO  
   wait_ms(20);                                // Wait for change to take effect
   xmWriteByte(FIFO_CTRL_REG, 0x20 | 0x1F);  // Enable accelerometer FIFO stream mode and set watermark at 32 samples
   wait_ms(1000);  // delay 1000 milliseconds to collect FIFO samples
-
+ 
   samples = (xmReadByte(FIFO_SRC_REG) & 0x1F); // Read number of stored accelerometer samples
-
+ 
    for(ii = 0; ii < samples ; ii++) {          // Read the accelerometer data stored in the FIFO
     xmReadBytes(OUT_X_L_A, &data[0], 6);
     accel_bias[0] += (((int16_t)data[1] << 8) | data[0]);
     accel_bias[1] += (((int16_t)data[3] << 8) | data[2]);
     accel_bias[2] += (((int16_t)data[5] << 8) | data[4]) - (int16_t)(1.0f/aRes); // Assumes sensor facing up!
   }  
-
+ 
   accel_bias[0] /= samples; // average the data
   accel_bias[1] /= samples; 
   accel_bias[2] /= samples; 
@@ -325,13 +325,13 @@
   abias[0] = (float)accel_bias[0]*aRes; // Properly scale data to get gs
   abias[1] = (float)accel_bias[1]*aRes;
   abias[2] = (float)accel_bias[2]*aRes;
-
+ 
   c = xmReadByte(CTRL_REG0_XM);
   xmWriteByte(CTRL_REG0_XM, c & ~0x40);    // Disable accelerometer FIFO  
   wait_ms(20);
   xmWriteByte(FIFO_CTRL_REG, 0x00);       // Enable accelerometer bypass mode
 }
-
+ 
 //**********************
 //  Gyro section
 //**********************
@@ -343,14 +343,14 @@
     gy = (temp[3] << 8) | temp[2]; // Store y-axis values into gy
     gz = (temp[5] << 8) | temp[4]; // Store z-axis values into gz
 }
-
+ 
 void LSM9DS0::setGyroOffset(int16_t _gx, int16_t _gy, int16_t _gz)
 {
     gyroOffset[0] = _gx;
     gyroOffset[1] = _gy;
     gyroOffset[2] = _gz;
 }
-
+ 
 int16_t LSM9DS0::readRawGyroX( void )
 {
     uint8_t temp[2];
@@ -358,7 +358,7 @@
     gx = (temp[1] << 8) | temp[0];
     return gx;
 }
-
+ 
 int16_t LSM9DS0::readRawGyroY( void )
 {
     uint8_t temp[2];
@@ -366,7 +366,7 @@
     gy = (temp[1] << 8) | temp[0];
     return gy;
 }
-
+ 
 int16_t LSM9DS0::readRawGyroZ( void )
 {
     uint8_t temp[2];
@@ -374,25 +374,25 @@
     gz = (temp[1] << 8) | temp[0];
     return gz;
 }
-
+ 
 float LSM9DS0::readFloatGyroX( void )
 {
     float output = calcGyro(readRawGyroX() - gyroOffset[0]);
     return output;
 }
-
+ 
 float LSM9DS0::readFloatGyroY( void )
 {
     float output = calcGyro(readRawGyroY() - gyroOffset[1]);
     return output;
 }
-
+ 
 float LSM9DS0::readFloatGyroZ( void )
 {
     float output = calcGyro(readRawGyroZ() - gyroOffset[2]);
     return output;
 }
-
+ 
 //**********************
 //  Accel section
 //**********************
@@ -404,14 +404,14 @@
     ay = (temp[3] << 8) | temp[2]; // Store y-axis values into ay
     az = (temp[5] << 8) | temp[4]; // Store z-axis values into az
 }
-
+ 
 void LSM9DS0::setAccelOffset(int16_t _ax, int16_t _ay, int16_t _az)
 {
     accelOffset[0] = _ax;
     accelOffset[1] = _ay;
     accelOffset[2] = _az;
 }
-
+ 
 int16_t LSM9DS0::readRawAccelX( void )
 {
     uint8_t temp[2];
@@ -419,7 +419,7 @@
     ax = (temp[1] << 8) | temp[0];
     return ax;
 }
-
+ 
 int16_t LSM9DS0::readRawAccelY( void )
 {
     uint8_t temp[2];
@@ -427,7 +427,7 @@
     ay = (temp[1] << 8) | temp[0];
     return ay;
 }
-
+ 
 int16_t LSM9DS0::readRawAccelZ( void )
 {
     uint8_t temp[2];
@@ -435,25 +435,25 @@
     az = (temp[1] << 8) | temp[0];
     return az;
 }
-
+ 
 float LSM9DS0::readFloatAccelX( void )
 {
     float output = calcAccel(readRawAccelX() - accelOffset[0]);
     return output;
 }
-
+ 
 float LSM9DS0::readFloatAccelY( void )
 {
     float output = calcAccel(readRawAccelY() - accelOffset[1]);
     return output;
 }
-
+ 
 float LSM9DS0::readFloatAccelZ( void )
 {
     float output = calcAccel(readRawAccelZ() - accelOffset[2]);
     return output;
 }
-
+ 
 //**********************
 //  Mag section
 //**********************
@@ -465,14 +465,14 @@
     my = (temp[3] << 8) | temp[2]; // Store y-axis values into my
     mz = (temp[5] << 8) | temp[4]; // Store z-axis values into mz
 }
-
+ 
 void LSM9DS0::setMagOffset(int16_t _mx, int16_t _my, int16_t _mz)
 {
     magOffset[0] = _mx;
     magOffset[1] = _my;
     magOffset[2] = _mz;
 }
-
+ 
 int16_t LSM9DS0::readRawMagX( void )
 {
     uint8_t temp[2];
@@ -480,7 +480,7 @@
     mx = (temp[1] << 8) | temp[0];
     return mx;
 }
-
+ 
 int16_t LSM9DS0::readRawMagY( void )
 {
     uint8_t temp[2];
@@ -488,7 +488,7 @@
     my = (temp[1] << 8) | temp[0];
     return my;
 }
-
+ 
 int16_t LSM9DS0::readRawMagZ( void )
 {
     uint8_t temp[2];
@@ -496,25 +496,25 @@
     mz = (temp[1] << 8) | temp[0];
     return mz;
 }
-
+ 
 float LSM9DS0::readFloatMagX( void )
 {
     float output = calcMag(readRawMagX() - magOffset[0]);
     return output;
 }
-
+ 
 float LSM9DS0::readFloatMagY( void )
 {
     float output = calcMag(readRawMagY() - magOffset[1]);
     return output;
 }
-
+ 
 float LSM9DS0::readFloatMagZ( void )
 {
     float output = calcMag(readRawMagZ() - magOffset[2]);
     return output;
 }
-
+ 
 //**********************
 //  Temp section
 //**********************
@@ -524,25 +524,25 @@
     xmReadBytes(OUT_TEMP_L_XM, temp, 2); // Read 2 bytes, beginning at OUT_TEMP_L_M
     temperature = (((int16_t) temp[1] << 12) | temp[0] << 4 ) >> 4; // Temperature is a 12-bit signed integer
 }
-
+ 
 float LSM9DS0::calcGyro(int16_t gyro)
 {
     // Return the gyro raw reading times our pre-calculated DPS / (ADC tick):
     return gRes * gyro; 
 }
-
+ 
 float LSM9DS0::calcAccel(int16_t accel)
 {
     // Return the accel raw reading times our pre-calculated g's / (ADC tick):
     return aRes * accel;
 }
-
+ 
 float LSM9DS0::calcMag(int16_t mag)
 {
     // Return the mag raw reading times our pre-calculated Gs / (ADC tick):
     return mRes * mag;
 }
-
+ 
 void LSM9DS0::setGyroScale(gyro_scale gScl)
 {
     // We need to preserve the other bytes in CTRL_REG4_G. So, first read it:
@@ -560,7 +560,7 @@
     // Then calculate a new gRes, which relies on gScale being set correctly:
     calcgRes();
 }
-
+ 
 void LSM9DS0::setAccelScale(accel_scale aScl)
 {
     // We need to preserve the other bytes in CTRL_REG2_XM. So, first read it:
@@ -578,7 +578,7 @@
     // Then calculate a new aRes, which relies on aScale being set correctly:
     calcaRes();
 }
-
+ 
 void LSM9DS0::setMagScale(mag_scale mScl)
 {
     // We need to preserve the other bytes in CTRL_REG6_XM. So, first read it:
@@ -596,7 +596,7 @@
     // Then calculate a new mRes, which relies on mScale being set correctly:
     calcmRes();
 }
-
+ 
 void LSM9DS0::setGyroODR(gyro_odr gRate)
 {
     // We need to preserve the other bytes in CTRL_REG1_G. So, first read it:
@@ -641,7 +641,7 @@
     // And write the new register value back into CTRL_REG5_XM:
     xmWriteByte(CTRL_REG5_XM, temp);
 }
-
+ 
 void LSM9DS0::configGyroInt(uint8_t int1Cfg, uint16_t int1ThsX, uint16_t int1ThsY, uint16_t int1ThsZ, uint8_t duration)
 {
     gWriteByte(INT1_CFG_G, int1Cfg);
@@ -656,7 +656,7 @@
     else
         gWriteByte(INT1_DURATION_G, 0x00);
 }
-
+ 
 void LSM9DS0::calcgRes()
 {
     // Possible gyro scales (and their register bit settings) are:
@@ -675,7 +675,7 @@
         break;
     }
 }
-
+ 
 void LSM9DS0::calcaRes()
 {
     // Possible accelerometer scales (and their register bit settings) are:
@@ -684,7 +684,7 @@
     aRes = aScale == A_SCALE_16G ? 16.0 / 32768.0 : 
            (((float) aScale + 1.0f) * 2.0f) / 32768.0f;
 }
-
+ 
 void LSM9DS0::calcmRes()
 {
     // Possible magnetometer scales (and their register bit settings) are:
@@ -703,7 +703,7 @@
     else if (interfaceMode == SPI_MODE)
         SPIwriteByte(gAddress, subAddress, data);
 }
-
+ 
 void LSM9DS0::xmWriteByte(uint8_t subAddress, uint8_t data)
 {
     // Whether we're using I2C or SPI, write a byte using the
@@ -713,7 +713,7 @@
     else if (interfaceMode == SPI_MODE)
         return SPIwriteByte(xmAddress, subAddress, data);
 }
-
+ 
 uint8_t LSM9DS0::gReadByte(uint8_t subAddress)
 {
     // Whether we're using I2C or SPI, read a byte using the
@@ -725,7 +725,7 @@
     else
         return SPIreadByte(gAddress, subAddress);
 }
-
+ 
 void LSM9DS0::gReadBytes(uint8_t subAddress, uint8_t * dest, uint8_t count)
 {
     // Whether we're using I2C or SPI, read multiple bytes using the
@@ -735,7 +735,7 @@
     else if (interfaceMode == SPI_MODE)
         SPIreadBytes(gAddress, subAddress, dest, count);
 }
-
+ 
 uint8_t LSM9DS0::xmReadByte(uint8_t subAddress)
 {
     // Whether we're using I2C or SPI, read a byte using the
@@ -747,7 +747,7 @@
     else
         return SPIreadByte(xmAddress, subAddress);
 }
-
+ 
 void LSM9DS0::xmReadBytes(uint8_t subAddress, uint8_t * dest, uint8_t count)
 {
     // Whether we're using I2C or SPI, read multiple bytes using the
@@ -757,7 +757,7 @@
     else if (interfaceMode == SPI_MODE)
         SPIreadBytes(xmAddress, subAddress, dest, count);
 }
-
+ 
 void LSM9DS0::initSPI()
 {
     csG_ = 1;
@@ -767,7 +767,7 @@
 //    spi_.frequency(1000000);
     spi_.format(8,0b11);
 }
-
+ 
 void LSM9DS0::SPIwriteByte(uint8_t csPin, uint8_t subAddress, uint8_t data)
 {
     // Initiate communication
@@ -784,7 +784,7 @@
     csG_ = 1; // Close communication
     csXM_= 1;
 }
-
+ 
 uint8_t LSM9DS0::SPIreadByte(uint8_t csPin, uint8_t subAddress)
 {
     uint8_t temp;
@@ -793,7 +793,7 @@
     SPIreadBytes(csPin, subAddress, &temp, 1);
     return temp;
 }
-
+ 
 void LSM9DS0::SPIreadBytes(uint8_t csPin, uint8_t subAddress,
                             uint8_t * dest, uint8_t count)
 {
@@ -816,13 +816,13 @@
     csG_ = 1; // Close communication
     csXM_= 1;
 }
-
+ 
 void LSM9DS0::initI2C()
 {
 //    Wire.begin();   // Initialize I2C library
     ;
 }
-
+ 
 // Wire.h read and write protocols
 void LSM9DS0::I2CwriteByte(uint8_t address, uint8_t subAddress, uint8_t data)
 {
@@ -832,7 +832,7 @@
 //    Wire.write(data);                 // Put data in Tx buffer
 //    Wire.endTransmission();           // Send the Tx buffer
 }
-
+ 
 uint8_t LSM9DS0::I2CreadByte(uint8_t address, uint8_t subAddress)
 {
     return 0;
@@ -844,7 +844,7 @@
 //    data = Wire.read();                      // Fill Rx buffer with result
 //    return data;                             // Return data read from slave register
 }
-
+ 
 void LSM9DS0::I2CreadBytes(uint8_t address, uint8_t subAddress, uint8_t * dest, uint8_t count)
 {
     ;
@@ -858,4 +858,24 @@
 //    {
 //        dest[i++] = Wire.read(); // Put read results in the Rx buffer
 //    }
-}
\ No newline at end of file
+}
+ 
+void LSM9DS0::complementaryFilter(float * data, float dt)
+{
+    
+    float pitchAcc, rollAcc;
+ 
+    /* Integrate the gyro data(deg/s) over time to get angle */
+    pitch += data[5] * dt;  // Angle around the Z-axis
+    roll +=  data[3] * dt;  // Angle around the X-axis
+    
+    /* Turning around the X-axis results in a vector on the Y-axis
+    whereas turning around the Y-axis results in a vector on the X-axis. */
+    pitchAcc = (float)atan2f(-data[0], -data[1])*180.0f/PI;
+    rollAcc  = (float)atan2f(data[2], -data[1])*180.0f/PI;
+  
+    /* Apply Complementary Filter */
+    pitch = pitch * 0.999 + pitchAcc * 0.001;
+    roll  = roll  * 0.999 + rollAcc  * 0.001;
+}
+            
\ No newline at end of file