Unit testing and development for 9DOF sparkfun sensor stick

Dependencies:   ADXL345 HMC5883L ITG3200 mbed

Committer:
tylerjw
Date:
Thu Nov 01 18:46:58 2012 +0000
Revision:
2:d7e66940541d
Child:
3:5e21a352e236
ADXL345 unit test initial commit, built in self test (not tested)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tylerjw 2:d7e66940541d 1 /*
tylerjw 2:d7e66940541d 2 * @file adxl345unit.cpp
tylerjw 2:d7e66940541d 3 * @author Tyler Weaver
tylerjw 2:d7e66940541d 4 *
tylerjw 2:d7e66940541d 5 * @section LICENSE
tylerjw 2:d7e66940541d 6 *
tylerjw 2:d7e66940541d 7 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
tylerjw 2:d7e66940541d 8 * and associated documentation files (the "Software"), to deal in the Software without restriction,
tylerjw 2:d7e66940541d 9 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
tylerjw 2:d7e66940541d 10 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
tylerjw 2:d7e66940541d 11 * furnished to do so, subject to the following conditions:
tylerjw 2:d7e66940541d 12 *
tylerjw 2:d7e66940541d 13 * The above copyright notice and this permission notice shall be included in all copies or
tylerjw 2:d7e66940541d 14 * substantial portions of the Software.
tylerjw 2:d7e66940541d 15 *
tylerjw 2:d7e66940541d 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
tylerjw 2:d7e66940541d 17 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
tylerjw 2:d7e66940541d 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
tylerjw 2:d7e66940541d 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
tylerjw 2:d7e66940541d 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
tylerjw 2:d7e66940541d 21 *
tylerjw 2:d7e66940541d 22 * @section DESCRIPTION
tylerjw 2:d7e66940541d 23 *
tylerjw 2:d7e66940541d 24 * Unit test for the ADXL345 library.
tylerjw 2:d7e66940541d 25 *
tylerjw 2:d7e66940541d 26 * Reference:
tylerjw 2:d7e66940541d 27 */
tylerjw 2:d7e66940541d 28
tylerjw 2:d7e66940541d 29 #include "adxl345unit.h"
tylerjw 2:d7e66940541d 30
tylerjw 2:d7e66940541d 31 ADXL345UNIT::ADXL345UNIT(I2C &i2c) : adxl345_(i2c), pc_(USBTX, USBRX), local_("local"), open_file_(LED1)
tylerjw 2:d7e66940541d 32 {
tylerjw 2:d7e66940541d 33 pc_.baud(9600);
tylerjw 2:d7e66940541d 34 open_file_ = 0;
tylerjw 2:d7e66940541d 35 init();
tylerjw 2:d7e66940541d 36 }
tylerjw 2:d7e66940541d 37
tylerjw 2:d7e66940541d 38 void ADXL345UNIT::init()
tylerjw 2:d7e66940541d 39 {
tylerjw 2:d7e66940541d 40 // place initilazaition code here
tylerjw 2:d7e66940541d 41 }
tylerjw 2:d7e66940541d 42
tylerjw 2:d7e66940541d 43 bool ADXL345UNIT::builtInSelfTest()
tylerjw 2:d7e66940541d 44 {
tylerjw 2:d7e66940541d 45 bool test_pass[4] = {true,true,true,true};
tylerjw 2:d7e66940541d 46 bool full_test = true;
tylerjw 2:d7e66940541d 47
tylerjw 2:d7e66940541d 48 int st_off[3][100]; // {x,y,z}, self test off
tylerjw 2:d7e66940541d 49 int st_off_avg[3]; // self test off average
tylerjw 2:d7e66940541d 50 int st_on[3][100]; // {x,y,z}, self test off
tylerjw 2:d7e66940541d 51 int st_on_avg[3]; // self test on average
tylerjw 2:d7e66940541d 52 int delta[3]; // st_on - st_off
tylerjw 2:d7e66940541d 53
tylerjw 2:d7e66940541d 54 const char axisK[3] = {'X','Y','Z'};
tylerjw 2:d7e66940541d 55 const int resolutionsK[4] = {16,8,4,2};
tylerjw 2:d7e66940541d 56 const char data_formatK[4] = {ADXL345_16G, ADXL345_8G, ADXL345_4G, (ADXL345_2G | ADXL345_FULL_RES)};
tylerjw 2:d7e66940541d 57 const int delta_minK[4][3] = {{6,-67,10},{12,-135,19},{25,-270,38},{50,-540,75}}; // {{16g},{8g},{4g},{2g}} from datasheet
tylerjw 2:d7e66940541d 58 const int delta_maxK[4][3] = {{67,-6,110},{135,-12,219},{270,-25,438},{540,-50,875}};
tylerjw 2:d7e66940541d 59
tylerjw 2:d7e66940541d 60 Timer t; // for timming sample readings
tylerjw 2:d7e66940541d 61 float start_time, elapsed_time;
tylerjw 2:d7e66940541d 62 float period = 0.001; // period of sample rate
tylerjw 2:d7e66940541d 63
tylerjw 2:d7e66940541d 64 for(int res = 0; res < 4; res++) {
tylerjw 2:d7e66940541d 65 //print starting message
tylerjw 2:d7e66940541d 66 pc_.printf("ADXL345: Starting Built In Self Test (%dg resolution)... \n\r", resolutionsK[res]);
tylerjw 2:d7e66940541d 67 //wait 1.1ms
tylerjw 2:d7e66940541d 68 wait(0.0011);
tylerjw 2:d7e66940541d 69 //initial command sequence
tylerjw 2:d7e66940541d 70 adxl345_.setDataFormatControl(data_formatK[res]); // 16g, 13bit mode
tylerjw 2:d7e66940541d 71 adxl345_.setDataRate(ADXL345_100HZ); // 100Hz data rate
tylerjw 2:d7e66940541d 72 adxl345_.setPowerMode(0); // high power
tylerjw 2:d7e66940541d 73 adxl345_.setPowerControl(0x08); // start measurement
tylerjw 2:d7e66940541d 74 adxl345_.setInterruptEnableControl(0x80); // enable data_ready interupt (not needed?)
tylerjw 2:d7e66940541d 75 //wait 1.1ms
tylerjw 2:d7e66940541d 76 wait(0.0011);
tylerjw 2:d7e66940541d 77 //take 100 data points and average (100Hz)
tylerjw 2:d7e66940541d 78 for(int sample = 0; sample < 100; sample++) {
tylerjw 2:d7e66940541d 79 start_time = t.read();
tylerjw 2:d7e66940541d 80
tylerjw 2:d7e66940541d 81 adxl345_.getOutput(st_off[sample]);
tylerjw 2:d7e66940541d 82
tylerjw 2:d7e66940541d 83 elapsed_time = t.read() - start_time;
tylerjw 2:d7e66940541d 84 if(elapsed_time > period) {
tylerjw 2:d7e66940541d 85 pc_.puts("Error: elapsed_time > period\n\r");
tylerjw 2:d7e66940541d 86 return false;
tylerjw 2:d7e66940541d 87 }
tylerjw 2:d7e66940541d 88 wait(period - elapsed_time);
tylerjw 2:d7e66940541d 89 }
tylerjw 2:d7e66940541d 90 for(int axis = 0; axis < 3; axis++)
tylerjw 2:d7e66940541d 91 st_off_avg[axis] = arr_avg(st_off[axis], 100); // average
tylerjw 2:d7e66940541d 92
tylerjw 2:d7e66940541d 93 //activate self test
tylerjw 2:d7e66940541d 94 adxl345_.setDataFormatControl(data_formatK[res] | ADXL345_SELF_TEST); // self test enabled
tylerjw 2:d7e66940541d 95 //wait 1.1ms
tylerjw 2:d7e66940541d 96 wait(0.0011);
tylerjw 2:d7e66940541d 97 //take 100 data points and average (100Hz)
tylerjw 2:d7e66940541d 98 for(int sample = 0; sample < 100; sample++) {
tylerjw 2:d7e66940541d 99 start_time = t.read();
tylerjw 2:d7e66940541d 100
tylerjw 2:d7e66940541d 101 adxl345_.getOutput(st_on[sample]);
tylerjw 2:d7e66940541d 102
tylerjw 2:d7e66940541d 103 elapsed_time = t.read() - start_time;
tylerjw 2:d7e66940541d 104 if(elapsed_time > period) {
tylerjw 2:d7e66940541d 105 pc_.puts("Error: elapsed_time > period\n\r");
tylerjw 2:d7e66940541d 106 return false;
tylerjw 2:d7e66940541d 107 }
tylerjw 2:d7e66940541d 108 wait(period - elapsed_time);
tylerjw 2:d7e66940541d 109 }
tylerjw 2:d7e66940541d 110 for(int axis = 0; axis < 3; axis++)
tylerjw 2:d7e66940541d 111 st_on_avg[axis] = arr_avg(st_on[axis], 100); // average
tylerjw 2:d7e66940541d 112 //inactivate self test
tylerjw 2:d7e66940541d 113 adxl345_.setDataFormatControl(data_formatK[res]); // self test off
tylerjw 2:d7e66940541d 114 //calculate self test delta(change) and compare to limits in data sheet
tylerjw 2:d7e66940541d 115 //open file
tylerjw 2:d7e66940541d 116 open_file_ = 1;
tylerjw 2:d7e66940541d 117 FILE *fp = fopen("/local/ADXL_BIT.csv", "a"); // open append, or create
tylerjw 2:d7e66940541d 118 fprintf(fp, "ADXL345 Built In Self-Test at %dg resolution.\r\nAxis,Min,Max,Actual,Pass\r\n", resolutionsK[res]);
tylerjw 2:d7e66940541d 119 for(int axis = 0; axis < 3; axis++) {
tylerjw 2:d7e66940541d 120 delta[axis] = st_on_avg[axis] - st_off_avg[axis];
tylerjw 2:d7e66940541d 121 bool test = (delta[axis] > delta_minK[res][axis] && delta[axis] < delta_maxK[res][axis]);
tylerjw 2:d7e66940541d 122 if(test == false)
tylerjw 2:d7e66940541d 123 test_pass[res] = full_test = false;
tylerjw 2:d7e66940541d 124 fprintf(fp, "%c,%4d,%4d,%4d,%s\r\n", axisK[axis],delta_minK[res][axis],delta_maxK[res][axis],delta[axis],(test)?"pass":"fail");
tylerjw 2:d7e66940541d 125 }
tylerjw 2:d7e66940541d 126 fprintf(fp, "Test Result: %s\r\n\r\n", (test_pass[res])?"pass":"fail");
tylerjw 2:d7e66940541d 127 // close file
tylerjw 2:d7e66940541d 128 fclose(fp);
tylerjw 2:d7e66940541d 129 open_file_ = 0;
tylerjw 2:d7e66940541d 130 pc_.printf("%s\r\n", (test_pass[res])?"pass":"fail");
tylerjw 2:d7e66940541d 131 }
tylerjw 2:d7e66940541d 132 //return result
tylerjw 2:d7e66940541d 133 return full_test;
tylerjw 2:d7e66940541d 134 }
tylerjw 2:d7e66940541d 135
tylerjw 2:d7e66940541d 136 int ADXL345UNIT::arr_avg(int* arr,int length)
tylerjw 2:d7e66940541d 137 {
tylerjw 2:d7e66940541d 138 double average;
tylerjw 2:d7e66940541d 139 for(int i = 0; i < length; i++)
tylerjw 2:d7e66940541d 140 average += static_cast<double>(arr[i]) / static_cast<double>(length);
tylerjw 2:d7e66940541d 141 return static_cast<int>(average);
tylerjw 2:d7e66940541d 142 }