Republished Library, to be refined for use with the SparkFun 9DOF in HARP project.
Fork of ADXL345 by
Diff: ADXL345.cpp
- 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