Unit testing and development for 9DOF sparkfun sensor stick
Dependencies: ADXL345 HMC5883L ITG3200 mbed
Revision 3:5e21a352e236, committed 2012-11-05
- Comitter:
- tylerjw
- Date:
- Mon Nov 05 18:35:42 2012 +0000
- Parent:
- 2:d7e66940541d
- Child:
- 4:8a77e21d08f1
- Commit message:
- Working adxl built in test and calibration test in adxl345unit;
Changed in this revision
--- a/ADXL345.lib Thu Nov 01 18:46:58 2012 +0000 +++ b/ADXL345.lib Mon Nov 05 18:35:42 2012 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/tylerjw/code/ADXL345/#839128c6e20a +http://mbed.org/users/tylerjw/code/ADXL345/#4cdd4315189f
--- a/adxl345unit.cpp Thu Nov 01 18:46:58 2012 +0000 +++ b/adxl345unit.cpp Mon Nov 05 18:35:42 2012 +0000 @@ -28,7 +28,7 @@ #include "adxl345unit.h" -ADXL345UNIT::ADXL345UNIT(I2C &i2c) : adxl345_(i2c), pc_(USBTX, USBRX), local_("local"), open_file_(LED1) +ADXL345UNIT::ADXL345UNIT(I2C &i2c, Timer &t) : adxl345_(i2c), pc_(USBTX, USBRX), open_file_(LED1), t_(t) { pc_.baud(9600); open_file_ = 0; @@ -40,85 +40,73 @@ // place initilazaition code here } -bool ADXL345UNIT::builtInSelfTest() +bool ADXL345UNIT::builtInSelfTest(bool store_raw) { + LocalFileSystem local("local"); + FILE *fp; // file pointer + bool test_pass[4] = {true,true,true,true}; bool full_test = true; - int st_off[3][100]; // {x,y,z}, self test off - int st_off_avg[3]; // self test off average - int st_on[3][100]; // {x,y,z}, self test off - int st_on_avg[3]; // self test on average - int delta[3]; // st_on - st_off + int16_t st_off[100][3]; // {x,y,z}, self test off + int16_t st_off_avg[3]; // self test off average + int16_t st_on[100][3]; // {x,y,z}, self test off + int16_t st_on_avg[3]; // self test on average + int16_t delta[3]; // st_on - st_off const char axisK[3] = {'X','Y','Z'}; - const int resolutionsK[4] = {16,8,4,2}; + const int16_t resolutionsK[4] = {16,8,4,2}; const char data_formatK[4] = {ADXL345_16G, ADXL345_8G, ADXL345_4G, (ADXL345_2G | ADXL345_FULL_RES)}; - const int delta_minK[4][3] = {{6,-67,10},{12,-135,19},{25,-270,38},{50,-540,75}}; // {{16g},{8g},{4g},{2g}} from datasheet - const int delta_maxK[4][3] = {{67,-6,110},{135,-12,219},{270,-25,438},{540,-50,875}}; + const int16_t delta_minK[4][3] = {{6,-67,10},{12,-135,19},{25,-270,38},{50,-540,75}}; // {{16g},{8g},{4g},{2g}} from datasheet + const int16_t delta_maxK[4][3] = {{67,-6,110},{135,-12,219},{270,-25,438},{540,-50,875}}; - Timer t; // for timming sample readings - float start_time, elapsed_time; - float period = 0.001; // period of sample rate + float period = 0.01; // period of sample rate + + adxl345_.setDataRate(ADXL345_100HZ); // 100Hz data rate + adxl345_.setPowerMode(0); // high power for(int res = 0; res < 4; res++) { //print starting message pc_.printf("ADXL345: Starting Built In Self Test (%dg resolution)... \n\r", resolutionsK[res]); + //wait 1.1ms - wait(0.0011); + wait(0.0111); + + pc_.puts("Calibrating... "); //initial command sequence - adxl345_.setDataFormatControl(data_formatK[res]); // 16g, 13bit mode - adxl345_.setDataRate(ADXL345_100HZ); // 100Hz data rate - adxl345_.setPowerMode(0); // high power + adxl345_.setDataFormatControl(data_formatK[res]); adxl345_.setPowerControl(0x08); // start measurement - adxl345_.setInterruptEnableControl(0x80); // enable data_ready interupt (not needed?) - //wait 1.1ms - wait(0.0011); + //adxl345_.setInterruptEnableControl(0x80); // enable data_ready interupt (not needed?) + pc_.puts("Done!\r\n"); + + //wait 11.1ms + wait(0.0111); + + pc_.puts("Sampling: "); //take 100 data points and average (100Hz) - for(int sample = 0; sample < 100; sample++) { - start_time = t.read(); - - adxl345_.getOutput(st_off[sample]); + sample100avg(period, st_off, st_off_avg, &t_); - elapsed_time = t.read() - start_time; - if(elapsed_time > period) { - pc_.puts("Error: elapsed_time > period\n\r"); - return false; - } - wait(period - elapsed_time); - } - for(int axis = 0; axis < 3; axis++) - st_off_avg[axis] = arr_avg(st_off[axis], 100); // average - //activate self test adxl345_.setDataFormatControl(data_formatK[res] | ADXL345_SELF_TEST); // self test enabled - //wait 1.1ms - wait(0.0011); - //take 100 data points and average (100Hz) - for(int sample = 0; sample < 100; sample++) { - start_time = t.read(); - - adxl345_.getOutput(st_on[sample]); - elapsed_time = t.read() - start_time; - if(elapsed_time > period) { - pc_.puts("Error: elapsed_time > period\n\r"); - return false; - } - wait(period - elapsed_time); - } - for(int axis = 0; axis < 3; axis++) - st_on_avg[axis] = arr_avg(st_on[axis], 100); // average + //wait 11.1ms + wait(0.0111); + + //take 100 data points and average (100Hz) + sample100avg(period, st_on, st_on_avg, &t_); + pc_.puts("Done!\r\n"); + //inactivate self test adxl345_.setDataFormatControl(data_formatK[res]); // self test off + //calculate self test delta(change) and compare to limits in data sheet //open file open_file_ = 1; - FILE *fp = fopen("/local/ADXL_BIT.csv", "a"); // open append, or create - fprintf(fp, "ADXL345 Built In Self-Test at %dg resolution.\r\nAxis,Min,Max,Actual,Pass\r\n", resolutionsK[res]); + fp = fopen("/local/BIST.csv", "a"); // open append, or create + fprintf(fp, "ADXL345 Built In Self-Test\n\rResolution,%d,g\r\n\r\nAxis,Min,Max,Actual,Pass\r\n", resolutionsK[res]); for(int axis = 0; axis < 3; axis++) { delta[axis] = st_on_avg[axis] - st_off_avg[axis]; - bool test = (delta[axis] > delta_minK[res][axis] && delta[axis] < delta_maxK[res][axis]); + bool test = (delta[axis] >= delta_minK[res][axis] && delta[axis] <= delta_maxK[res][axis]); if(test == false) test_pass[res] = full_test = false; fprintf(fp, "%c,%4d,%4d,%4d,%s\r\n", axisK[axis],delta_minK[res][axis],delta_maxK[res][axis],delta[axis],(test)?"pass":"fail"); @@ -127,16 +115,113 @@ // close file fclose(fp); open_file_ = 0; - pc_.printf("%s\r\n", (test_pass[res])?"pass":"fail"); + pc_.printf("Test Result: %s\r\n", (test_pass[res])?"pass":"fail"); + + pc_.puts("Dumping raw data to BIT_RAW.csv... "); + open_file_ = 1; + + if(store_raw) { + //dump raw data to ADXL_RAW.csv + fp = fopen("/local/BIST_RAW.csv", "a"); // open append, or create + fprintf(fp, "ADXL345 Built In Self-Test Raw Data\n\rResolution,%d,g\r\nSample,X st_off,X st_on,Y st_off,Y st_on,Z st_off, Z st_off\r\n", resolutionsK[res]); + for(int sample = 0; sample < 100; sample++) + fprintf(fp, "%3d,%4d,%4d,%4d,%4d,%4d,%4d\r\n", (sample+1),st_on[sample][0],st_off[sample][0],st_on[sample][1],st_off[sample][1],st_on[sample][2],st_off[sample][2]); + fputs("\r\n",fp); + fclose(fp); + open_file_ = 0; + } + + pc_.puts("Done!\r\n"); } + //return result return full_test; } -int ADXL345UNIT::arr_avg(int* arr,int length) +void ADXL345UNIT::offsetCalibration(bool store_raw) +{ + int16_t data[100][3]; // {x,y,z}, data + int16_t data_avg[3]; + int16_t calibration_offset[3]; + + LocalFileSystem local("local"); + + float period = 0.01; // period of sample rate + + // place sensor in x = 0g, y = 0g, z = 1g orientation + pc_.puts("Offset Calibration: Sensor should be in x=0g,y=0g,z=1g orientation\r\n"); + + // wait 11.1ms + wait(0.0111); + + // initalize command sequence + adxl345_.setDataFormatControl((ADXL345_16G | ADXL345_FULL_RES)); + adxl345_.setDataRate(ADXL345_100HZ); // 100Hz data rate + adxl345_.setPowerMode(0); // high power + adxl345_.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 + + // display and store values + pc_.printf("X offset: %d\r\n", calibration_offset[0]); + pc_.printf("Y offset: %d\r\n", calibration_offset[1]); + pc_.printf("Z offset: %d\r\n", calibration_offset[2]); + + open_file_ = 1; + 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]); + if(store_raw) { + 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); + open_file_ = 0; +} + +bool ADXL345UNIT::methodTest() +{ + // constructors and size of obj tests + // destructor test + // get device id [0xE5] + // set power mode > get bw rate + // +} + +int16_t ADXL345UNIT::arr_avg(int16_t* arr,int16_t length) { double average; for(int i = 0; i < length; i++) average += static_cast<double>(arr[i]) / static_cast<double>(length); - return static_cast<int>(average); + return static_cast<int16_t>(average); +} + +void ADXL345UNIT::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(); + + adxl345_.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); + } } \ No newline at end of file
--- a/adxl345unit.h Thu Nov 01 18:46:58 2012 +0000 +++ b/adxl345unit.h Mon Nov 05 18:35:42 2012 +0000 @@ -40,7 +40,7 @@ * * @param i2c buss to use for adxl345 */ - ADXL345UNIT(I2C &i2c); + ADXL345UNIT(I2C &i2c, Timer &t); /** * Initalize the device @@ -48,16 +48,41 @@ void init(); /** - * Perform built in self test and print results to ADXL_BIT.csv + * Perform built in self test and print results to BIST.csv + * Raw data is printed to BIST_RAW.csv + * + * NOT YET TESTED + * + * @param store_raw true to store raw data + * @returns test result: true if passed, false if failed + */ + bool builtInSelfTest(bool); + + /** + * Performs the offset callibration test and prints to OFF_CAL.csv + * + * NOT YET TESTED * - * @returns true if passed, false if failed + * TODO: implement into ADXL345 class. + * + * @param store_raw true to store raw data */ - bool builtInSelfTest(); + void offsetCalibration(bool); + + /** + * Tests the method of ADXL345 library + * + * Results stored in method.txt + * + * @returns test result, true if passed, false if not + */ + bool methodTest(); + private: ADXL345 adxl345_; Serial pc_; - LocalFileSystem local_; DigitalOut open_file_; + Timer t_; /** * Averages an array of n length @@ -65,7 +90,17 @@ * @param the array * @param length */ - int arr_avg(int*,int); + int16_t arr_avg(int16_t*,int16_t); + + /** + * Sample 100 times and average + * + * @param period of sample rate + * @param array to hold raw data, should be int16_t[100][3] (sample,axis) + * @param array to hold averages, should be 3 in length + * @param pointer to timer object (should already be started) + */ + void sample100avg(float, int16_t[][3], int16_t*, Timer*); }; #endif \ No newline at end of file
--- a/main.cpp Thu Nov 01 18:46:58 2012 +0000 +++ b/main.cpp Mon Nov 05 18:35:42 2012 +0000 @@ -17,12 +17,54 @@ #include "mbed.h" //#include "ITG3200.h" //#include "HMC5883L.h" +#include "adxl345unit.h" I2C i2c_bus(p28, p27); +ADXL345 accel(i2c_bus); +Timer t; +Serial pc(USBTX, USBRX); +//ADXL345UNIT accel_test(i2c_bus, t); int main() { + t.start(); + pc.baud(9600); + accel.calibrate(&t, true); + //accel_test.builtInSelfTest(true); + //accel_test.offsetCalibration(true); +/* + int sample[3]; + float elapsed_time; + float time_stamp[100]; + int samples[100][3]; + Timer t; + Serial pc(USBTX, USBRX); + pc.baud(9600); + + accel.setDataRate(ADXL345_100HZ); // 100Hz data rate + accel.setDataFormatControl(ADXL345_16G | ADXL345_FULL_RES); + accel.setPowerControl(0x08); // start measurement + + wait(0.001); + + t.start(); + accel.getOutput(sample); + elapsed_time = t.read(); + + pc.printf("Sample took %f seconds.\r\n", elapsed_time); + pc.printf("x: %d, y: %d, z: %d\r\n", sample[0],sample[1],sample[2]); + + for(int i = 0; i < 100; i++) { + t.reset(); + accel.getOutput(samples[i]); + time_stamp[i] = t.read(); + } + for(int i = 0; i < 100; i++) { + pc.printf("Sample took %f seconds.\r\n", time_stamp[i]); + pc.printf("x: %d, y: %d, z: %d\r\n", samples[i][0],samples[i][1],samples[i][2]); + } + */ } /* @@ -31,7 +73,7 @@ Serial pc(USBTX, USBRX); pc.baud(9600); - + HMC5883L compass(i2c_bus); int data[3];