Assignment 5 for OCE360, timers, tickers, and interrupts.

Dependencies:   4DGL-uLCD-SE MMA8452Q SDFileSystem bouncing_ball mbed

Fork of OCE360_4 by OCE_360

Committer:
rsean10
Date:
Fri Nov 17 01:06:01 2017 +0000
Revision:
13:1e7ad7812d5e
Parent:
12:1b20c6eceae8
Final Version: Will record on hardware interrupt, however interrupt will not stop recording.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
slicht 2:552e6feb8709 1 // A solution to OCE360 Homework #4.
slicht 2:552e6feb8709 2 // Objective: Use object oriented programming to create a system that displays
slicht 2:552e6feb8709 3 // multiple balls bouncing around the LCD screen.
slicht 3:a7f02754bc99 4 // Stephen Licht, 11/7/2017
slicht 1:6b99ffa62cc8 5
slicht 0:8d3812068c6c 6 #include "mbed.h"
slicht 2:552e6feb8709 7 #include "MMA8452Q.h" //acceleromater library
slicht 2:552e6feb8709 8 #include "uLCD_4DGL.h" //LCD library
slicht 2:552e6feb8709 9 #include "bouncing_ball.h" //new ball phyics library
rsean10 8:2617100c441d 10 #include "SDFileSystem.h"
slicht 1:6b99ffa62cc8 11
slicht 2:552e6feb8709 12 #define UPDATE_TIME_S 0.02
slicht 2:552e6feb8709 13 #define START_X_1 10
slicht 2:552e6feb8709 14 #define START_Y_1 10
slicht 2:552e6feb8709 15 #define START_X_2 20
slicht 2:552e6feb8709 16 #define START_Y_2 20
slicht 2:552e6feb8709 17 #define RADIUS_1 6
slicht 2:552e6feb8709 18 #define RADIUS_2 3
slicht 0:8d3812068c6c 19
slicht 2:552e6feb8709 20 #define DEBUG_MODE 0
slicht 2:552e6feb8709 21
rsean10 6:050104c0dc75 22 #define LCD_UPDATE .091 //11 Hz
rsean10 9:7a577d790538 23
rsean10 10:1fe988d4e61e 24 // Accelerometer - SDA, SCL, and I2C address
rsean10 10:1fe988d4e61e 25 MMA8452Q accel(p28, p27, 0x1D); //initialize a driver object for an accelerometer connected on pins 27-28.
rsean10 10:1fe988d4e61e 26
rsean10 9:7a577d790538 27 // Analog input (pin 15)
rsean10 9:7a577d790538 28 AnalogIn tempin(p15);
rsean10 5:93f88deda5ba 29
rsean10 5:93f88deda5ba 30 //Initialize Serial communication
rsean10 5:93f88deda5ba 31 Serial pc(USBTX, USBRX);
rsean10 5:93f88deda5ba 32
rsean10 8:2617100c441d 33 // SD card (SPI pins)
rsean10 8:2617100c441d 34 SDFileSystem sd(p5, p6, p7, p8, "sd");
rsean10 8:2617100c441d 35
rsean10 9:7a577d790538 36 //Drawing positions
rsean10 9:7a577d790538 37 int lastx1;
rsean10 9:7a577d790538 38 int lasty1;
rsean10 9:7a577d790538 39 int lastx2;
rsean10 9:7a577d790538 40 int lasty2;
rsean10 9:7a577d790538 41
rsean10 6:050104c0dc75 42 //Led Initialization
rsean10 6:050104c0dc75 43 DigitalOut led1(LED1); //update leds
rsean10 6:050104c0dc75 44 DigitalOut led2(LED2);
rsean10 7:614b40b85579 45 DigitalOut led3(LED3);
rsean10 6:050104c0dc75 46
rsean10 7:614b40b85579 47 //Toggle Initialization
rsean10 7:614b40b85579 48 InterruptIn button(p13); //Interrupt on the button on pin 13
rsean10 7:614b40b85579 49 Timer debounce; //defines debounce timer for proper switching
rsean10 12:1b20c6eceae8 50 Timer logtimer;
rsean10 7:614b40b85579 51
rsean10 8:2617100c441d 52 int recorder = 0;
rsean10 12:1b20c6eceae8 53 int state = 0;
rsean10 8:2617100c441d 54
rsean10 7:614b40b85579 55 void toggle(){
rsean10 7:614b40b85579 56 if(debounce.read_ms()>175){
rsean10 9:7a577d790538 57 led3= !led3;
rsean10 8:2617100c441d 58 recorder = !recorder;
rsean10 7:614b40b85579 59 debounce.reset(); //restart timer after toggle occurs
rsean10 12:1b20c6eceae8 60 logtimer.start();
rsean10 12:1b20c6eceae8 61 state = !state;
rsean10 7:614b40b85579 62 }
rsean10 7:614b40b85579 63 }
rsean10 6:050104c0dc75 64
rsean10 8:2617100c441d 65 //Position recorder
rsean10 9:7a577d790538 66 Ticker logticker;
rsean10 8:2617100c441d 67
rsean10 10:1fe988d4e61e 68 float voltage_in;
rsean10 10:1fe988d4e61e 69 float degrees_c;
rsean10 10:1fe988d4e61e 70
rsean10 10:1fe988d4e61e 71 FILE *file;
rsean10 10:1fe988d4e61e 72 void datarecord();
rsean10 8:2617100c441d 73
slicht 2:552e6feb8709 74 //Function prototype for color selection function:
slicht 2:552e6feb8709 75 int get_LCD_color(int color_integer);
slicht 1:6b99ffa62cc8 76
slicht 1:6b99ffa62cc8 77 // Graphic LCD - TX, RX, and RES pins
slicht 2:552e6feb8709 78 uLCD_4DGL uLCD(p9,p10,p11); //initialize a driver object for an LCD connected on pins 9-11
slicht 1:6b99ffa62cc8 79
slicht 2:552e6feb8709 80 physics_ball ball1; //initialize two balls for bouncing
slicht 2:552e6feb8709 81 physics_ball ball2; //the default states from the library will be used initially
slicht 0:8d3812068c6c 82
rsean10 6:050104c0dc75 83 //Ticker for update
rsean10 6:050104c0dc75 84 Ticker update1; //ball 1 ticker for update position
rsean10 6:050104c0dc75 85 Ticker update2; //ball 2 ticker for update position
rsean10 6:050104c0dc75 86
rsean10 6:050104c0dc75 87 void ball1up(){
rsean10 6:050104c0dc75 88 ball1.update(UPDATE_TIME_S,accel); //updates position
rsean10 6:050104c0dc75 89 led1 = !led1; //changes led state every update
rsean10 6:050104c0dc75 90 }
rsean10 6:050104c0dc75 91
rsean10 6:050104c0dc75 92 void ball2up(){
rsean10 6:050104c0dc75 93 ball2.update(UPDATE_TIME_S,accel); //updates position
rsean10 6:050104c0dc75 94 led2 = !led2; //changes led state every update
rsean10 6:050104c0dc75 95 }
rsean10 6:050104c0dc75 96
rsean10 6:050104c0dc75 97 //Ticker for display
rsean10 6:050104c0dc75 98 Ticker displayup; //ticker for displaying ball on lcd
rsean10 6:050104c0dc75 99
rsean10 6:050104c0dc75 100 void display(){
rsean10 9:7a577d790538 101
rsean10 9:7a577d790538 102 // Erase old circles by writing over there locations using the screen color:
rsean10 9:7a577d790538 103 uLCD.filled_circle(lastx1, lasty1, ball1.radius, BLACK);
rsean10 9:7a577d790538 104 uLCD.filled_circle(lastx2, lasty2, ball2.radius, BLACK);
rsean10 9:7a577d790538 105
rsean10 6:050104c0dc75 106 // Draw circles in the x and y positions stored by the ball objects:
rsean10 6:050104c0dc75 107 uLCD.filled_circle(ball1.posx, ball1.posy, ball1.radius, get_LCD_color(ball1.color));
rsean10 6:050104c0dc75 108 uLCD.filled_circle(ball2.posx, ball2.posy, ball2.radius, get_LCD_color(ball2.color));
rsean10 9:7a577d790538 109
rsean10 9:7a577d790538 110 //Sets previous ball position to be erased in next iteration
rsean10 9:7a577d790538 111 lastx1 = ball1.posx;
rsean10 9:7a577d790538 112 lasty1 = ball1.posy;
rsean10 9:7a577d790538 113 lastx2 = ball2.posx;
rsean10 9:7a577d790538 114 lasty2 = ball2.posy;
rsean10 5:93f88deda5ba 115 }
rsean10 5:93f88deda5ba 116
rsean10 5:93f88deda5ba 117 int main(){
rsean10 12:1b20c6eceae8 118
rsean10 12:1b20c6eceae8 119 file = fopen("/sd/ball_data.txt", "w");
rsean10 12:1b20c6eceae8 120 if ( file == NULL ) {
rsean10 12:1b20c6eceae8 121 error("ERROR: Could not open file for writing!\n\r");
rsean10 12:1b20c6eceae8 122 return -1;
rsean10 12:1b20c6eceae8 123 }
rsean10 12:1b20c6eceae8 124
rsean10 12:1b20c6eceae8 125 fprintf(file, " Time X Position Y Position X Speed Y Speed X Acceleration Y Acceleration Temperature\n\r");
rsean10 12:1b20c6eceae8 126
rsean10 12:1b20c6eceae8 127
slicht 1:6b99ffa62cc8 128 // Initialize uLCD
slicht 1:6b99ffa62cc8 129 uLCD.baudrate(115200);
slicht 1:6b99ffa62cc8 130 uLCD.background_color(BLACK);
slicht 1:6b99ffa62cc8 131 uLCD.cls();
rsean10 8:2617100c441d 132
slicht 1:6b99ffa62cc8 133 // Initialize accelerometer
slicht 1:6b99ffa62cc8 134 accel.init();
slicht 1:6b99ffa62cc8 135
slicht 2:552e6feb8709 136 //Initialize balls:
slicht 2:552e6feb8709 137 ball1.set_state(START_X_1,START_Y_1,0,0); //speeds are set to zero
slicht 2:552e6feb8709 138 ball1.set_state(START_X_2,START_Y_2,0,0);
slicht 2:552e6feb8709 139
slicht 2:552e6feb8709 140 //Set ball radius and color:
slicht 2:552e6feb8709 141 ball1.set_param(RADIUS_1,0); //color is unimportant
slicht 2:552e6feb8709 142 ball2.set_param(RADIUS_2,1); //just making sure the colors are different
slicht 2:552e6feb8709 143
rsean10 6:050104c0dc75 144 update1.attach(&ball1up,UPDATE_TIME_S); //ticker force position update ball 1
rsean10 6:050104c0dc75 145 update2.attach(&ball2up,UPDATE_TIME_S); //ticker force position update ball 2
rsean10 6:050104c0dc75 146
rsean10 6:050104c0dc75 147 displayup.attach(&display,LCD_UPDATE); //ticker force lcd update
rsean10 6:050104c0dc75 148
rsean10 8:2617100c441d 149 debounce.start(); //starts debounce timer
rsean10 8:2617100c441d 150 button.rise(&toggle); //toggles on button press
rsean10 8:2617100c441d 151
rsean10 12:1b20c6eceae8 152 logticker.attach(&datarecord,LCD_UPDATE);
rsean10 12:1b20c6eceae8 153
rsean10 9:7a577d790538 154 while (1) { //execute 'forever'
rsean10 12:1b20c6eceae8 155 /*
rsean10 9:7a577d790538 156 if (recorder == 1){
rsean10 9:7a577d790538 157 //File Writing
rsean10 10:1fe988d4e61e 158 //FILE *file;
rsean10 9:7a577d790538 159 file = fopen("/sd/ball_data.txt", "w");
rsean10 9:7a577d790538 160 if ( file == NULL ) {
rsean10 9:7a577d790538 161 error("ERROR: Could not open file for writing!\n\r");
rsean10 9:7a577d790538 162 return -1;
rsean10 9:7a577d790538 163 }
rsean10 9:7a577d790538 164 // Tell the user we need to wait while we collect some data
rsean10 9:7a577d790538 165 pc.printf("\nCollecting data (Do not remove SD Card!) ...\n\r");
rsean10 11:abfb94de3a41 166 logtimer.start();
rsean10 9:7a577d790538 167 fprintf(file, " Time X Position Y Position X Accleration Y Acceleration Temperature\n\r");
rsean10 11:abfb94de3a41 168 //logticker.attach(&datarecord,LCD_UPDATE);
rsean10 9:7a577d790538 169 pc.printf("\nData Recorded Sucessfully! \n\r");
rsean10 11:abfb94de3a41 170 logtimer.reset();
rsean10 9:7a577d790538 171
rsean10 9:7a577d790538 172 // Close file
rsean10 9:7a577d790538 173 fclose(file);
rsean10 9:7a577d790538 174 }
rsean10 12:1b20c6eceae8 175 */
rsean10 12:1b20c6eceae8 176 /*
rsean10 12:1b20c6eceae8 177 if (recorder == 0){
rsean10 12:1b20c6eceae8 178 fclose(file);
rsean10 12:1b20c6eceae8 179 }
rsean10 12:1b20c6eceae8 180 */
slicht 2:552e6feb8709 181 if (DEBUG_MODE) {
slicht 3:a7f02754bc99 182 //If compiled with DEBUG_MODE flag raised, print values to screen.
slicht 2:552e6feb8709 183 uLCD.locate(0,4);
slicht 2:552e6feb8709 184 uLCD.printf("X: %d.1\nY: %.1d",ball1.posx,ball1.posy);
rsean10 9:7a577d790538 185
slicht 2:552e6feb8709 186 uLCD.locate(0,6);
slicht 2:552e6feb8709 187 uLCD.printf("VX: %f.1\nVY: %.1f",ball1.speedx,ball1.speedy);
rsean10 9:7a577d790538 188
slicht 2:552e6feb8709 189 uLCD.locate(0,10);
slicht 2:552e6feb8709 190 uLCD.printf("AX: %f.1\nAY: %.1f\nAZ: %0.1f",accel.readX(),accel.readY(),accel.readZ());
slicht 2:552e6feb8709 191 }
slicht 2:552e6feb8709 192 }
slicht 2:552e6feb8709 193 }
slicht 1:6b99ffa62cc8 194
slicht 3:a7f02754bc99 195 //Interpret LCD colors.
slicht 2:552e6feb8709 196 int get_LCD_color(int color_integer)
slicht 2:552e6feb8709 197 {
slicht 2:552e6feb8709 198 switch (color_integer) {
slicht 2:552e6feb8709 199 case 0:
slicht 2:552e6feb8709 200 return(RED);
slicht 2:552e6feb8709 201 case 1:
slicht 2:552e6feb8709 202 return(BLUE);
slicht 2:552e6feb8709 203 case 2:
slicht 2:552e6feb8709 204 return(GREEN);
slicht 2:552e6feb8709 205 default:
slicht 2:552e6feb8709 206 return(WHITE);
slicht 0:8d3812068c6c 207 }
rsean10 10:1fe988d4e61e 208 }
rsean10 10:1fe988d4e61e 209
rsean10 12:1b20c6eceae8 210 /*
rsean10 10:1fe988d4e61e 211 void datarecord(){
rsean10 10:1fe988d4e61e 212 float time = 1*logtimer.read();
rsean10 10:1fe988d4e61e 213 float pos1x = 1*ball1.posx;
rsean10 10:1fe988d4e61e 214 float pos1y = 1*ball1.posy;
rsean10 10:1fe988d4e61e 215 float spe1x = 1*ball1.speedx;
rsean10 10:1fe988d4e61e 216 float spe1y = 1*ball1.speedy;
rsean10 10:1fe988d4e61e 217 float accx = 1*accel.readX();
rsean10 10:1fe988d4e61e 218 float accy = 1*accel.readY();
rsean10 10:1fe988d4e61e 219
rsean10 10:1fe988d4e61e 220 float pos2x = 1*ball2.posx;
rsean10 10:1fe988d4e61e 221 float pos2y = 1*ball2.posy;
rsean10 10:1fe988d4e61e 222 float spe2x = 1*ball2.speedx;
rsean10 10:1fe988d4e61e 223 float spe2y = 1*ball2.speedy;
rsean10 10:1fe988d4e61e 224
rsean10 10:1fe988d4e61e 225 voltage_in = tempin * 3.3;
rsean10 10:1fe988d4e61e 226 degrees_c = (voltage_in - 0.5) * 100.0;
rsean10 10:1fe988d4e61e 227
rsean10 12:1b20c6eceae8 228 fprintf(file, "Ball 1: %.3g %.3g %.3g %.3g %.3g %.3g %.3g %.3g\n\r",time,pos1x,pos1y,spe1x,spe1y,accx,accy,degrees_c);
rsean10 12:1b20c6eceae8 229
rsean10 12:1b20c6eceae8 230 fprintf(file, "Ball 2: %.3g %.3g %.3g %.3g \n\r",pos2x,pos2y,spe2x,spe2y);
rsean10 12:1b20c6eceae8 231 }
rsean10 12:1b20c6eceae8 232 */
rsean10 12:1b20c6eceae8 233
rsean10 12:1b20c6eceae8 234 void datarecord(){
rsean10 12:1b20c6eceae8 235 float time = 1*logtimer.read();
rsean10 12:1b20c6eceae8 236 float pos1x = 1*ball1.posx;
rsean10 12:1b20c6eceae8 237 float pos1y = 1*ball1.posy;
rsean10 12:1b20c6eceae8 238 float spe1x = 1*ball1.speedx;
rsean10 12:1b20c6eceae8 239 float spe1y = 1*ball1.speedy;
rsean10 12:1b20c6eceae8 240 float accx = 1*accel.readX();
rsean10 12:1b20c6eceae8 241 float accy = 1*accel.readY();
rsean10 12:1b20c6eceae8 242
rsean10 12:1b20c6eceae8 243 float pos2x = 1*ball2.posx;
rsean10 12:1b20c6eceae8 244 float pos2y = 1*ball2.posy;
rsean10 12:1b20c6eceae8 245 float spe2x = 1*ball2.speedx;
rsean10 12:1b20c6eceae8 246 float spe2y = 1*ball2.speedy;
rsean10 10:1fe988d4e61e 247
rsean10 12:1b20c6eceae8 248 voltage_in = tempin * 3.3;
rsean10 12:1b20c6eceae8 249 degrees_c = (voltage_in - 0.5) * 100.0;
rsean10 12:1b20c6eceae8 250
rsean10 12:1b20c6eceae8 251 if(recorder == 1){
rsean10 12:1b20c6eceae8 252 // Tell the user we need to wait while we collect some data
rsean10 12:1b20c6eceae8 253 pc.printf("\nCollecting data (Do not remove SD Card!) ...\n\r");
rsean10 12:1b20c6eceae8 254 fprintf(file, "Ball 1: %.3g %.3g %.3g %.3g %.3g %.3g %.3g %.3g\n\r",time,pos1x,pos1y,spe1x,spe1y,accx,accy,degrees_c);
rsean10 12:1b20c6eceae8 255 fprintf(file, "Ball 2: %.3g %.3g %.3g %.3g \n\r",pos2x,pos2y,spe2x,spe2y);
rsean10 12:1b20c6eceae8 256 //logticker.attach(&datarecord,LCD_UPDATE);
rsean10 12:1b20c6eceae8 257 pc.printf("\nData Recorded Sucessfully! \n\r");
rsean10 12:1b20c6eceae8 258 }
rsean10 12:1b20c6eceae8 259 /*
rsean10 12:1b20c6eceae8 260 if (state == 0){
rsean10 12:1b20c6eceae8 261 fclose(file);
rsean10 12:1b20c6eceae8 262 state = 0;
rsean10 12:1b20c6eceae8 263 }
rsean10 12:1b20c6eceae8 264 */
rsean10 12:1b20c6eceae8 265 }
rsean10 12:1b20c6eceae8 266
rsean10 12:1b20c6eceae8 267