Unit testing and development for 9DOF sparkfun sensor stick
Dependencies: ADXL345 HMC5883L ITG3200 mbed
main.cpp@1:dc730a26cdc2, 2012-10-30 (annotated)
- Committer:
- tylerjw
- Date:
- Tue Oct 30 23:47:14 2012 +0000
- Revision:
- 1:dc730a26cdc2
- Parent:
- 0:ac2f55940442
- Child:
- 2:d7e66940541d
HMC5883L prof of concept
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tylerjw | 0:ac2f55940442 | 1 | /** |
tylerjw | 0:ac2f55940442 | 2 | 10 second 9-dof data log |
tylerjw | 0:ac2f55940442 | 3 | |
tylerjw | 0:ac2f55940442 | 4 | The purpose of this program is to demonstrate and calibrate the three |
tylerjw | 0:ac2f55940442 | 5 | sensors on teh 9-doft board. |
tylerjw | 0:ac2f55940442 | 6 | |
tylerjw | 0:ac2f55940442 | 7 | The first version of this software will test the ITG3200 gyro to find |
tylerjw | 0:ac2f55940442 | 8 | the temperature drift line. Data will be logged to help determine the |
tylerjw | 0:ac2f55940442 | 9 | thermal drift line. |
tylerjw | 0:ac2f55940442 | 10 | See: http://mbed.org/users/gltest26/code/ITG3200/wiki/Thermal-Drift |
tylerjw | 1:dc730a26cdc2 | 11 | |
tylerjw | 1:dc730a26cdc2 | 12 | The second versoin of this will test the HMC5883L 3 axis magnometer |
tylerjw | 0:ac2f55940442 | 13 | */ |
tylerjw | 0:ac2f55940442 | 14 | |
tylerjw | 0:ac2f55940442 | 15 | #include "mbed.h" |
tylerjw | 1:dc730a26cdc2 | 16 | //#include "ITG3200.h" |
tylerjw | 1:dc730a26cdc2 | 17 | |
tylerjw | 1:dc730a26cdc2 | 18 | // configuration register a |
tylerjw | 1:dc730a26cdc2 | 19 | #define AVG1_SAMPLES 0x00 |
tylerjw | 1:dc730a26cdc2 | 20 | #define AVG2_SAMPLES 0x20 |
tylerjw | 1:dc730a26cdc2 | 21 | #define AVG4_SAMPLES 0x80 |
tylerjw | 1:dc730a26cdc2 | 22 | #define AVG8_SAMPLES 0xC0 |
tylerjw | 1:dc730a26cdc2 | 23 | |
tylerjw | 1:dc730a26cdc2 | 24 | #define OUTPUT_RATE_0_75 0x00 |
tylerjw | 1:dc730a26cdc2 | 25 | #define OUTPUT_RATE_1_5 0x04 |
tylerjw | 1:dc730a26cdc2 | 26 | #define OUTPUT_RATE_3 0x08 |
tylerjw | 1:dc730a26cdc2 | 27 | #define OUTPUT_RATE_7_5 0x0C |
tylerjw | 1:dc730a26cdc2 | 28 | #define OUTPUT_RATE_15 0x10 |
tylerjw | 1:dc730a26cdc2 | 29 | #define OUTPUT_RATE_30 0x14 |
tylerjw | 1:dc730a26cdc2 | 30 | #define OUTPUT_RATE_75 0x18 |
tylerjw | 1:dc730a26cdc2 | 31 | |
tylerjw | 1:dc730a26cdc2 | 32 | #define NORMAL_MEASUREMENT 0x00 |
tylerjw | 1:dc730a26cdc2 | 33 | #define POSITIVE_BIAS 0x01 |
tylerjw | 1:dc730a26cdc2 | 34 | #define NEGATIVE_BIAS 0x02 |
tylerjw | 1:dc730a26cdc2 | 35 | |
tylerjw | 1:dc730a26cdc2 | 36 | // mode register |
tylerjw | 1:dc730a26cdc2 | 37 | #define CONTINUOUS_MODE 0x00 |
tylerjw | 1:dc730a26cdc2 | 38 | #define SINGLE_MODE 0x01 |
tylerjw | 1:dc730a26cdc2 | 39 | #define IDLE_MODE 0x02 |
tylerjw | 1:dc730a26cdc2 | 40 | |
tylerjw | 1:dc730a26cdc2 | 41 | // status register |
tylerjw | 1:dc730a26cdc2 | 42 | #define LOCK 0x02 |
tylerjw | 1:dc730a26cdc2 | 43 | #define READY 0x01 |
tylerjw | 1:dc730a26cdc2 | 44 | |
tylerjw | 1:dc730a26cdc2 | 45 | char addr = 0x3D; |
tylerjw | 1:dc730a26cdc2 | 46 | |
tylerjw | 1:dc730a26cdc2 | 47 | I2C i2c_(p28, p27); // sda, scl |
tylerjw | 1:dc730a26cdc2 | 48 | |
tylerjw | 1:dc730a26cdc2 | 49 | void setConfigurationA(char,char,char); |
tylerjw | 1:dc730a26cdc2 | 50 | char getConfigurationA(); |
tylerjw | 1:dc730a26cdc2 | 51 | void setConfigurationB(char); |
tylerjw | 1:dc730a26cdc2 | 52 | char getConfigurationB(); |
tylerjw | 1:dc730a26cdc2 | 53 | void setMode(char); |
tylerjw | 1:dc730a26cdc2 | 54 | char getMode(); |
tylerjw | 1:dc730a26cdc2 | 55 | void getXYZ(int*); |
tylerjw | 1:dc730a26cdc2 | 56 | char getStatus(); |
tylerjw | 1:dc730a26cdc2 | 57 | |
tylerjw | 1:dc730a26cdc2 | 58 | void setConfigurationA(char averaged_samples = AVG1_SAMPLES, char output_rate = OUTPUT_RATE_15, char measurement_mode = NORMAL_MEASUREMENT) |
tylerjw | 1:dc730a26cdc2 | 59 | { |
tylerjw | 1:dc730a26cdc2 | 60 | char cmd[2]; |
tylerjw | 1:dc730a26cdc2 | 61 | cmd[0] = 0x00; // register a address |
tylerjw | 1:dc730a26cdc2 | 62 | cmd[1] = averaged_samples | output_rate | measurement_mode; |
tylerjw | 1:dc730a26cdc2 | 63 | |
tylerjw | 1:dc730a26cdc2 | 64 | i2c_.write(addr, cmd, 2); |
tylerjw | 1:dc730a26cdc2 | 65 | } |
tylerjw | 1:dc730a26cdc2 | 66 | |
tylerjw | 1:dc730a26cdc2 | 67 | char getConfigurationA() |
tylerjw | 1:dc730a26cdc2 | 68 | { |
tylerjw | 1:dc730a26cdc2 | 69 | char cmd[2]; |
tylerjw | 1:dc730a26cdc2 | 70 | cmd[0] = 0x00; // register a address |
tylerjw | 1:dc730a26cdc2 | 71 | i2c_.write(addr, cmd, 1, true); |
tylerjw | 1:dc730a26cdc2 | 72 | i2c_.read(addr, &cmd[1], 1, false); |
tylerjw | 1:dc730a26cdc2 | 73 | return cmd[1]; |
tylerjw | 1:dc730a26cdc2 | 74 | } |
tylerjw | 1:dc730a26cdc2 | 75 | |
tylerjw | 1:dc730a26cdc2 | 76 | void setConfigurationB(char gain = 0x20) // default value 0x20 |
tylerjw | 1:dc730a26cdc2 | 77 | { |
tylerjw | 1:dc730a26cdc2 | 78 | char cmd[2]; |
tylerjw | 1:dc730a26cdc2 | 79 | cmd[0] = 0x01; |
tylerjw | 1:dc730a26cdc2 | 80 | cmd[1] = gain; |
tylerjw | 1:dc730a26cdc2 | 81 | |
tylerjw | 1:dc730a26cdc2 | 82 | i2c_.write(addr, cmd, 2); |
tylerjw | 1:dc730a26cdc2 | 83 | } |
tylerjw | 1:dc730a26cdc2 | 84 | |
tylerjw | 1:dc730a26cdc2 | 85 | char getConfigurationB() |
tylerjw | 1:dc730a26cdc2 | 86 | { |
tylerjw | 1:dc730a26cdc2 | 87 | char cmd[2]; |
tylerjw | 1:dc730a26cdc2 | 88 | cmd[0] = 0x01; // register b address |
tylerjw | 1:dc730a26cdc2 | 89 | i2c_.write(addr, cmd, 1, true); |
tylerjw | 1:dc730a26cdc2 | 90 | i2c_.read(addr, &cmd[1], 1, false); |
tylerjw | 1:dc730a26cdc2 | 91 | return cmd[1]; |
tylerjw | 1:dc730a26cdc2 | 92 | } |
tylerjw | 1:dc730a26cdc2 | 93 | |
tylerjw | 1:dc730a26cdc2 | 94 | void setMode(char mode = SINGLE_MODE) |
tylerjw | 1:dc730a26cdc2 | 95 | { |
tylerjw | 1:dc730a26cdc2 | 96 | char cmd[2]; |
tylerjw | 1:dc730a26cdc2 | 97 | cmd[0] = 0x02; // mode register address |
tylerjw | 1:dc730a26cdc2 | 98 | cmd[1] = mode; |
tylerjw | 1:dc730a26cdc2 | 99 | i2c_.write(addr,cmd,2); |
tylerjw | 1:dc730a26cdc2 | 100 | } |
tylerjw | 1:dc730a26cdc2 | 101 | |
tylerjw | 1:dc730a26cdc2 | 102 | char getMode() |
tylerjw | 1:dc730a26cdc2 | 103 | { |
tylerjw | 1:dc730a26cdc2 | 104 | char cmd[2]; |
tylerjw | 1:dc730a26cdc2 | 105 | cmd[0] = 0x02; // mode register address |
tylerjw | 1:dc730a26cdc2 | 106 | i2c_.write(addr, cmd, 1, true); |
tylerjw | 1:dc730a26cdc2 | 107 | i2c_.read(addr, &cmd[1], 1, false); |
tylerjw | 1:dc730a26cdc2 | 108 | return cmd[1]; |
tylerjw | 1:dc730a26cdc2 | 109 | } |
tylerjw | 1:dc730a26cdc2 | 110 | |
tylerjw | 1:dc730a26cdc2 | 111 | void getXYZ(int output[3]) |
tylerjw | 1:dc730a26cdc2 | 112 | { |
tylerjw | 1:dc730a26cdc2 | 113 | char cmd[2]; |
tylerjw | 1:dc730a26cdc2 | 114 | char data[6]; |
tylerjw | 1:dc730a26cdc2 | 115 | cmd[0] = 0x03; // starting point for reading |
tylerjw | 1:dc730a26cdc2 | 116 | i2c_.write(addr, cmd, 1, true); // set the pointer to the start of x |
tylerjw | 1:dc730a26cdc2 | 117 | i2c_.read(addr, data, 6, false); |
tylerjw | 1:dc730a26cdc2 | 118 | |
tylerjw | 1:dc730a26cdc2 | 119 | for(int i = 0; i < 3; i++) // fill the output variables |
tylerjw | 1:dc730a26cdc2 | 120 | output[i] = (data[i*2] << 8) + data[i*2+1]; |
tylerjw | 1:dc730a26cdc2 | 121 | } |
tylerjw | 1:dc730a26cdc2 | 122 | |
tylerjw | 1:dc730a26cdc2 | 123 | char getStatus() |
tylerjw | 1:dc730a26cdc2 | 124 | { |
tylerjw | 1:dc730a26cdc2 | 125 | char cmd[2]; |
tylerjw | 1:dc730a26cdc2 | 126 | cmd[0] = 0x09; // status register address |
tylerjw | 1:dc730a26cdc2 | 127 | i2c_.write(addr, cmd, 1, true); |
tylerjw | 1:dc730a26cdc2 | 128 | i2c_.read(addr, &cmd[1], 1, false); |
tylerjw | 1:dc730a26cdc2 | 129 | return cmd[1]; |
tylerjw | 1:dc730a26cdc2 | 130 | } |
tylerjw | 0:ac2f55940442 | 131 | |
tylerjw | 0:ac2f55940442 | 132 | int main() |
tylerjw | 0:ac2f55940442 | 133 | { |
tylerjw | 1:dc730a26cdc2 | 134 | Serial pc(USBTX, USBRX); |
tylerjw | 1:dc730a26cdc2 | 135 | |
tylerjw | 1:dc730a26cdc2 | 136 | pc.baud(9600); |
tylerjw | 1:dc730a26cdc2 | 137 | |
tylerjw | 1:dc730a26cdc2 | 138 | int data[3]; |
tylerjw | 1:dc730a26cdc2 | 139 | |
tylerjw | 1:dc730a26cdc2 | 140 | // configure |
tylerjw | 1:dc730a26cdc2 | 141 | setConfigurationA(AVG8_SAMPLES); // 8 sample average, 15Hz, normal mode |
tylerjw | 1:dc730a26cdc2 | 142 | setConfigurationB(); // default (0x20) |
tylerjw | 1:dc730a26cdc2 | 143 | setMode(CONTINUOUS_MODE); // continuous sample mode |
tylerjw | 1:dc730a26cdc2 | 144 | wait(0.006); // 6 milisecond pause to allow registers to fill up |
tylerjw | 1:dc730a26cdc2 | 145 | |
tylerjw | 1:dc730a26cdc2 | 146 | while(1) |
tylerjw | 1:dc730a26cdc2 | 147 | { |
tylerjw | 1:dc730a26cdc2 | 148 | getXYZ(data); |
tylerjw | 1:dc730a26cdc2 | 149 | pc.printf("x: 0x%4x, y: 0x%4x, z: 0x%4x\r\n", data[0], data[1], data[2]); |
tylerjw | 1:dc730a26cdc2 | 150 | wait(0.067); |
tylerjw | 1:dc730a26cdc2 | 151 | } |
tylerjw | 1:dc730a26cdc2 | 152 | } |
tylerjw | 1:dc730a26cdc2 | 153 | |
tylerjw | 1:dc730a26cdc2 | 154 | /* |
tylerjw | 1:dc730a26cdc2 | 155 | void itg3200_test() |
tylerjw | 1:dc730a26cdc2 | 156 | { |
tylerjw | 1:dc730a26cdc2 | 157 | DigitalOut myled(LED1); |
tylerjw | 0:ac2f55940442 | 158 | LocalFileSystem local("local"); // Create the local filesystem under the name "local" |
tylerjw | 0:ac2f55940442 | 159 | ITG3200 gyro(p28, p27); // sda, scl - gyro |
tylerjw | 1:dc730a26cdc2 | 160 | const float offset[3] = {99.5, -45.0, -29.7}; // taken from itg3200.xls curve fit test |
tylerjw | 1:dc730a26cdc2 | 161 | const float slope[3] = {-1.05, 0.95, 0.47}; |
tylerjw | 1:dc730a26cdc2 | 162 | |
tylerjw | 1:dc730a26cdc2 | 163 | gyro.setCalibrationCurve(offset, slope); |
tylerjw | 1:dc730a26cdc2 | 164 | gyro.setLpBandwidth(LPFBW_5HZ); // lowest rate low-pass filter |
tylerjw | 1:dc730a26cdc2 | 165 | |
tylerjw | 0:ac2f55940442 | 166 | Serial pc(USBTX, USBRX); |
tylerjw | 0:ac2f55940442 | 167 | |
tylerjw | 0:ac2f55940442 | 168 | pc.baud(9600); |
tylerjw | 0:ac2f55940442 | 169 | |
tylerjw | 0:ac2f55940442 | 170 | myled = 0; |
tylerjw | 0:ac2f55940442 | 171 | FILE *fp = fopen("/local/itg3200.csv", "w"); // Open "itg3200.csv" for writing |
tylerjw | 0:ac2f55940442 | 172 | fputs("Temp, X, Y, Z\r\n", fp); // place the header at the top |
tylerjw | 0:ac2f55940442 | 173 | |
tylerjw | 0:ac2f55940442 | 174 | float temperature = 0.0; |
tylerjw | 0:ac2f55940442 | 175 | int gyro_readings[3]; |
tylerjw | 0:ac2f55940442 | 176 | |
tylerjw | 0:ac2f55940442 | 177 | for(int i = 0; i < 120; i++) { // 120 seconds - 600 samples |
tylerjw | 0:ac2f55940442 | 178 | myled = 1; |
tylerjw | 1:dc730a26cdc2 | 179 | //gyro.calibrate(1.0); |
tylerjw | 1:dc730a26cdc2 | 180 | wait(0.5); |
tylerjw | 0:ac2f55940442 | 181 | myled = 0; |
tylerjw | 1:dc730a26cdc2 | 182 | gyro.getGyroXYZ(gyro_readings, ITG3200::Calibration); |
tylerjw | 1:dc730a26cdc2 | 183 | //gyro.getOffset(gyro_readings); |
tylerjw | 0:ac2f55940442 | 184 | temperature = gyro.getTemperature(); |
tylerjw | 0:ac2f55940442 | 185 | pc.printf("%3d,%f,%d,%d,%d\r\n",i,temperature,gyro_readings[0],gyro_readings[1],gyro_readings[2]); |
tylerjw | 0:ac2f55940442 | 186 | fprintf(fp, "%f,%d,%d,%d\r\n",temperature,gyro_readings[0],gyro_readings[1],gyro_readings[2]); |
tylerjw | 0:ac2f55940442 | 187 | } |
tylerjw | 0:ac2f55940442 | 188 | fclose(fp); |
tylerjw | 0:ac2f55940442 | 189 | myled = 0; |
tylerjw | 0:ac2f55940442 | 190 | } |
tylerjw | 1:dc730a26cdc2 | 191 | */ |