A hello world for inertial sensors
Dependencies: FXAS21000 FXOS8700Q mbed
Fork of FRDM-STBC-AGM01 by
main.cpp@4:5ab2bb2f062b, 2015-06-30 (annotated)
- Committer:
- Elecia
- Date:
- Tue Jun 30 16:23:32 2015 +0000
- Revision:
- 4:5ab2bb2f062b
- Parent:
- 3:123b546e4a5c
Added element14 link
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
screamer | 0:bfb567985c64 | 1 | /* Copyright (c) 2010-2011 mbed.org, MIT License |
screamer | 0:bfb567985c64 | 2 | * |
screamer | 0:bfb567985c64 | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
screamer | 0:bfb567985c64 | 4 | * and associated documentation files (the "Software"), to deal in the Software without |
screamer | 0:bfb567985c64 | 5 | * restriction, including without limitation the rights to use, copy, modify, merge, publish, |
screamer | 0:bfb567985c64 | 6 | * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the |
screamer | 0:bfb567985c64 | 7 | * Software is furnished to do so, subject to the following conditions: |
screamer | 0:bfb567985c64 | 8 | * |
screamer | 0:bfb567985c64 | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
screamer | 0:bfb567985c64 | 10 | * substantial portions of the Software. |
screamer | 0:bfb567985c64 | 11 | * |
screamer | 0:bfb567985c64 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
screamer | 0:bfb567985c64 | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
screamer | 0:bfb567985c64 | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
screamer | 0:bfb567985c64 | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
screamer | 0:bfb567985c64 | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
screamer | 0:bfb567985c64 | 17 | */ |
screamer | 0:bfb567985c64 | 18 | |
Elecia | 3:123b546e4a5c | 19 | /* This project was created by Elecia White of Embedded.fm and Logical Elegance using hardware |
Elecia | 3:123b546e4a5c | 20 | * supplied by element14. It uses |
Elecia | 3:123b546e4a5c | 21 | * * a FRDM-KL05Z board (http://www.newark.com/webapp/wcs/stores/servlet/ProductDisplay?catalogId=15003&langId=-1&urlRequestType=Base&partNumber=53W2646&storeId=10194) |
Elecia | 3:123b546e4a5c | 22 | * * an IMU sensor toolbox shield (http://www.newark.com/webapp/wcs/stores/servlet/ProductDisplay?catalogId=15003&langId=-1&urlRequestType=Base&partNumber=30Y6365&storeId=10194) |
Elecia | 3:123b546e4a5c | 23 | * * a momentary button connected to A5 and ground |
Elecia | 3:123b546e4a5c | 24 | * Together, these create a sort of "hello world" for the accelerometer, gyro, and magnetometer so |
Elecia | 3:123b546e4a5c | 25 | * people can see what each sensor does. |
Elecia | 3:123b546e4a5c | 26 | * |
Elecia | 3:123b546e4a5c | 27 | * On boot, the system will have no LED running though it will be outputting IMU |
Elecia | 3:123b546e4a5c | 28 | * data on the serial port available from USB (115200, 8, None, 1). |
Elecia | 3:123b546e4a5c | 29 | * |
Elecia | 3:123b546e4a5c | 30 | * Press the button to go into accelerometer demo mode. The LED will come on and |
Elecia | 3:123b546e4a5c | 31 | * tell you upon which axis it feels gravity (red = X, green = Y, blue = Z). |
Elecia | 3:123b546e4a5c | 32 | * As you move it, the LED will change. If you jiggle it, you can see the light |
Elecia | 3:123b546e4a5c | 33 | * change in intensity. A gentle toss up might lead to a dark sensor at the top |
Elecia | 3:123b546e4a5c | 34 | * of the arc (free fall!). And if you tap on the device, you will likely see a |
Elecia | 3:123b546e4a5c | 35 | * brighter flare of the LED: accelerometers do really well with tap detection. |
Elecia | 3:123b546e4a5c | 36 | * |
Elecia | 3:123b546e4a5c | 37 | * Press the button again to get into gyro demo mode. The LED will go off until |
Elecia | 3:123b546e4a5c | 38 | * you turn the unit. Spinning it around one axis is the obvious mechanism. But |
Elecia | 3:123b546e4a5c | 39 | * try swinging it back and forth in different direction. Look at the joints on |
Elecia | 3:123b546e4a5c | 40 | * your arm, what colors do you see when you move (and how consistently)? |
Elecia | 3:123b546e4a5c | 41 | * |
Elecia | 3:123b546e4a5c | 42 | * Press the button again to go into the North Star mode. Remember, it might light |
Elecia | 3:123b546e4a5c | 43 | * your way home, but only if you and it are pointed in the same direction. |
Elecia | 3:123b546e4a5c | 44 | * |
Elecia | 4:5ab2bb2f062b | 45 | * For more information, see the element14 post: http://www.element14.com/community/community/designcenter/kinetis_kl2_freedom_board/blog/2015/06/30/brave-new-hello-world |
Elecia | 3:123b546e4a5c | 46 | * |
Elecia | 3:123b546e4a5c | 47 | */ |
screamer | 0:bfb567985c64 | 48 | #include "mbed.h" |
screamer | 0:bfb567985c64 | 49 | #include "FXOS8700Q.h" |
screamer | 0:bfb567985c64 | 50 | #include "FXAS21000.h" |
Elecia | 3:123b546e4a5c | 51 | #include "led.h" |
Elecia | 3:123b546e4a5c | 52 | #include "Adafruit_9DOF.h" |
Elecia | 3:123b546e4a5c | 53 | #include "northStarFuncs.h" |
Elecia | 3:123b546e4a5c | 54 | #include "button.h" |
screamer | 0:bfb567985c64 | 55 | |
Elecia | 3:123b546e4a5c | 56 | #define ACCEL_FLOAT_TO_MG_INT (1000.0F) // G to mG |
Elecia | 3:123b546e4a5c | 57 | #define PI_F 3.14159265 |
Elecia | 3:123b546e4a5c | 58 | #define DEGREES_TO_MRADS (1000.0*(2.0*PI_F/360.0)) |
screamer | 0:bfb567985c64 | 59 | |
screamer | 0:bfb567985c64 | 60 | FXOS8700Q_acc combo_acc(D14, D15, FXOS8700CQ_SLAVE_ADDR0); |
screamer | 0:bfb567985c64 | 61 | FXOS8700Q_mag combo_mag(D14, D15, FXOS8700CQ_SLAVE_ADDR0); |
screamer | 0:bfb567985c64 | 62 | FXAS21000 gyro(D14, D15); |
screamer | 0:bfb567985c64 | 63 | |
Elecia | 3:123b546e4a5c | 64 | Serial pc(USBTX, USBRX); |
Elecia | 3:123b546e4a5c | 65 | SMART_LED smartLed(LED1, LED2, LED3); |
Elecia | 3:123b546e4a5c | 66 | DigitalIn gButton(A5, PullUp); |
Elecia | 3:123b546e4a5c | 67 | |
Elecia | 3:123b546e4a5c | 68 | typedef struct { |
Elecia | 3:123b546e4a5c | 69 | int16_t a[NUM_AXIS]; // 3D accelerometer data in 0.001 G (milliGs) |
Elecia | 3:123b546e4a5c | 70 | int16_t m[NUM_AXIS]; // 3D magnetometer data in 0.001 gauss (milliGauss) |
Elecia | 3:123b546e4a5c | 71 | int16_t g[NUM_AXIS]; // 3D angular rate darta in degrees per second |
Elecia | 3:123b546e4a5c | 72 | } tImuData; |
Elecia | 3:123b546e4a5c | 73 | |
Elecia | 3:123b546e4a5c | 74 | |
Elecia | 3:123b546e4a5c | 75 | // UpdateLeds uses the inertial data to set the LED (according to the current mode). |
Elecia | 3:123b546e4a5c | 76 | // It alsu updates the current mode when the button is pressed |
Elecia | 3:123b546e4a5c | 77 | int UpdateLed(tImuData *imuData) |
Elecia | 3:123b546e4a5c | 78 | { |
Elecia | 3:123b546e4a5c | 79 | static eModes gMode = OFF; |
Elecia | 3:123b546e4a5c | 80 | uint8_t r = 0, b = 0, g = 0; |
Elecia | 3:123b546e4a5c | 81 | int delayMs = 10; |
screamer | 0:bfb567985c64 | 82 | |
Elecia | 3:123b546e4a5c | 83 | switch (gMode) { |
Elecia | 3:123b546e4a5c | 84 | case ACCEL: |
Elecia | 3:123b546e4a5c | 85 | // the color brightness is the abs value of the direction, |
Elecia | 3:123b546e4a5c | 86 | // scaled to one G |
Elecia | 3:123b546e4a5c | 87 | r = conditionAccels(imuData->a[X]); |
Elecia | 3:123b546e4a5c | 88 | g = conditionAccels(imuData->a[Y]); |
Elecia | 3:123b546e4a5c | 89 | b = conditionAccels(imuData->a[Z]); |
Elecia | 3:123b546e4a5c | 90 | delayMs = 10; // 100 Hz readings on the accel |
Elecia | 3:123b546e4a5c | 91 | break; |
Elecia | 3:123b546e4a5c | 92 | case MAG: |
Elecia | 3:123b546e4a5c | 93 | tOrientation orientation; |
Elecia | 3:123b546e4a5c | 94 | if (fusionGetOrientation(imuData->a, imuData->m, &orientation)) { |
Elecia | 3:123b546e4a5c | 95 | // N = white, E = green, W = red, S = dark |
Elecia | 3:123b546e4a5c | 96 | r = conditionMags(orientation.heading, -45.0, 120.0); |
Elecia | 3:123b546e4a5c | 97 | g = conditionMags(orientation.heading, 45.0, 120.0); |
Elecia | 3:123b546e4a5c | 98 | b = conditionMags(orientation.heading, 0.0, 120.0); |
Elecia | 3:123b546e4a5c | 99 | } else{ |
Elecia | 3:123b546e4a5c | 100 | printf("orientation failed\r\n"); |
Elecia | 3:123b546e4a5c | 101 | } |
Elecia | 3:123b546e4a5c | 102 | delayMs = 20; // 50 Hz readings on the mag |
Elecia | 3:123b546e4a5c | 103 | break; |
Elecia | 3:123b546e4a5c | 104 | case GYRO: |
Elecia | 3:123b546e4a5c | 105 | // scale the brightness to the motion being |
Elecia | 3:123b546e4a5c | 106 | // experienced, where X = R, Y = B, Z = G |
Elecia | 3:123b546e4a5c | 107 | r = conditionGyros(imuData->g[X]); |
Elecia | 3:123b546e4a5c | 108 | g = conditionGyros(imuData->g[Y]); |
Elecia | 3:123b546e4a5c | 109 | b = conditionGyros(imuData->g[Z]); |
Elecia | 3:123b546e4a5c | 110 | delayMs = 10; |
Elecia | 3:123b546e4a5c | 111 | break; |
Elecia | 3:123b546e4a5c | 112 | default: |
Elecia | 3:123b546e4a5c | 113 | r = g = b = 0; |
Elecia | 3:123b546e4a5c | 114 | delayMs = 10; |
Elecia | 3:123b546e4a5c | 115 | break; |
Elecia | 3:123b546e4a5c | 116 | } |
Elecia | 3:123b546e4a5c | 117 | if (debounceButtonPress(gButton)) { |
Elecia | 3:123b546e4a5c | 118 | printf("Button pressed from %d", gMode); |
Elecia | 3:123b546e4a5c | 119 | gMode = changeMode(gMode); |
Elecia | 3:123b546e4a5c | 120 | printf(" to new mode %d\r\n", gMode); |
Elecia | 3:123b546e4a5c | 121 | } |
Elecia | 3:123b546e4a5c | 122 | smartLed.set(r, g, b); |
Elecia | 3:123b546e4a5c | 123 | return (delayMs); |
Elecia | 3:123b546e4a5c | 124 | } |
screamer | 0:bfb567985c64 | 125 | |
screamer | 0:bfb567985c64 | 126 | int main() |
Elecia | 3:123b546e4a5c | 127 | { |
ajtag | 2:0cccf85f9b3f | 128 | pc.baud(115200); |
ajtag | 2:0cccf85f9b3f | 129 | |
ajtag | 2:0cccf85f9b3f | 130 | float gyro_data[3]; |
screamer | 0:bfb567985c64 | 131 | MotionSensorDataUnits adata; |
screamer | 0:bfb567985c64 | 132 | MotionSensorDataUnits mdata; |
screamer | 0:bfb567985c64 | 133 | printf("\r\nStarting\r\n\r\n"); |
screamer | 0:bfb567985c64 | 134 | |
screamer | 0:bfb567985c64 | 135 | combo_acc.enable(); |
screamer | 0:bfb567985c64 | 136 | combo_mag.enable(); |
ajtag | 2:0cccf85f9b3f | 137 | printf("FXOS8700 Combo mag = %X\r\n", combo_mag.whoAmI()); |
ajtag | 2:0cccf85f9b3f | 138 | printf("FXOS8700 Combo acc = %X\r\n", combo_acc.whoAmI()); |
screamer | 0:bfb567985c64 | 139 | printf("FXAS21000 Gyro = %X\r\n", gyro.getWhoAmI()); |
Elecia | 3:123b546e4a5c | 140 | |
screamer | 0:bfb567985c64 | 141 | while(1) { |
Elecia | 3:123b546e4a5c | 142 | tImuData imuData; |
screamer | 0:bfb567985c64 | 143 | combo_acc.getAxis(adata); |
Elecia | 3:123b546e4a5c | 144 | imuData.a[X] = adata.x * ACCEL_FLOAT_TO_MG_INT; |
Elecia | 3:123b546e4a5c | 145 | imuData.a[Y] = adata.y * ACCEL_FLOAT_TO_MG_INT; |
Elecia | 3:123b546e4a5c | 146 | imuData.a[Z] = adata.z * ACCEL_FLOAT_TO_MG_INT; |
screamer | 0:bfb567985c64 | 147 | printf("FXOS8700 Acc: X:%6.3f Y:%6.3f Z:%6.3f\r\n", adata.x, adata.y, adata.z); |
screamer | 0:bfb567985c64 | 148 | |
Elecia | 3:123b546e4a5c | 149 | combo_mag.getAxis(mdata); // data in mGauss already |
Elecia | 3:123b546e4a5c | 150 | imuData.m[X] = mdata.x; |
Elecia | 3:123b546e4a5c | 151 | imuData.m[Y] = mdata.y; |
Elecia | 3:123b546e4a5c | 152 | imuData.m[Z] = mdata.z; |
screamer | 0:bfb567985c64 | 153 | printf("FXOS8700 Mag: X:%6.2f Y:%6.2f Z:%6.2f\r\n", mdata.x, mdata.y, mdata.z); |
Elecia | 3:123b546e4a5c | 154 | |
screamer | 0:bfb567985c64 | 155 | gyro.ReadXYZ(gyro_data); |
Elecia | 3:123b546e4a5c | 156 | imuData.g[X] = gyro_data[0] * DEGREES_TO_MRADS; |
Elecia | 3:123b546e4a5c | 157 | imuData.g[Y] = gyro_data[1] * DEGREES_TO_MRADS; |
Elecia | 3:123b546e4a5c | 158 | imuData.g[Z] = gyro_data[2] * DEGREES_TO_MRADS; |
Elecia | 3:123b546e4a5c | 159 | printf("FXAS21000 Gyro: X:%6.2f Y:%6.2f Z:%6.2f\r\n", gyro_data[0], gyro_data[1], gyro_data[2]); |
screamer | 0:bfb567985c64 | 160 | printf("\r\n"); |
screamer | 0:bfb567985c64 | 161 | |
Elecia | 3:123b546e4a5c | 162 | int delayMs = UpdateLed(&imuData); |
Elecia | 3:123b546e4a5c | 163 | wait_ms(delayMs); |
screamer | 0:bfb567985c64 | 164 | } |
screamer | 0:bfb567985c64 | 165 | } |