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

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

Fork of OCE360_4 by OCE_360

main.cpp

Committer:
rsean10
Date:
2017-11-17
Revision:
13:1e7ad7812d5e
Parent:
12:1b20c6eceae8

File content as of revision 13:1e7ad7812d5e:

// A solution to OCE360 Homework #4.
// Objective: Use object oriented programming to create a system that displays
// multiple balls bouncing around the LCD screen.
// Stephen Licht, 11/7/2017

#include "mbed.h"
#include "MMA8452Q.h"           //acceleromater library
#include "uLCD_4DGL.h"          //LCD library
#include "bouncing_ball.h"      //new ball phyics library
#include "SDFileSystem.h"

#define UPDATE_TIME_S 0.02
#define START_X_1 10
#define START_Y_1 10
#define START_X_2 20
#define START_Y_2 20
#define RADIUS_1 6
#define RADIUS_2 3

#define DEBUG_MODE 0

#define LCD_UPDATE .091         //11 Hz

// Accelerometer - SDA, SCL, and I2C address
MMA8452Q accel(p28, p27, 0x1D);  //initialize a driver object for an accelerometer connected on pins 27-28.

// Analog input (pin 15)
AnalogIn tempin(p15);

//Initialize Serial communication
Serial pc(USBTX, USBRX);

// SD card (SPI pins)
SDFileSystem sd(p5, p6, p7, p8, "sd");

//Drawing positions
int lastx1;
int lasty1;
int lastx2; 
int lasty2;

//Led Initialization
DigitalOut led1(LED1); //update leds
DigitalOut led2(LED2);
DigitalOut led3(LED3);

//Toggle Initialization
InterruptIn button(p13);    //Interrupt on the button on pin 13
Timer debounce;             //defines debounce timer for proper switching
Timer logtimer;

int recorder = 0;
int state = 0;

void toggle(){
    if(debounce.read_ms()>175){
        led3= !led3;
        recorder = !recorder;
        debounce.reset(); //restart timer after toggle occurs
        logtimer.start();
        state = !state;
        }
    }

//Position recorder
Ticker logticker;

float voltage_in;
float degrees_c;

FILE *file;
void datarecord();

//Function prototype for color selection function:
int get_LCD_color(int color_integer);

// Graphic LCD - TX, RX, and RES pins
uLCD_4DGL uLCD(p9,p10,p11);     //initialize a driver object for an LCD connected on pins 9-11

physics_ball ball1;  //initialize two balls for bouncing
physics_ball ball2;  //the default states from the library will be used initially

//Ticker for update
Ticker update1; //ball 1 ticker for update position
Ticker update2; //ball 2 ticker for update position

void ball1up(){
    ball1.update(UPDATE_TIME_S,accel);  //updates position
    led1 = !led1;                       //changes led state every update
    }

void ball2up(){
    ball2.update(UPDATE_TIME_S,accel);  //updates position
    led2 = !led2;                       //changes led state every update
    }

//Ticker for display
Ticker displayup;   //ticker for displaying ball on lcd

void display(){
    
    // Erase old circles by writing over there locations using the screen color:
    uLCD.filled_circle(lastx1, lasty1, ball1.radius, BLACK);
    uLCD.filled_circle(lastx2, lasty2, ball2.radius, BLACK);
    
    // Draw circles in the x and y positions stored by the ball objects:
    uLCD.filled_circle(ball1.posx, ball1.posy, ball1.radius, get_LCD_color(ball1.color));
    uLCD.filled_circle(ball2.posx, ball2.posy, ball2.radius, get_LCD_color(ball2.color));
    
    //Sets previous ball position to be erased in next iteration
    lastx1 = ball1.posx;
    lasty1 = ball1.posy;
    lastx2 = ball2.posx;
    lasty2 = ball2.posy;
    }

