Republished Library, to be refined for use with the SparkFun 9DOF in HARP project.

Dependents:   vmConfort_v6

Fork of ADXL345 by Tyler Weaver

Revision:
8:4cdd4315189f
Parent:
6:5fb29534a6cf
Child:
9:cc0260a2404b
--- a/ADXL345.cpp	Thu Nov 01 18:46:24 2012 +0000
+++ b/ADXL345.cpp	Mon Nov 05 18:34:49 2012 +0000
@@ -1,5 +1,6 @@
 /**
  * @file ADXL345.cpp
+ * @author Tyler Weaver
  * @author Peter Swanson
  * A personal note from me: Jesus Christ has changed my life so much it blows my mind. I say this because
  *                  today, religion is thought of as something that you do or believe and has about as
@@ -70,7 +71,7 @@
     // initialize the BW data rate
     setDataRate(ADXL345_6HZ25); // 6.25 Hz
 
-    //Data format (for +-16g) - This is done by setting Bit D3 of the DATA_FORMAT register (Address 0x31) 
+    //Data format (for +-16g) - This is done by setting Bit D3 of the DATA_FORMAT register (Address 0x31)
     //and writing a value of 0x03 to the range bits (Bit D1 and Bit D0) of the DATA_FORMAT register (Address 0x31).
     setDataFormatControl(ADXL345_FULL_RES | ADXL345_2G); // full resolution, right justified, 2g range
 
@@ -120,11 +121,10 @@
 
     ack = i2c_.write( ADXL345_WRITE, &address, 1);  //tell it where to write to
     return ack | i2c_.write( ADXL345_READ, ptr_data, size);  //tell it what data to write
-
 }
 
 
-void ADXL345::getOutput(int* readings)
+void ADXL345::getOutput(int16_t* readings)
 {
     char buffer[6];
     multiByteRead(ADXL345_DATAX0_REG, buffer, 6);
@@ -132,7 +132,6 @@
     readings[0] = wordExtend(&buffer[0]);
     readings[1] = wordExtend(&buffer[2]);
     readings[2] = wordExtend(&buffer[4]);
-
 }
 
 char ADXL345::getDeviceID()
@@ -148,6 +147,16 @@
     return SingleByteWrite(ADXL345_BW_RATE_REG, registerContents);
 }
 
+char ADXL345::getBwRateReg()
+{
+    return SingleByteRead(ADXL345_BW_RATE_REG);
+}
+
+int ADXL345::setBwRateReg(char reg)
+{
+    return SingleByteWrite(ADXL345_BW_RATE_REG, reg);
+}
+
 char ADXL345::getPowerControl()
 {
     return SingleByteRead(ADXL345_POWER_CTL_REG);
@@ -393,4 +402,131 @@
 char ADXL345::getInterruptSource(void)
 {
     return SingleByteRead(ADXL345_INT_SOURCE_REG);
+}
+
+void ADXL345::sample100avg(float period, int16_t buffer[][3], int16_t *avg, Timer* t)
+{
+    double start_time;
+
+    for(int sample = 0; sample < 100; sample++) {
+        start_time = t->read();
+
+        getOutput(buffer[sample]);
+
+        wait(period - (start_time - t->read()));
+    }
+
+    for(int axis = 0; axis < 3; axis++) {
+        double average = 0.0;
+        for(int sample = 0; sample < 100; sample++)
+            average += buffer[sample][axis];
+        average /= 100.0;
+        avg[axis] = static_cast<int16_t>(average);
+    }
+}
+
+void ADXL345::calibrate(Timer* t, bool store_output, Serial *pc)
+{
+    int16_t data[100][3]; // {x,y,z}, data
+    int16_t data_avg[3];
+    int8_t calibration_offset[3];
+
+    float period = 0.01; // period of sample rate
+
+    // wait 11.1ms
+    wait(0.0111);
+    
+    pc->puts("Reading old register states... ");
+    // read current register states
+    char bw_rate = getBwRateReg();
+    char power_control = getPowerControl();
+    char data_format = getDataFormatControl();
+
+    pc->puts("Done!\r\nSetting new register states... ");
+    // initalize command sequence
+    setDataFormatControl((ADXL345_16G | ADXL345_FULL_RES));
+    setBwRateReg(ADXL345_100HZ); // 100Hz data rate
+    setPowerControl(0x08); // start measurement
+
+    // wait 1.1ms
+    wait(0.0111);
+    pc->puts("Done!\r\nSampling... ");
+    //take 100 data points and average (100Hz)
+    sample100avg(period, data, data_avg, t);
+    pc->puts("Done!\r\nCalculating offset values... ");
+    // calculate calibration value
+    calibration_offset[0] = -1 * (data_avg[0] / 4); // x
+    calibration_offset[1] = -1 * (data_avg[1] / 4); // y
+    calibration_offset[2] = -1 * ((data_avg[2] - 256) / 4); // z
+    
+    if(store_output) {
+        pc->puts("Done!\r\nStoring output to file... ");
+        LocalFileSystem local("local");
+        FILE *fp = fopen("/local/OFF_CAL.csv", "w"); // write
+        fprintf(fp, "ADXL345 Calibration offsets\r\nx,%d\r\ny,%d\r\nz,%d\r\n\r\n", calibration_offset[0], calibration_offset[1], calibration_offset[2]);
+
+        fputs("Raw Data:\r\nX,Y,Z\r\n", fp);
+        for(int sample = 0; sample < 100; sample++)
+            fprintf(fp, "%d,%d,%d\r\n",data[sample][0],data[sample][1],data[sample][2]);
+        fclose(fp);
+    }
+    pc->puts("Done!\r\nSetting the offset registers... ");
+    // update offset registers
+    for(char axis = 0x00; axis < 0x03; axis++)
+        setOffset(axis,calibration_offset[axis]);
+    pc->puts("Done!\r\nReturning registers to original state... ");
+    // return control registers to original state
+    setDataFormatControl(data_format);
+    setBwRateReg(bw_rate);
+    setPowerControl(power_control);
+    pc->puts("Done!\r\n");
+}
+
+void ADXL345::calibrate(Timer* t, bool store_output)
+{
+    int16_t data[100][3]; // {x,y,z}, data
+    int16_t data_avg[3];
+    int8_t calibration_offset[3];
+
+    float period = 0.01; // period of sample rate
+
+    // wait 11.1ms
+    wait(0.0111);
+    
+    // read current register states
+    char bw_rate = getBwRateReg();
+    char power_control = getPowerControl();
+    char data_format = getDataFormatControl();
+
+    // initalize command sequence
+    setDataFormatControl((ADXL345_16G | ADXL345_FULL_RES));
+    setBwRateReg(ADXL345_100HZ); // 100Hz data rate
+    setPowerControl(0x08); // start measurement
+
+    // wait 1.1ms
+    wait(0.0111);
+    //take 100 data points and average (100Hz)
+    sample100avg(period, data, data_avg, t);
+    // calculate calibration value
+    calibration_offset[0] = -1 * (data_avg[0] / 4); // x
+    calibration_offset[1] = -1 * (data_avg[1] / 4); // y
+    calibration_offset[2] = -1 * ((data_avg[2] - 256) / 4); // z
+    
+    if(store_output) {
+        LocalFileSystem local("local");
+        FILE *fp = fopen("/local/OFF_CAL.csv", "w"); // write
+        fprintf(fp, "ADXL345 Calibration offsets\r\nx,%d\r\ny,%d\r\nz,%d\r\n\r\n", calibration_offset[0], calibration_offset[1], calibration_offset[2]);
+
+        fputs("Raw Data:\r\nX,Y,Z\r\n", fp);
+        for(int sample = 0; sample < 100; sample++)
+            fprintf(fp, "%d,%d,%d\r\n",data[sample][0],data[sample][1],data[sample][2]);
+        fclose(fp);
+    }
+    // update offset registers
+    for(char axis = 0x00; axis < 0x03; axis++)
+        setOffset(axis,calibration_offset[axis]);
+    // return control registers to original state
+    setDataFormatControl(data_format);
+    setBwRateReg(bw_rate);
+    setPowerControl(power_control);
 }
\ No newline at end of file