Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@3:25eba54bace2, 2015-12-08 (annotated)
- Committer:
- alecselfridge
- Date:
- Tue Dec 08 00:21:22 2015 +0000
- Revision:
- 3:25eba54bace2
- Parent:
- 2:f3ae10decc2f
- Child:
- 4:b3c3bca604a6
Current Version 1.4 w/ all features.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| alecselfridge | 2:f3ae10decc2f | 1 | /************************************************************************ |
| alecselfridge | 2:f3ae10decc2f | 2 | * Authors: Alec Selfridge/Dylan Smith |
| alecselfridge | 2:f3ae10decc2f | 3 | * Date: 12/4/2015 |
| alecselfridge | 2:f3ae10decc2f | 4 | * Rev: 1.4 |
| alecselfridge | 2:f3ae10decc2f | 5 | * Project: RTOS Light Animations |
| alecselfridge | 2:f3ae10decc2f | 6 | * Notes: The z-axis of the accelerometer is used to calculate the |
| alecselfridge | 2:f3ae10decc2f | 7 | * "effective" angle that the board is tilted. First, the Z data |
| alecselfridge | 2:f3ae10decc2f | 8 | * (0-65) is converted to a (0-90) scale. Then the actual |
| alecselfridge | 2:f3ae10decc2f | 9 | * manipulation occurs by injecting the acc data into a response |
| alecselfridge | 2:f3ae10decc2f | 10 | * formula in the form of ax^2 - by + c. The resulting angle has |
| alecselfridge | 2:f3ae10decc2f | 11 | * no sign but it's magnitude is used to determine the rate at |
| alecselfridge | 2:f3ae10decc2f | 12 | * which LEDs will "fill", thus simulating a gravity effect. To |
| alecselfridge | 2:f3ae10decc2f | 13 | * account for both directions of tilt we check the polarity of |
| alecselfridge | 2:f3ae10decc2f | 14 | * the x-axis. A negative value indicates a tilt to the right |
| alecselfridge | 2:f3ae10decc2f | 15 | * and vice versa. |
| alecselfridge | 2:f3ae10decc2f | 16 | * A 5-axis joystick is used to mix R, G, and B values to create |
| alecselfridge | 2:f3ae10decc2f | 17 | * a custom color. The RGB LED is controled via PWM with a value |
| alecselfridge | 2:f3ae10decc2f | 18 | * of 1.0 indicating "off" and vice versa. |
| alecselfridge | 2:f3ae10decc2f | 19 | * |
| alecselfridge | 2:f3ae10decc2f | 20 | ************************************************************************/ |
| alecselfridge | 2:f3ae10decc2f | 21 | |
| alecselfridge | 0:4555c427d7a8 | 22 | #include "mbed.h" |
| alecselfridge | 1:0a93e9e88ad3 | 23 | #include "rtos.h" |
| alecselfridge | 0:4555c427d7a8 | 24 | #include "MMA7455.h" |
| alecselfridge | 0:4555c427d7a8 | 25 | |
| alecselfridge | 2:f3ae10decc2f | 26 | // response formula coefficients |
| alecselfridge | 2:f3ae10decc2f | 27 | #define X2 0.0038 |
| alecselfridge | 2:f3ae10decc2f | 28 | #define X 0.0299 |
| alecselfridge | 2:f3ae10decc2f | 29 | #define C 0.1883 |
| alecselfridge | 0:4555c427d7a8 | 30 | |
| alecselfridge | 0:4555c427d7a8 | 31 | /* |
| alecselfridge | 0:4555c427d7a8 | 32 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 33 | Display Functions |
| alecselfridge | 0:4555c427d7a8 | 34 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 35 | */ |
| alecselfridge | 0:4555c427d7a8 | 36 | void displayBanner(); |
| alecselfridge | 0:4555c427d7a8 | 37 | void newline(); |
| alecselfridge | 0:4555c427d7a8 | 38 | |
| alecselfridge | 0:4555c427d7a8 | 39 | /* |
| alecselfridge | 0:4555c427d7a8 | 40 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 41 | Utility Functions |
| alecselfridge | 0:4555c427d7a8 | 42 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 43 | */ |
| alecselfridge | 2:f3ae10decc2f | 44 | void SerialInit(void); |
| alecselfridge | 2:f3ae10decc2f | 45 | void AccInit(void); |
| alecselfridge | 2:f3ae10decc2f | 46 | void LEDsInit(void); |
| alecselfridge | 2:f3ae10decc2f | 47 | void RgbInit(void); |
| alecselfridge | 2:f3ae10decc2f | 48 | void accFeed(void); |
| alecselfridge | 0:4555c427d7a8 | 49 | void sampleAcc(int period, int32_t data[3]); |
| alecselfridge | 2:f3ae10decc2f | 50 | double getAngle(void); |
| alecselfridge | 2:f3ae10decc2f | 51 | unsigned char mapLEDS(double v); |
| alecselfridge | 2:f3ae10decc2f | 52 | void LEDPush(void const *args); |
| alecselfridge | 2:f3ae10decc2f | 53 | void RGBpicker(void const *args); |
| alecselfridge | 2:f3ae10decc2f | 54 | void testLED(void); |
| alecselfridge | 2:f3ae10decc2f | 55 | void testRGB(void); |
| alecselfridge | 0:4555c427d7a8 | 56 | |
| alecselfridge | 0:4555c427d7a8 | 57 | /* |
| alecselfridge | 0:4555c427d7a8 | 58 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 59 | Global Data |
| alecselfridge | 0:4555c427d7a8 | 60 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 61 | */ |
| alecselfridge | 0:4555c427d7a8 | 62 | const char banner[37] = "Serial Comm Established with LPC4088"; |
| alecselfridge | 0:4555c427d7a8 | 63 | // x, y, z |
| alecselfridge | 0:4555c427d7a8 | 64 | // holds current position |
| alecselfridge | 0:4555c427d7a8 | 65 | int32_t accPos[3] = {}; |
| alecselfridge | 0:4555c427d7a8 | 66 | // holds up to 20 samples of data |
| alecselfridge | 0:4555c427d7a8 | 67 | int32_t accData[20][20][20] = {}; |
| alecselfridge | 0:4555c427d7a8 | 68 | // holds calibration offsets |
| alecselfridge | 0:4555c427d7a8 | 69 | int32_t accCal[3] = {}; |
| alecselfridge | 2:f3ae10decc2f | 70 | // holds last acc value |
| alecselfridge | 2:f3ae10decc2f | 71 | int32_t acc_old = 0; |
| alecselfridge | 2:f3ae10decc2f | 72 | // holds most recent, adjusted, acc value |
| alecselfridge | 2:f3ae10decc2f | 73 | double acc_adj = 0.0; |
| alecselfridge | 2:f3ae10decc2f | 74 | // a value representing what's shown on the LEDs |
| alecselfridge | 2:f3ae10decc2f | 75 | uint8_t LEDvals = 0; |
| alecselfridge | 2:f3ae10decc2f | 76 | // tracker of how many times the joystick was used |
| alecselfridge | 2:f3ae10decc2f | 77 | uint8_t tick = 0; |
| alecselfridge | 2:f3ae10decc2f | 78 | // red value of RGB |
| alecselfridge | 2:f3ae10decc2f | 79 | float r = 0; |
| alecselfridge | 2:f3ae10decc2f | 80 | // green value of RGB |
| alecselfridge | 2:f3ae10decc2f | 81 | float g = 0; |
| alecselfridge | 2:f3ae10decc2f | 82 | // blue value of RGB |
| alecselfridge | 2:f3ae10decc2f | 83 | float b = 0; |
| alecselfridge | 0:4555c427d7a8 | 84 | |
| alecselfridge | 0:4555c427d7a8 | 85 | /* |
| alecselfridge | 0:4555c427d7a8 | 86 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 87 | Objects |
| alecselfridge | 0:4555c427d7a8 | 88 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 89 | */ |
| alecselfridge | 0:4555c427d7a8 | 90 | // UART connection to PC |
| alecselfridge | 0:4555c427d7a8 | 91 | Serial terminal(USBTX, USBRX); |
| alecselfridge | 0:4555c427d7a8 | 92 | // accelerometer on I2C bus |
| alecselfridge | 0:4555c427d7a8 | 93 | MMA7455 acc(P0_27, P0_28); |
| alecselfridge | 1:0a93e9e88ad3 | 94 | // SPI interface for 8 LEDs |
| alecselfridge | 1:0a93e9e88ad3 | 95 | SPI leds(p5, NC, p7); |
| alecselfridge | 1:0a93e9e88ad3 | 96 | // load for shift register |
| alecselfridge | 1:0a93e9e88ad3 | 97 | DigitalOut ld(p30); |
| alecselfridge | 2:f3ae10decc2f | 98 | // R of RGB LED |
| alecselfridge | 2:f3ae10decc2f | 99 | PwmOut R(p25); |
| alecselfridge | 2:f3ae10decc2f | 100 | // G of RGB LED |
| alecselfridge | 2:f3ae10decc2f | 101 | PwmOut G(p28); |
| alecselfridge | 2:f3ae10decc2f | 102 | // B of RGB LED |
| alecselfridge | 2:f3ae10decc2f | 103 | PwmOut B(p26); |
| alecselfridge | 2:f3ae10decc2f | 104 | // active-low 5-axis joystick |
| alecselfridge | 2:f3ae10decc2f | 105 | // center, left_hi, right_hi, left_lo, right_lo |
| alecselfridge | 2:f3ae10decc2f | 106 | BusIn joystick(p31, p32, p37, p39, p38); |
| alecselfridge | 0:4555c427d7a8 | 107 | |
| alecselfridge | 0:4555c427d7a8 | 108 | int main() { |
| alecselfridge | 0:4555c427d7a8 | 109 | /* |
| alecselfridge | 0:4555c427d7a8 | 110 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 111 | Initializations |
| alecselfridge | 0:4555c427d7a8 | 112 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 113 | */ |
| alecselfridge | 0:4555c427d7a8 | 114 | SerialInit(); |
| alecselfridge | 2:f3ae10decc2f | 115 | AccInit(); |
| alecselfridge | 1:0a93e9e88ad3 | 116 | LEDsInit(); |
| alecselfridge | 2:f3ae10decc2f | 117 | testLED(); |
| alecselfridge | 2:f3ae10decc2f | 118 | RgbInit(); |
| alecselfridge | 2:f3ae10decc2f | 119 | testRGB(); |
| alecselfridge | 1:0a93e9e88ad3 | 120 | |
| alecselfridge | 2:f3ae10decc2f | 121 | terminal.printf("Initializing timers.........."); |
| alecselfridge | 2:f3ae10decc2f | 122 | // timer responsible for updating the LEDs |
| alecselfridge | 2:f3ae10decc2f | 123 | RtosTimer refresh_timer(LEDPush, osTimerPeriodic, (void *)0); |
| alecselfridge | 2:f3ae10decc2f | 124 | // 16.7Hz timer (60ms or ~1/2 of 30fps) |
| alecselfridge | 1:0a93e9e88ad3 | 125 | refresh_timer.start(60); |
| alecselfridge | 2:f3ae10decc2f | 126 | RtosTimer update_timer(RGBpicker, osTimerPeriodic, (void *)0); |
| alecselfridge | 2:f3ae10decc2f | 127 | // 10Hz timer (100ms) |
| alecselfridge | 2:f3ae10decc2f | 128 | update_timer.start(100); |
| alecselfridge | 2:f3ae10decc2f | 129 | terminal.printf("done."); |
| alecselfridge | 1:0a93e9e88ad3 | 130 | |
| alecselfridge | 2:f3ae10decc2f | 131 | newline(); newline(); |
| alecselfridge | 2:f3ae10decc2f | 132 | terminal.printf("Initialization complete."); |
| alecselfridge | 2:f3ae10decc2f | 133 | newline(); |
| alecselfridge | 0:4555c427d7a8 | 134 | /* |
| alecselfridge | 0:4555c427d7a8 | 135 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 136 | Main Execution |
| alecselfridge | 0:4555c427d7a8 | 137 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 138 | */ |
| alecselfridge | 2:f3ae10decc2f | 139 | while(true) { |
| alecselfridge | 0:4555c427d7a8 | 140 | acc.read(accPos[0], accPos[1], accPos[2]); |
| alecselfridge | 2:f3ae10decc2f | 141 | acc_adj = getAngle(); |
| alecselfridge | 2:f3ae10decc2f | 142 | LEDvals = mapLEDS(acc_adj); |
| alecselfridge | 0:4555c427d7a8 | 143 | } |
| alecselfridge | 0:4555c427d7a8 | 144 | } |
| alecselfridge | 0:4555c427d7a8 | 145 | |
| alecselfridge | 0:4555c427d7a8 | 146 | /* |
| alecselfridge | 0:4555c427d7a8 | 147 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 148 | Function Definitions |
| alecselfridge | 0:4555c427d7a8 | 149 | ************************** |
| alecselfridge | 0:4555c427d7a8 | 150 | */ |
| alecselfridge | 0:4555c427d7a8 | 151 | void SerialInit() |
| alecselfridge | 0:4555c427d7a8 | 152 | { |
| alecselfridge | 2:f3ae10decc2f | 153 | // initialize connection to PC. default: 8N1 |
| alecselfridge | 0:4555c427d7a8 | 154 | terminal.baud(19200); |
| alecselfridge | 0:4555c427d7a8 | 155 | displayBanner(); |
| alecselfridge | 0:4555c427d7a8 | 156 | newline(); |
| alecselfridge | 0:4555c427d7a8 | 157 | } |
| alecselfridge | 0:4555c427d7a8 | 158 | |
| alecselfridge | 0:4555c427d7a8 | 159 | void AccInit() |
| alecselfridge | 0:4555c427d7a8 | 160 | { |
| alecselfridge | 0:4555c427d7a8 | 161 | // configure accelerometer for 2G range |
| alecselfridge | 0:4555c427d7a8 | 162 | acc.setMode(MMA7455::ModeMeasurement); |
| alecselfridge | 0:4555c427d7a8 | 163 | acc.setRange(MMA7455::Range_2g); |
| alecselfridge | 0:4555c427d7a8 | 164 | terminal.printf("Calibrating accelerometer..."); |
| alecselfridge | 0:4555c427d7a8 | 165 | |
| alecselfridge | 0:4555c427d7a8 | 166 | // if we can successfully calibrate the accelerometer... |
| alecselfridge | 0:4555c427d7a8 | 167 | if(acc.calibrate()) { |
| alecselfridge | 0:4555c427d7a8 | 168 | newline(); |
| alecselfridge | 0:4555c427d7a8 | 169 | acc.getCalibrationOffsets(accCal[0], accCal[1], accCal[2]); |
| alecselfridge | 2:f3ae10decc2f | 170 | terminal.printf(" Offsets are (x,y,z): (%d, %d, %d)", accCal[0], accCal[1], accCal[2]); |
| alecselfridge | 0:4555c427d7a8 | 171 | newline(); newline(); |
| alecselfridge | 0:4555c427d7a8 | 172 | } |
| alecselfridge | 0:4555c427d7a8 | 173 | else { |
| alecselfridge | 0:4555c427d7a8 | 174 | terminal.printf("failed."); |
| alecselfridge | 0:4555c427d7a8 | 175 | newline(); newline(); |
| alecselfridge | 0:4555c427d7a8 | 176 | } |
| alecselfridge | 0:4555c427d7a8 | 177 | } |
| alecselfridge | 0:4555c427d7a8 | 178 | |
| alecselfridge | 2:f3ae10decc2f | 179 | void LEDsInit() |
| alecselfridge | 2:f3ae10decc2f | 180 | { |
| alecselfridge | 2:f3ae10decc2f | 181 | terminal.printf("Initializing LED array......."); |
| alecselfridge | 2:f3ae10decc2f | 182 | leds.format(8, 3); // 8-bit packet, polarity & phase mode 3 |
| alecselfridge | 2:f3ae10decc2f | 183 | leds.frequency(100000); // 1MHz SPI |
| alecselfridge | 2:f3ae10decc2f | 184 | ld = 1; |
| alecselfridge | 2:f3ae10decc2f | 185 | LEDvals = 0x00; |
| alecselfridge | 2:f3ae10decc2f | 186 | terminal.printf("done."); |
| alecselfridge | 2:f3ae10decc2f | 187 | newline(); |
| alecselfridge | 2:f3ae10decc2f | 188 | } |
| alecselfridge | 2:f3ae10decc2f | 189 | |
| alecselfridge | 2:f3ae10decc2f | 190 | void RgbInit() |
| alecselfridge | 2:f3ae10decc2f | 191 | { |
| alecselfridge | 2:f3ae10decc2f | 192 | terminal.printf("Initializing RGB LED........."); |
| alecselfridge | 2:f3ae10decc2f | 193 | // 1KHz |
| alecselfridge | 2:f3ae10decc2f | 194 | R.period(.001); |
| alecselfridge | 2:f3ae10decc2f | 195 | R = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 196 | G.period(.001); |
| alecselfridge | 2:f3ae10decc2f | 197 | G = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 198 | B.period(.001); |
| alecselfridge | 2:f3ae10decc2f | 199 | B = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 200 | terminal.printf("done."); |
| alecselfridge | 2:f3ae10decc2f | 201 | newline(); |
| alecselfridge | 2:f3ae10decc2f | 202 | } |
| alecselfridge | 2:f3ae10decc2f | 203 | |
| alecselfridge | 0:4555c427d7a8 | 204 | void newline() |
| alecselfridge | 0:4555c427d7a8 | 205 | { |
| alecselfridge | 0:4555c427d7a8 | 206 | // newline = carriage return + line feed |
| alecselfridge | 0:4555c427d7a8 | 207 | terminal.putc('\n'); |
| alecselfridge | 0:4555c427d7a8 | 208 | terminal.putc('\r'); |
| alecselfridge | 0:4555c427d7a8 | 209 | } |
| alecselfridge | 0:4555c427d7a8 | 210 | |
| alecselfridge | 0:4555c427d7a8 | 211 | /* |
| alecselfridge | 0:4555c427d7a8 | 212 | Displays the following header: |
| alecselfridge | 0:4555c427d7a8 | 213 | ************************************************ |
| alecselfridge | 0:4555c427d7a8 | 214 | Serial Comm Established with LPC4088 |
| alecselfridge | 0:4555c427d7a8 | 215 | ************************************************ |
| alecselfridge | 0:4555c427d7a8 | 216 | */ |
| alecselfridge | 0:4555c427d7a8 | 217 | void displayBanner() |
| alecselfridge | 0:4555c427d7a8 | 218 | { |
| alecselfridge | 0:4555c427d7a8 | 219 | int i = 0; |
| alecselfridge | 0:4555c427d7a8 | 220 | for(int j = 0; j < 48; j++) |
| alecselfridge | 0:4555c427d7a8 | 221 | terminal.putc('*'); |
| alecselfridge | 0:4555c427d7a8 | 222 | newline(); |
| alecselfridge | 0:4555c427d7a8 | 223 | |
| alecselfridge | 0:4555c427d7a8 | 224 | while(i != 36) { |
| alecselfridge | 0:4555c427d7a8 | 225 | char c = banner[i]; |
| alecselfridge | 0:4555c427d7a8 | 226 | terminal.putc(c); |
| alecselfridge | 0:4555c427d7a8 | 227 | i++; |
| alecselfridge | 0:4555c427d7a8 | 228 | } |
| alecselfridge | 0:4555c427d7a8 | 229 | newline(); |
| alecselfridge | 0:4555c427d7a8 | 230 | |
| alecselfridge | 0:4555c427d7a8 | 231 | for(int j = 0; j < 48; j++) |
| alecselfridge | 0:4555c427d7a8 | 232 | terminal.putc('*'); |
| alecselfridge | 0:4555c427d7a8 | 233 | } |
| alecselfridge | 0:4555c427d7a8 | 234 | |
| alecselfridge | 0:4555c427d7a8 | 235 | // prints the current positional data from the accelerometer |
| alecselfridge | 0:4555c427d7a8 | 236 | void accFeed() |
| alecselfridge | 0:4555c427d7a8 | 237 | { |
| alecselfridge | 0:4555c427d7a8 | 238 | // returns false if the mode is set to standby or unable to convert |
| alecselfridge | 0:4555c427d7a8 | 239 | if(acc.read(accPos[0], accPos[1], accPos[2])) { |
| alecselfridge | 0:4555c427d7a8 | 240 | terminal.printf("x: %d y: %d z: %d", accPos[0], accPos[1], accPos[2]); |
| alecselfridge | 0:4555c427d7a8 | 241 | newline(); |
| alecselfridge | 0:4555c427d7a8 | 242 | } |
| alecselfridge | 0:4555c427d7a8 | 243 | else { |
| alecselfridge | 2:f3ae10decc2f | 244 | terminal.printf("Unable to access MMA7455."); |
| alecselfridge | 0:4555c427d7a8 | 245 | newline(); |
| alecselfridge | 0:4555c427d7a8 | 246 | } |
| alecselfridge | 0:4555c427d7a8 | 247 | } |
| alecselfridge | 0:4555c427d7a8 | 248 | |
| alecselfridge | 0:4555c427d7a8 | 249 | /* |
| alecselfridge | 0:4555c427d7a8 | 250 | Samples the accelerometer in 1/4s intervals for the length of "period" (max 5). |
| alecselfridge | 0:4555c427d7a8 | 251 | The results are placed in the 3D array. Additionally, the array passed in |
| alecselfridge | 0:4555c427d7a8 | 252 | will hold the last reading. |
| alecselfridge | 0:4555c427d7a8 | 253 | */ |
| alecselfridge | 0:4555c427d7a8 | 254 | void sampleAcc(int period, int32_t data[3]) |
| alecselfridge | 0:4555c427d7a8 | 255 | { |
| alecselfridge | 0:4555c427d7a8 | 256 | for(int i = 0; i < period*4; i++) { |
| alecselfridge | 0:4555c427d7a8 | 257 | //load temps |
| alecselfridge | 0:4555c427d7a8 | 258 | acc.read(data[0], data[1], data[2]); |
| alecselfridge | 0:4555c427d7a8 | 259 | accData[i][0][0] = data[0]; // x |
| alecselfridge | 0:4555c427d7a8 | 260 | accData[0][i][0] = data[1]; // y |
| alecselfridge | 0:4555c427d7a8 | 261 | accData[0][0][i] = data[2]; // z |
| alecselfridge | 0:4555c427d7a8 | 262 | wait(.25); |
| alecselfridge | 0:4555c427d7a8 | 263 | } |
| alecselfridge | 0:4555c427d7a8 | 264 | // if we didn't fill the whole array, we'll clear it to avoid confusion later |
| alecselfridge | 0:4555c427d7a8 | 265 | if(period < 5) { |
| alecselfridge | 0:4555c427d7a8 | 266 | for(int i = period*4; i < 20; i++) |
| alecselfridge | 0:4555c427d7a8 | 267 | accData[i][i][i] = 0; |
| alecselfridge | 0:4555c427d7a8 | 268 | } |
| alecselfridge | 1:0a93e9e88ad3 | 269 | } |
| alecselfridge | 1:0a93e9e88ad3 | 270 | |
| alecselfridge | 2:f3ae10decc2f | 271 | // called by the refresh timer every 60ms |
| alecselfridge | 2:f3ae10decc2f | 272 | void LEDPush(void const *args) |
| alecselfridge | 2:f3ae10decc2f | 273 | { |
| alecselfridge | 2:f3ae10decc2f | 274 | ld = 0; // active-low load |
| alecselfridge | 2:f3ae10decc2f | 275 | leds.write(LEDvals); |
| alecselfridge | 2:f3ae10decc2f | 276 | ld = 1; // "lock" lights |
| alecselfridge | 2:f3ae10decc2f | 277 | } |
| alecselfridge | 2:f3ae10decc2f | 278 | |
| alecselfridge | 2:f3ae10decc2f | 279 | void RGBPush(void) |
| alecselfridge | 2:f3ae10decc2f | 280 | { |
| alecselfridge | 2:f3ae10decc2f | 281 | R = r; |
| alecselfridge | 2:f3ae10decc2f | 282 | G = g; |
| alecselfridge | 2:f3ae10decc2f | 283 | B = b; |
| alecselfridge | 2:f3ae10decc2f | 284 | } |
| alecselfridge | 2:f3ae10decc2f | 285 | |
| alecselfridge | 2:f3ae10decc2f | 286 | /* |
| alecselfridge | 2:f3ae10decc2f | 287 | -0-90 degrees = 0-65 units (deg/unit ratio) |
| alecselfridge | 2:f3ae10decc2f | 288 | -90 - conversion = actual angle (a value of 65 means the device is flat) |
| alecselfridge | 2:f3ae10decc2f | 289 | thus, Theta = 90 - (90/65 * x) (90/65 = 1.38) |
| alecselfridge | 2:f3ae10decc2f | 290 | -Using ax^2 - by + c allows the data to fit into a custom model of about 1/3 scale |
| alecselfridge | 2:f3ae10decc2f | 291 | Therefore, the final equation is: Theta = 90 - 3(ax^2 - by + c) |
| alecselfridge | 2:f3ae10decc2f | 292 | */ |
| alecselfridge | 2:f3ae10decc2f | 293 | double getAngle(void) |
| alecselfridge | 2:f3ae10decc2f | 294 | { |
| alecselfridge | 2:f3ae10decc2f | 295 | double deg = 1.38 * accPos[2]; |
| alecselfridge | 2:f3ae10decc2f | 296 | double cal = 1.38 * accCal[2]; |
| alecselfridge | 2:f3ae10decc2f | 297 | return ( 90 - (3.0 * ((X2*deg*deg) - (X*cal) + C)) ); |
| alecselfridge | 2:f3ae10decc2f | 298 | } |
| alecselfridge | 2:f3ae10decc2f | 299 | |
| alecselfridge | 2:f3ae10decc2f | 300 | // look-up table based on ranges |
| alecselfridge | 2:f3ae10decc2f | 301 | // this setup gives a nonlinear response from 0-90 degrees |
| alecselfridge | 2:f3ae10decc2f | 302 | unsigned char mapLEDS(double v) |
| alecselfridge | 1:0a93e9e88ad3 | 303 | { |
| alecselfridge | 2:f3ae10decc2f | 304 | int angle = int(v); |
| alecselfridge | 2:f3ae10decc2f | 305 | if(accPos[0] < 0) { |
| alecselfridge | 2:f3ae10decc2f | 306 | if(angle < 8) |
| alecselfridge | 2:f3ae10decc2f | 307 | return 0xFF; |
| alecselfridge | 2:f3ae10decc2f | 308 | else if(angle >= 8 && angle < 15) |
| alecselfridge | 2:f3ae10decc2f | 309 | return 0x7F; |
| alecselfridge | 2:f3ae10decc2f | 310 | else if(angle >= 15 && angle < 25) |
| alecselfridge | 2:f3ae10decc2f | 311 | return 0x3F; |
| alecselfridge | 2:f3ae10decc2f | 312 | else if(angle >= 25 && angle < 35) |
| alecselfridge | 2:f3ae10decc2f | 313 | return 0x1F; |
| alecselfridge | 2:f3ae10decc2f | 314 | else if(angle >= 35 && angle < 40) |
| alecselfridge | 2:f3ae10decc2f | 315 | return 0x0F; |
| alecselfridge | 2:f3ae10decc2f | 316 | else if(angle >= 40 && angle < 50) |
| alecselfridge | 2:f3ae10decc2f | 317 | return 0x07; |
| alecselfridge | 2:f3ae10decc2f | 318 | else if(angle >= 50 && angle < 60) |
| alecselfridge | 2:f3ae10decc2f | 319 | return 0x03; |
| alecselfridge | 2:f3ae10decc2f | 320 | else if(angle >= 60 && angle < 70) |
| alecselfridge | 2:f3ae10decc2f | 321 | return 0x01; |
| alecselfridge | 2:f3ae10decc2f | 322 | else if(angle >= 70) |
| alecselfridge | 2:f3ae10decc2f | 323 | return 0x00; |
| alecselfridge | 2:f3ae10decc2f | 324 | else |
| alecselfridge | 2:f3ae10decc2f | 325 | return 0xFF; |
| alecselfridge | 2:f3ae10decc2f | 326 | } |
| alecselfridge | 2:f3ae10decc2f | 327 | else { |
| alecselfridge | 2:f3ae10decc2f | 328 | if(angle < 8) |
| alecselfridge | 2:f3ae10decc2f | 329 | return 0xFF; |
| alecselfridge | 2:f3ae10decc2f | 330 | else if(angle >= 8 && angle < 15) |
| alecselfridge | 2:f3ae10decc2f | 331 | return 0xFE; |
| alecselfridge | 2:f3ae10decc2f | 332 | else if(angle >= 15 && angle < 25) |
| alecselfridge | 2:f3ae10decc2f | 333 | return 0xFC; |
| alecselfridge | 2:f3ae10decc2f | 334 | else if(angle >= 25 && angle < 35) |
| alecselfridge | 2:f3ae10decc2f | 335 | return 0xF8; |
| alecselfridge | 2:f3ae10decc2f | 336 | else if(angle >= 35 && angle < 40) |
| alecselfridge | 2:f3ae10decc2f | 337 | return 0xF0; |
| alecselfridge | 2:f3ae10decc2f | 338 | else if(angle >= 40 && angle < 50) |
| alecselfridge | 2:f3ae10decc2f | 339 | return 0xE0; |
| alecselfridge | 2:f3ae10decc2f | 340 | else if(angle >= 50 && angle < 60) |
| alecselfridge | 2:f3ae10decc2f | 341 | return 0xC0; |
| alecselfridge | 2:f3ae10decc2f | 342 | else if(angle >= 60 && angle < 70) |
| alecselfridge | 2:f3ae10decc2f | 343 | return 0x80; |
| alecselfridge | 2:f3ae10decc2f | 344 | else if(angle >= 70) |
| alecselfridge | 2:f3ae10decc2f | 345 | return 0x00; |
| alecselfridge | 2:f3ae10decc2f | 346 | else |
| alecselfridge | 2:f3ae10decc2f | 347 | return 0xFF; |
| alecselfridge | 2:f3ae10decc2f | 348 | } |
| alecselfridge | 1:0a93e9e88ad3 | 349 | } |
| alecselfridge | 1:0a93e9e88ad3 | 350 | |
| alecselfridge | 2:f3ae10decc2f | 351 | /* |
| alecselfridge | 2:f3ae10decc2f | 352 | joystick: 0 1 2 3 4 |
| alecselfridge | 2:f3ae10decc2f | 353 | center left_hi right_hi left_lo right_lo |
| alecselfridge | 2:f3ae10decc2f | 354 | */ |
| alecselfridge | 2:f3ae10decc2f | 355 | void RGBpicker(void const *args) |
| alecselfridge | 1:0a93e9e88ad3 | 356 | { |
| alecselfridge | 2:f3ae10decc2f | 357 | tick++; |
| alecselfridge | 2:f3ae10decc2f | 358 | if(tick > 1) { |
| alecselfridge | 2:f3ae10decc2f | 359 | tick = 0; |
| alecselfridge | 2:f3ae10decc2f | 360 | return; |
| alecselfridge | 2:f3ae10decc2f | 361 | } |
| alecselfridge | 2:f3ae10decc2f | 362 | // left : R |
| alecselfridge | 3:25eba54bace2 | 363 | if(!(joystick[3])) { |
| alecselfridge | 2:f3ae10decc2f | 364 | if(R.read() == 0.0) |
| alecselfridge | 2:f3ae10decc2f | 365 | r = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 366 | r = r - .02; |
| alecselfridge | 2:f3ae10decc2f | 367 | } |
| alecselfridge | 2:f3ae10decc2f | 368 | // right : B |
| alecselfridge | 3:25eba54bace2 | 369 | if(!(joystick[2])) { |
| alecselfridge | 2:f3ae10decc2f | 370 | if(B.read() == 0.0) |
| alecselfridge | 2:f3ae10decc2f | 371 | b = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 372 | b = b - .02; |
| alecselfridge | 2:f3ae10decc2f | 373 | } |
| alecselfridge | 2:f3ae10decc2f | 374 | // up : G |
| alecselfridge | 3:25eba54bace2 | 375 | if(!(joystick[4])) { |
| alecselfridge | 2:f3ae10decc2f | 376 | if(G.read() == 0.0) |
| alecselfridge | 2:f3ae10decc2f | 377 | g = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 378 | g = g - .02; |
| alecselfridge | 2:f3ae10decc2f | 379 | } |
| alecselfridge | 3:25eba54bace2 | 380 | // down : Reset |
| alecselfridge | 3:25eba54bace2 | 381 | if(!(joystick[1])) { |
| alecselfridge | 3:25eba54bace2 | 382 | r = 1.0; g = 1.0; b = 1.0; |
| alecselfridge | 3:25eba54bace2 | 383 | } |
| alecselfridge | 2:f3ae10decc2f | 384 | // center : confirm changes |
| alecselfridge | 3:25eba54bace2 | 385 | if(!joystick[0]) { |
| alecselfridge | 2:f3ae10decc2f | 386 | RGBPush(); |
| alecselfridge | 3:25eba54bace2 | 387 | terminal.printf("RGB updated: (%3.2f, %3.2f, %3.2f)", ((1 - R.read())*100), ((1 - G.read())*100), ((1 - B.read())*100)); |
| alecselfridge | 2:f3ae10decc2f | 388 | newline(); |
| alecselfridge | 2:f3ae10decc2f | 389 | } |
| alecselfridge | 1:0a93e9e88ad3 | 390 | } |
| alecselfridge | 1:0a93e9e88ad3 | 391 | |
| alecselfridge | 2:f3ae10decc2f | 392 | // "chase" pattern to verify LED array |
| alecselfridge | 2:f3ae10decc2f | 393 | void testLED(void) |
| alecselfridge | 2:f3ae10decc2f | 394 | { |
| alecselfridge | 2:f3ae10decc2f | 395 | LEDvals = 0x80; |
| alecselfridge | 2:f3ae10decc2f | 396 | LEDPush(0); |
| alecselfridge | 2:f3ae10decc2f | 397 | wait_ms(75); |
| alecselfridge | 2:f3ae10decc2f | 398 | for(int i = 0; i < 8; i++) { |
| alecselfridge | 2:f3ae10decc2f | 399 | LEDvals = LEDvals >> 1;; |
| alecselfridge | 2:f3ae10decc2f | 400 | LEDPush(0); |
| alecselfridge | 2:f3ae10decc2f | 401 | wait_ms(75); |
| alecselfridge | 2:f3ae10decc2f | 402 | } |
| alecselfridge | 2:f3ae10decc2f | 403 | LEDvals = 0x01; |
| alecselfridge | 2:f3ae10decc2f | 404 | LEDPush(0); |
| alecselfridge | 2:f3ae10decc2f | 405 | wait_ms(75); |
| alecselfridge | 2:f3ae10decc2f | 406 | for(int i = 0; i < 8; i++) { |
| alecselfridge | 2:f3ae10decc2f | 407 | LEDvals = LEDvals << 1;; |
| alecselfridge | 2:f3ae10decc2f | 408 | LEDPush(0); |
| alecselfridge | 2:f3ae10decc2f | 409 | wait_ms(75); |
| alecselfridge | 2:f3ae10decc2f | 410 | } |
| alecselfridge | 2:f3ae10decc2f | 411 | } |
| alecselfridge | 2:f3ae10decc2f | 412 | |
| alecselfridge | 2:f3ae10decc2f | 413 | // cycles thru various colors to show functionality of an RGB LED |
| alecselfridge | 2:f3ae10decc2f | 414 | void testRGB(void) |
| alecselfridge | 1:0a93e9e88ad3 | 415 | { |
| alecselfridge | 2:f3ae10decc2f | 416 | r = 1.0; g = 1.0; b = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 417 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 418 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 419 | r = 0.0; g = 1.0; b = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 420 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 421 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 422 | r = .6; g = 0.0; b = 0.0; |
| alecselfridge | 2:f3ae10decc2f | 423 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 424 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 425 | r = 1.0; g = 1.0; b = 0.0; |
| alecselfridge | 2:f3ae10decc2f | 426 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 427 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 428 | r = 1.0; g = 0.0; b = 0.0; |
| alecselfridge | 2:f3ae10decc2f | 429 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 430 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 431 | r = 1.0; g = 0.0; b = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 432 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 433 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 434 | r = 1.0; g = 1.0; b = 0.0; |
| alecselfridge | 2:f3ae10decc2f | 435 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 436 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 437 | r = 0.0; g = 0.0; b = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 438 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 439 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 440 | r = 0.0; g = 1.0; b = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 441 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 442 | wait_ms(150); |
| alecselfridge | 2:f3ae10decc2f | 443 | r = 1.0; g = 1.0; b = 1.0; |
| alecselfridge | 2:f3ae10decc2f | 444 | RGBPush(); |
| alecselfridge | 2:f3ae10decc2f | 445 | wait_ms(150); |
| alecselfridge | 0:4555c427d7a8 | 446 | } |