int main(){
    
    file = fopen("/sd/ball_data.txt", "w");
        if ( file == NULL ) {
            error("ERROR: Could not open file for writing!\n\r");
            return -1;
        }
    
    fprintf(file, "        Time   X Position   Y Position   X Speed   Y Speed   X Acceleration   Y Acceleration   Temperature\n\r");
    
        
    // Initialize uLCD
    uLCD.baudrate(115200);
    uLCD.background_color(BLACK);
    uLCD.cls();
    
    // Initialize accelerometer
    accel.init();

    //Initialize balls:
    ball1.set_state(START_X_1,START_Y_1,0,0); //speeds are set to zero
    ball1.set_state(START_X_2,START_Y_2,0,0);

    //Set ball radius and color:
    ball1.set_param(RADIUS_1,0); //color is unimportant
    ball2.set_param(RADIUS_2,1); //just making sure the colors are different

    update1.attach(&ball1up,UPDATE_TIME_S); //ticker force position update ball 1
    update2.attach(&ball2up,UPDATE_TIME_S); //ticker force position update ball 2
    
    displayup.attach(&display,LCD_UPDATE);   //ticker force lcd update
    
    debounce.start();       //starts debounce timer
    button.rise(&toggle);   //toggles on button press
    
    logticker.attach(&datarecord,LCD_UPDATE);
    
    while (1) {  //execute 'forever'
        /*
        if (recorder == 1){
                //File Writing
                //FILE *file;
                file = fopen("/sd/ball_data.txt", "w");
                if ( file == NULL ) {
                    error("ERROR: Could not open file for writing!\n\r");
                    return -1;
                }
                // Tell the user we need to wait while we collect some data
                pc.printf("\nCollecting data (Do not remove SD Card!) ...\n\r");
                logtimer.start();
                fprintf(file, "       Time   X Position   Y Position   X Accleration   Y Acceleration   Temperature\n\r");
                //logticker.attach(&datarecord,LCD_UPDATE);
                pc.printf("\nData Recorded Sucessfully! \n\r");
                logtimer.reset();
                
                // Close file
                fclose(file);
                }
        */
        /*
        if (recorder == 0){
            fclose(file);
            }
        */
        if (DEBUG_MODE) {
            //If compiled with DEBUG_MODE flag raised, print values to screen.
            uLCD.locate(0,4);
            uLCD.printf("X: %d.1\nY: %.1d",ball1.posx,ball1.posy);
    
            uLCD.locate(0,6);
            uLCD.printf("VX: %f.1\nVY: %.1f",ball1.speedx,ball1.speedy);
    
            uLCD.locate(0,10);
            uLCD.printf("AX: %f.1\nAY: %.1f\nAZ: %0.1f",accel.readX(),accel.readY(),accel.readZ());
        }
    }
}

//Interpret LCD colors.
int get_LCD_color(int color_integer)
{
    switch (color_integer) {
        case 0:
            return(RED);
        case 1:
            return(BLUE);
        case 2:
            return(GREEN);
        default:
            return(WHITE);
    }
}

/*
void datarecord(){
    float time = 1*logtimer.read();
    float pos1x = 1*ball1.posx;
    float pos1y = 1*ball1.posy;
    float spe1x = 1*ball1.speedx;
    float spe1y = 1*ball1.speedy;
    float accx = 1*accel.readX();
    float accy = 1*accel.readY();
    
    float pos2x = 1*ball2.posx;
    float pos2y = 1*ball2.posy;
    float spe2x = 1*ball2.speedx;
    float spe2y = 1*ball2.speedy;
    
    voltage_in = tempin * 3.3;
    degrees_c = (voltage_in - 0.5) * 100.0;
    
    fprintf(file, "Ball 1: %.3g         %.3g             %.3g           %.3g          %.3g             %.3g               %.3g            %.3g\n\r",time,pos1x,pos1y,spe1x,spe1y,accx,accy,degrees_c);
    
    fprintf(file, "Ball 2:              %.3g             %.3g           %.3g          %.3g  \n\r",pos2x,pos2y,spe2x,spe2y);
    }
*/

void datarecord(){
    float time = 1*logtimer.read();
    float pos1x = 1*ball1.posx;
    float pos1y = 1*ball1.posy;
    float spe1x = 1*ball1.speedx;
    float spe1y = 1*ball1.speedy;
    float accx = 1*accel.readX();
    float accy = 1*accel.readY();
    
    float pos2x = 1*ball2.posx;
    float pos2y = 1*ball2.posy;
    float spe2x = 1*ball2.speedx;
    float spe2y = 1*ball2.speedy;
    
    voltage_in = tempin * 3.3;
    degrees_c = (voltage_in - 0.5) * 100.0;
    
    if(recorder == 1){
        // Tell the user we need to wait while we collect some data
        pc.printf("\nCollecting data (Do not remove SD Card!) ...\n\r");
        fprintf(file, "Ball 1: %.3g  %.3g          %.3g          %.3g   %.3g   %.3g   %.3g   %.3g\n\r",time,pos1x,pos1y,spe1x,spe1y,accx,accy,degrees_c);
        fprintf(file, "Ball 2:       %.3g          %.3g          %.3g   %.3g  \n\r",pos2x,pos2y,spe2x,spe2y);
        //logticker.attach(&datarecord,LCD_UPDATE);
        pc.printf("\nData Recorded Sucessfully! \n\r");
        }
    /*
    if (state == 0){
        fclose(file);
        state = 0;
        }
    */
    }