Unit testing and development for 9DOF sparkfun sensor stick
Dependencies: ADXL345 HMC5883L ITG3200 mbed
Revision 2:d7e66940541d, committed 2012-11-01
- Comitter:
- tylerjw
- Date:
- Thu Nov 01 18:46:58 2012 +0000
- Parent:
- 1:dc730a26cdc2
- Child:
- 3:5e21a352e236
- Commit message:
- ADXL345 unit test initial commit, built in self test (not tested)
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ADXL345.lib Thu Nov 01 18:46:58 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/tylerjw/code/ADXL345/#839128c6e20a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HMC5883L.lib Thu Nov 01 18:46:58 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/tylerjw/code/HMC5883L/#8eb755577f83
--- a/ITG3200.lib Tue Oct 30 23:47:14 2012 +0000 +++ b/ITG3200.lib Thu Nov 01 18:46:58 2012 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/tylerjw/code/ITG3200/#33a9ed8e8988 +http://mbed.org/users/tylerjw/code/ITG3200/#9a354f34d8e3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/adxl345unit.cpp Thu Nov 01 18:46:58 2012 +0000 @@ -0,0 +1,142 @@ +/* + * @file adxl345unit.cpp + * @author Tyler Weaver + * + * @section LICENSE + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * @section DESCRIPTION + * + * Unit test for the ADXL345 library. + * + * Reference: + */ + +#include "adxl345unit.h" + +ADXL345UNIT::ADXL345UNIT(I2C &i2c) : adxl345_(i2c), pc_(USBTX, USBRX), local_("local"), open_file_(LED1) +{ + pc_.baud(9600); + open_file_ = 0; + init(); +} + +void ADXL345UNIT::init() +{ + // place initilazaition code here +} + +bool ADXL345UNIT::builtInSelfTest() +{ + 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 + + const char axisK[3] = {'X','Y','Z'}; + const int 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}}; + + Timer t; // for timming sample readings + float start_time, elapsed_time; + float period = 0.001; // period of sample rate + + 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); + //initial command sequence + adxl345_.setDataFormatControl(data_formatK[res]); // 16g, 13bit mode + adxl345_.setDataRate(ADXL345_100HZ); // 100Hz data rate + adxl345_.setPowerMode(0); // high power + adxl345_.setPowerControl(0x08); // start measurement + adxl345_.setInterruptEnableControl(0x80); // enable data_ready interupt (not needed?) + //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_off[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_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 + //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]); + 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]); + 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"); + } + fprintf(fp, "Test Result: %s\r\n\r\n", (test_pass[res])?"pass":"fail"); + // close file + fclose(fp); + open_file_ = 0; + pc_.printf("%s\r\n", (test_pass[res])?"pass":"fail"); + } + //return result + return full_test; +} + +int ADXL345UNIT::arr_avg(int* arr,int 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); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/adxl345unit.h Thu Nov 01 18:46:58 2012 +0000 @@ -0,0 +1,71 @@ +/* + * @file adxl345unit.h + * @author Tyler Weaver + * + * @section LICENSE + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * @section DESCRIPTION + * + * Unit test for the ADXL345 library. + * + * Reference: + */ + +#ifndef ADXL345UNIT_H +#define ADXL345UNIT_H + +#include "mbed.h" +#include "ADXL345.h" + +class ADXL345UNIT { + public: + /** + * Constructor + * runs init() + * + * @param i2c buss to use for adxl345 + */ + ADXL345UNIT(I2C &i2c); + + /** + * Initalize the device + */ + void init(); + + /** + * Perform built in self test and print results to ADXL_BIT.csv + * + * @returns true if passed, false if failed + */ + bool builtInSelfTest(); + private: + ADXL345 adxl345_; + Serial pc_; + LocalFileSystem local_; + DigitalOut open_file_; + + /** + * Averages an array of n length + * + * @param the array + * @param length + */ + int arr_avg(int*,int); +}; + +#endif \ No newline at end of file
--- a/main.cpp Tue Oct 30 23:47:14 2012 +0000 +++ b/main.cpp Thu Nov 01 18:46:58 2012 +0000 @@ -1,5 +1,5 @@ /** - 10 second 9-dof data log + 9-dof unit testing The purpose of this program is to demonstrate and calibrate the three sensors on teh 9-doft board. @@ -10,147 +10,39 @@ See: http://mbed.org/users/gltest26/code/ITG3200/wiki/Thermal-Drift The second versoin of this will test the HMC5883L 3 axis magnometer + + The thrid version tests the ADXL345 library. */ #include "mbed.h" //#include "ITG3200.h" - -// configuration register a -#define AVG1_SAMPLES 0x00 -#define AVG2_SAMPLES 0x20 -#define AVG4_SAMPLES 0x80 -#define AVG8_SAMPLES 0xC0 - -#define OUTPUT_RATE_0_75 0x00 -#define OUTPUT_RATE_1_5 0x04 -#define OUTPUT_RATE_3 0x08 -#define OUTPUT_RATE_7_5 0x0C -#define OUTPUT_RATE_15 0x10 -#define OUTPUT_RATE_30 0x14 -#define OUTPUT_RATE_75 0x18 - -#define NORMAL_MEASUREMENT 0x00 -#define POSITIVE_BIAS 0x01 -#define NEGATIVE_BIAS 0x02 - -// mode register -#define CONTINUOUS_MODE 0x00 -#define SINGLE_MODE 0x01 -#define IDLE_MODE 0x02 - -// status register -#define LOCK 0x02 -#define READY 0x01 - -char addr = 0x3D; - -I2C i2c_(p28, p27); // sda, scl - -void setConfigurationA(char,char,char); -char getConfigurationA(); -void setConfigurationB(char); -char getConfigurationB(); -void setMode(char); -char getMode(); -void getXYZ(int*); -char getStatus(); - -void setConfigurationA(char averaged_samples = AVG1_SAMPLES, char output_rate = OUTPUT_RATE_15, char measurement_mode = NORMAL_MEASUREMENT) -{ - char cmd[2]; - cmd[0] = 0x00; // register a address - cmd[1] = averaged_samples | output_rate | measurement_mode; - - i2c_.write(addr, cmd, 2); -} +//#include "HMC5883L.h" -char getConfigurationA() -{ - char cmd[2]; - cmd[0] = 0x00; // register a address - i2c_.write(addr, cmd, 1, true); - i2c_.read(addr, &cmd[1], 1, false); - return cmd[1]; -} - -void setConfigurationB(char gain = 0x20) // default value 0x20 -{ - char cmd[2]; - cmd[0] = 0x01; - cmd[1] = gain; - - i2c_.write(addr, cmd, 2); -} - -char getConfigurationB() -{ - char cmd[2]; - cmd[0] = 0x01; // register b address - i2c_.write(addr, cmd, 1, true); - i2c_.read(addr, &cmd[1], 1, false); - return cmd[1]; -} - -void setMode(char mode = SINGLE_MODE) -{ - char cmd[2]; - cmd[0] = 0x02; // mode register address - cmd[1] = mode; - i2c_.write(addr,cmd,2); -} - -char getMode() -{ - char cmd[2]; - cmd[0] = 0x02; // mode register address - i2c_.write(addr, cmd, 1, true); - i2c_.read(addr, &cmd[1], 1, false); - return cmd[1]; -} - -void getXYZ(int output[3]) -{ - char cmd[2]; - char data[6]; - cmd[0] = 0x03; // starting point for reading - i2c_.write(addr, cmd, 1, true); // set the pointer to the start of x - i2c_.read(addr, data, 6, false); - - for(int i = 0; i < 3; i++) // fill the output variables - output[i] = (data[i*2] << 8) + data[i*2+1]; -} - -char getStatus() -{ - char cmd[2]; - cmd[0] = 0x09; // status register address - i2c_.write(addr, cmd, 1, true); - i2c_.read(addr, &cmd[1], 1, false); - return cmd[1]; -} +I2C i2c_bus(p28, p27); int main() { + +} + +/* +void hmc5883l_test() +{ Serial pc(USBTX, USBRX); - + pc.baud(9600); + HMC5883L compass(i2c_bus); + int data[3]; - - // configure - setConfigurationA(AVG8_SAMPLES); // 8 sample average, 15Hz, normal mode - setConfigurationB(); // default (0x20) - setMode(CONTINUOUS_MODE); // continuous sample mode - wait(0.006); // 6 milisecond pause to allow registers to fill up - - while(1) - { - getXYZ(data); - pc.printf("x: 0x%4x, y: 0x%4x, z: 0x%4x\r\n", data[0], data[1], data[2]); + + while(1) { + compass.getXYZ(data); + pc.printf("x: %4d, y: %4d, z: %4d\r\n", data[0], data[1], data[2]); wait(0.067); } } - +*/ /* void itg3200_test() {