Dependencies: 4DGL-uLCD-SE MMA8452Q_1 SDFileSystem bouncing_ball mbed
main.cpp@0:cd0b1641b303, 2017-12-07 (annotated)
- Committer:
- rsean10
- Date:
- Thu Dec 07 15:31:17 2017 +0000
- Revision:
- 0:cd0b1641b303
Full Working Version of OCE360 HW6
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rsean10 | 0:cd0b1641b303 | 1 | /* |
rsean10 | 0:cd0b1641b303 | 2 | R. Sean Nagle |
rsean10 | 0:cd0b1641b303 | 3 | 0CE306 HW6 |
rsean10 | 0:cd0b1641b303 | 4 | */ |
rsean10 | 0:cd0b1641b303 | 5 | |
rsean10 | 0:cd0b1641b303 | 6 | #include "mbed.h" |
rsean10 | 0:cd0b1641b303 | 7 | #include "MMA8452Q.h" //acceleromater library |
rsean10 | 0:cd0b1641b303 | 8 | #include "uLCD_4DGL.h" //LCD library |
rsean10 | 0:cd0b1641b303 | 9 | #include "bouncing_ball.h" //new ball phyics library |
rsean10 | 0:cd0b1641b303 | 10 | #include "SDFileSystem.h" |
rsean10 | 0:cd0b1641b303 | 11 | |
rsean10 | 0:cd0b1641b303 | 12 | #define UPDATE_TIME_S 0.02 |
rsean10 | 0:cd0b1641b303 | 13 | #define START_X_1 10 |
rsean10 | 0:cd0b1641b303 | 14 | #define START_Y_1 10 |
rsean10 | 0:cd0b1641b303 | 15 | #define START_X_2 20 |
rsean10 | 0:cd0b1641b303 | 16 | #define START_Y_2 20 |
rsean10 | 0:cd0b1641b303 | 17 | #define RADIUS_1 6 |
rsean10 | 0:cd0b1641b303 | 18 | #define RADIUS_2 3 |
rsean10 | 0:cd0b1641b303 | 19 | |
rsean10 | 0:cd0b1641b303 | 20 | #define DEBUG_MODE 0 |
rsean10 | 0:cd0b1641b303 | 21 | |
rsean10 | 0:cd0b1641b303 | 22 | #define LCD_UPDATE .091 //11 Hz |
rsean10 | 0:cd0b1641b303 | 23 | |
rsean10 | 0:cd0b1641b303 | 24 | // Accelerometer - SDA, SCL, and I2C address |
rsean10 | 0:cd0b1641b303 | 25 | MMA8452Q accel(p28, p27, 0x1D); //initialize a driver object for an accelerometer connected on pins 27-28. |
rsean10 | 0:cd0b1641b303 | 26 | |
rsean10 | 0:cd0b1641b303 | 27 | // Analog input (pin 15) |
rsean10 | 0:cd0b1641b303 | 28 | AnalogIn tempin(p15); |
rsean10 | 0:cd0b1641b303 | 29 | |
rsean10 | 0:cd0b1641b303 | 30 | //Initialize Serial communication |
rsean10 | 0:cd0b1641b303 | 31 | Serial pc(USBTX, USBRX); |
rsean10 | 0:cd0b1641b303 | 32 | |
rsean10 | 0:cd0b1641b303 | 33 | // SD card (SPI pins) |
rsean10 | 0:cd0b1641b303 | 34 | SDFileSystem sd(p5, p6, p7, p8, "sd"); |
rsean10 | 0:cd0b1641b303 | 35 | |
rsean10 | 0:cd0b1641b303 | 36 | //Drawing positions |
rsean10 | 0:cd0b1641b303 | 37 | int lastx1; |
rsean10 | 0:cd0b1641b303 | 38 | int lasty1; |
rsean10 | 0:cd0b1641b303 | 39 | int lastx2; |
rsean10 | 0:cd0b1641b303 | 40 | int lasty2; |
rsean10 | 0:cd0b1641b303 | 41 | |
rsean10 | 0:cd0b1641b303 | 42 | //Led Initialization |
rsean10 | 0:cd0b1641b303 | 43 | DigitalOut led1(LED1); //update leds |
rsean10 | 0:cd0b1641b303 | 44 | DigitalOut led2(LED2); |
rsean10 | 0:cd0b1641b303 | 45 | DigitalOut led3(LED3); |
rsean10 | 0:cd0b1641b303 | 46 | |
rsean10 | 0:cd0b1641b303 | 47 | //Function prototype for color selection function: |
rsean10 | 0:cd0b1641b303 | 48 | int get_LCD_color(int color_integer); |
rsean10 | 0:cd0b1641b303 | 49 | |
rsean10 | 0:cd0b1641b303 | 50 | // Graphic LCD - TX, RX, and RES pins |
rsean10 | 0:cd0b1641b303 | 51 | uLCD_4DGL uLCD(p9,p10,p11); //initialize a driver object for an LCD connected on pins 9-11 |
rsean10 | 0:cd0b1641b303 | 52 | |
rsean10 | 0:cd0b1641b303 | 53 | physics_ball ball1; //initialize two balls for bouncing |
rsean10 | 0:cd0b1641b303 | 54 | physics_ball ball2; //the default states from the library will be used initially |
rsean10 | 0:cd0b1641b303 | 55 | |
rsean10 | 0:cd0b1641b303 | 56 | //Ticker for update |
rsean10 | 0:cd0b1641b303 | 57 | Ticker update1; //ball 1 ticker for update position |
rsean10 | 0:cd0b1641b303 | 58 | Ticker update2; //ball 2 ticker for update position |
rsean10 | 0:cd0b1641b303 | 59 | |
rsean10 | 0:cd0b1641b303 | 60 | //Toggle Initialization |
rsean10 | 0:cd0b1641b303 | 61 | InterruptIn button(p18); //Interrupt on the button on pin 13 |
rsean10 | 0:cd0b1641b303 | 62 | Timer debounce; //defines debounce timer for proper switching |
rsean10 | 0:cd0b1641b303 | 63 | Timer logtimer; |
rsean10 | 0:cd0b1641b303 | 64 | int updtog = 0; |
rsean10 | 0:cd0b1641b303 | 65 | |
rsean10 | 0:cd0b1641b303 | 66 | void toggle(){ |
rsean10 | 0:cd0b1641b303 | 67 | if(debounce.read_ms()>175){ |
rsean10 | 0:cd0b1641b303 | 68 | led3= !led3; |
rsean10 | 0:cd0b1641b303 | 69 | debounce.reset(); //restart timer after toggle occurs |
rsean10 | 0:cd0b1641b303 | 70 | logtimer.start(); |
rsean10 | 0:cd0b1641b303 | 71 | if(logtimer.read()<2){ |
rsean10 | 0:cd0b1641b303 | 72 | updtog = 1; |
rsean10 | 0:cd0b1641b303 | 73 | } |
rsean10 | 0:cd0b1641b303 | 74 | } |
rsean10 | 0:cd0b1641b303 | 75 | } |
rsean10 | 0:cd0b1641b303 | 76 | /* |
rsean10 | 0:cd0b1641b303 | 77 | int v1x; |
rsean10 | 0:cd0b1641b303 | 78 | int v1y; |
rsean10 | 0:cd0b1641b303 | 79 | int v2x; |
rsean10 | 0:cd0b1641b303 | 80 | int v2y; |
rsean10 | 0:cd0b1641b303 | 81 | */ |
rsean10 | 0:cd0b1641b303 | 82 | |
rsean10 | 0:cd0b1641b303 | 83 | void ball1up(){ |
rsean10 | 0:cd0b1641b303 | 84 | if (updtog == 0){ |
rsean10 | 0:cd0b1641b303 | 85 | ball1.update(UPDATE_TIME_S,accel); //updates position |
rsean10 | 0:cd0b1641b303 | 86 | /* |
rsean10 | 0:cd0b1641b303 | 87 | v1x = (int)ball1.speedx; |
rsean10 | 0:cd0b1641b303 | 88 | v1y = (int)ball1.speedy; |
rsean10 | 0:cd0b1641b303 | 89 | */ |
rsean10 | 0:cd0b1641b303 | 90 | } |
rsean10 | 0:cd0b1641b303 | 91 | else { |
rsean10 | 0:cd0b1641b303 | 92 | ball1.set_state(ball1.posx,ball1.posy,0,0); //speeds are set to zero |
rsean10 | 0:cd0b1641b303 | 93 | //pc.printf("%i %i\r\n",v1x,v1y); |
rsean10 | 0:cd0b1641b303 | 94 | if(logtimer.read()>2){ |
rsean10 | 0:cd0b1641b303 | 95 | //ball1.set_state(ball1.posx,ball1.posy,v1x,v1y); |
rsean10 | 0:cd0b1641b303 | 96 | logtimer.stop(); |
rsean10 | 0:cd0b1641b303 | 97 | logtimer.reset(); |
rsean10 | 0:cd0b1641b303 | 98 | updtog = 0; |
rsean10 | 0:cd0b1641b303 | 99 | } |
rsean10 | 0:cd0b1641b303 | 100 | } |
rsean10 | 0:cd0b1641b303 | 101 | led1 = !led1; //changes led state every update |
rsean10 | 0:cd0b1641b303 | 102 | } |
rsean10 | 0:cd0b1641b303 | 103 | |
rsean10 | 0:cd0b1641b303 | 104 | void ball2up(){ |
rsean10 | 0:cd0b1641b303 | 105 | if (updtog == 0){ |
rsean10 | 0:cd0b1641b303 | 106 | ball2.update(UPDATE_TIME_S,accel); //updates position |
rsean10 | 0:cd0b1641b303 | 107 | /* |
rsean10 | 0:cd0b1641b303 | 108 | v2x = (int)ball2.speedx; |
rsean10 | 0:cd0b1641b303 | 109 | v2y = (int)ball2.speedy; |
rsean10 | 0:cd0b1641b303 | 110 | */ |
rsean10 | 0:cd0b1641b303 | 111 | } |
rsean10 | 0:cd0b1641b303 | 112 | else { |
rsean10 | 0:cd0b1641b303 | 113 | ball2.set_state(ball2.posx,ball2.posy,0,0); //speeds are set to zero |
rsean10 | 0:cd0b1641b303 | 114 | //pc.printf("%i %i\r\n",v2x,v2y); |
rsean10 | 0:cd0b1641b303 | 115 | if(logtimer.read()>2){ |
rsean10 | 0:cd0b1641b303 | 116 | //ball2.set_state(ball2.posx,ball2.posy,v2x,v2y); |
rsean10 | 0:cd0b1641b303 | 117 | logtimer.stop(); |
rsean10 | 0:cd0b1641b303 | 118 | logtimer.reset(); |
rsean10 | 0:cd0b1641b303 | 119 | updtog = 0; |
rsean10 | 0:cd0b1641b303 | 120 | } |
rsean10 | 0:cd0b1641b303 | 121 | } |
rsean10 | 0:cd0b1641b303 | 122 | led2 = !led2; //changes led state every update |
rsean10 | 0:cd0b1641b303 | 123 | } |
rsean10 | 0:cd0b1641b303 | 124 | |
rsean10 | 0:cd0b1641b303 | 125 | //Freefall Interrupt |
rsean10 | 0:cd0b1641b303 | 126 | InterruptIn FREEFALL(p17); |
rsean10 | 0:cd0b1641b303 | 127 | DigitalIn tompetty(p17); |
rsean10 | 0:cd0b1641b303 | 128 | |
rsean10 | 0:cd0b1641b303 | 129 | //Ticker for display |
rsean10 | 0:cd0b1641b303 | 130 | Ticker displayup; //ticker for displaying ball on lcd |
rsean10 | 0:cd0b1641b303 | 131 | |
rsean10 | 0:cd0b1641b303 | 132 | void display(){ |
rsean10 | 0:cd0b1641b303 | 133 | |
rsean10 | 0:cd0b1641b303 | 134 | // Erase old circles by writing over there locations using the screen color: |
rsean10 | 0:cd0b1641b303 | 135 | uLCD.filled_circle(lastx1, lasty1, ball1.radius, BLACK); |
rsean10 | 0:cd0b1641b303 | 136 | uLCD.filled_circle(lastx2, lasty2, ball2.radius, BLACK); |
rsean10 | 0:cd0b1641b303 | 137 | |
rsean10 | 0:cd0b1641b303 | 138 | // Draw circles in the x and y positions stored by the ball objects: |
rsean10 | 0:cd0b1641b303 | 139 | uLCD.filled_circle(ball1.posx, ball1.posy, ball1.radius, get_LCD_color(ball1.color)); |
rsean10 | 0:cd0b1641b303 | 140 | uLCD.filled_circle(ball2.posx, ball2.posy, ball2.radius, get_LCD_color(ball2.color)); |
rsean10 | 0:cd0b1641b303 | 141 | |
rsean10 | 0:cd0b1641b303 | 142 | //Sets previous ball position to be erased in next iteration |
rsean10 | 0:cd0b1641b303 | 143 | lastx1 = ball1.posx; |
rsean10 | 0:cd0b1641b303 | 144 | lasty1 = ball1.posy; |
rsean10 | 0:cd0b1641b303 | 145 | lastx2 = ball2.posx; |
rsean10 | 0:cd0b1641b303 | 146 | lasty2 = ball2.posy; |
rsean10 | 0:cd0b1641b303 | 147 | } |
rsean10 | 0:cd0b1641b303 | 148 | |
rsean10 | 0:cd0b1641b303 | 149 | int main(){ |
rsean10 | 0:cd0b1641b303 | 150 | |
rsean10 | 0:cd0b1641b303 | 151 | // Initialize uLCD |
rsean10 | 0:cd0b1641b303 | 152 | uLCD.baudrate(115200); |
rsean10 | 0:cd0b1641b303 | 153 | uLCD.background_color(BLACK); |
rsean10 | 0:cd0b1641b303 | 154 | uLCD.cls(); |
rsean10 | 0:cd0b1641b303 | 155 | |
rsean10 | 0:cd0b1641b303 | 156 | // Initialize accelerometer |
rsean10 | 0:cd0b1641b303 | 157 | accel.init(); |
rsean10 | 0:cd0b1641b303 | 158 | // Initialize freefall |
rsean10 | 0:cd0b1641b303 | 159 | accel.freefall(0x04,0x03); //0x04 for pin 1, 0x00 for pin 2, threshold = (threshold)/0.063 = counts to set register to |
rsean10 | 0:cd0b1641b303 | 160 | // example, thresh <0.2g, |
rsean10 | 0:cd0b1641b303 | 161 | |
rsean10 | 0:cd0b1641b303 | 162 | //Initialize balls: |
rsean10 | 0:cd0b1641b303 | 163 | ball1.set_state(START_X_1,START_Y_1,0,0); //speeds are set to zero |
rsean10 | 0:cd0b1641b303 | 164 | ball1.set_state(START_X_2,START_Y_2,0,0); |
rsean10 | 0:cd0b1641b303 | 165 | |
rsean10 | 0:cd0b1641b303 | 166 | //Set ball radius and color: |
rsean10 | 0:cd0b1641b303 | 167 | ball1.set_param(RADIUS_1,0); //color is unimportant |
rsean10 | 0:cd0b1641b303 | 168 | ball2.set_param(RADIUS_2,1); //just making sure the colors are different |
rsean10 | 0:cd0b1641b303 | 169 | |
rsean10 | 0:cd0b1641b303 | 170 | update1.attach(&ball1up,UPDATE_TIME_S); //ticker force position update ball 1 |
rsean10 | 0:cd0b1641b303 | 171 | update2.attach(&ball2up,UPDATE_TIME_S); //ticker force position update ball 2 |
rsean10 | 0:cd0b1641b303 | 172 | |
rsean10 | 0:cd0b1641b303 | 173 | displayup.attach(&display,LCD_UPDATE); //ticker force lcd update |
rsean10 | 0:cd0b1641b303 | 174 | |
rsean10 | 0:cd0b1641b303 | 175 | debounce.start(); //starts debounce timer |
rsean10 | 0:cd0b1641b303 | 176 | button.rise(&toggle); //toggles on button press |
rsean10 | 0:cd0b1641b303 | 177 | //FREEFALL.rise(&toggle); //interrupts on free fall |
rsean10 | 0:cd0b1641b303 | 178 | FREEFALL.fall(&toggle); //interrupts on free fall |
rsean10 | 0:cd0b1641b303 | 179 | |
rsean10 | 0:cd0b1641b303 | 180 | while (1) { //execute 'forever' |
rsean10 | 0:cd0b1641b303 | 181 | |
rsean10 | 0:cd0b1641b303 | 182 | uint8_t sixteen = accel.readRegister(0x16); |
rsean10 | 0:cd0b1641b303 | 183 | sixteen &= 0x80; |
rsean10 | 0:cd0b1641b303 | 184 | //pc.printf("%u\n\r",sixteen); |
rsean10 | 0:cd0b1641b303 | 185 | |
rsean10 | 0:cd0b1641b303 | 186 | |
rsean10 | 0:cd0b1641b303 | 187 | if (tompetty == 0){ |
rsean10 | 0:cd0b1641b303 | 188 | pc.printf("LOW %u\n\r",sixteen); |
rsean10 | 0:cd0b1641b303 | 189 | } |
rsean10 | 0:cd0b1641b303 | 190 | else { |
rsean10 | 0:cd0b1641b303 | 191 | pc.printf("HIGH %u\n\r",sixteen); |
rsean10 | 0:cd0b1641b303 | 192 | } |
rsean10 | 0:cd0b1641b303 | 193 | |
rsean10 | 0:cd0b1641b303 | 194 | |
rsean10 | 0:cd0b1641b303 | 195 | if (DEBUG_MODE) { |
rsean10 | 0:cd0b1641b303 | 196 | //If compiled with DEBUG_MODE flag raised, print values to screen. |
rsean10 | 0:cd0b1641b303 | 197 | uLCD.locate(0,4); |
rsean10 | 0:cd0b1641b303 | 198 | uLCD.printf("X: %d.1\nY: %.1d",ball1.posx,ball1.posy); |
rsean10 | 0:cd0b1641b303 | 199 | |
rsean10 | 0:cd0b1641b303 | 200 | uLCD.locate(0,6); |
rsean10 | 0:cd0b1641b303 | 201 | uLCD.printf("VX: %f.1\nVY: %.1f",ball1.speedx,ball1.speedy); |
rsean10 | 0:cd0b1641b303 | 202 | |
rsean10 | 0:cd0b1641b303 | 203 | uLCD.locate(0,10); |
rsean10 | 0:cd0b1641b303 | 204 | uLCD.printf("AX: %f.1\nAY: %.1f\nAZ: %0.1f",accel.readX(),accel.readY(),accel.readZ()); |
rsean10 | 0:cd0b1641b303 | 205 | } |
rsean10 | 0:cd0b1641b303 | 206 | } |
rsean10 | 0:cd0b1641b303 | 207 | } |
rsean10 | 0:cd0b1641b303 | 208 | |
rsean10 | 0:cd0b1641b303 | 209 | //Interpret LCD colors. |
rsean10 | 0:cd0b1641b303 | 210 | int get_LCD_color(int color_integer) |
rsean10 | 0:cd0b1641b303 | 211 | { |
rsean10 | 0:cd0b1641b303 | 212 | switch (color_integer) { |
rsean10 | 0:cd0b1641b303 | 213 | case 0: |
rsean10 | 0:cd0b1641b303 | 214 | return(RED); |
rsean10 | 0:cd0b1641b303 | 215 | case 1: |
rsean10 | 0:cd0b1641b303 | 216 | return(BLUE); |
rsean10 | 0:cd0b1641b303 | 217 | case 2: |
rsean10 | 0:cd0b1641b303 | 218 | return(GREEN); |
rsean10 | 0:cd0b1641b303 | 219 | default: |
rsean10 | 0:cd0b1641b303 | 220 | return(WHITE); |
rsean10 | 0:cd0b1641b303 | 221 | } |
rsean10 | 0:cd0b1641b303 | 222 | } |