A system to help you ride your bike better than you do right now.

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed LSM9DS1_Library_cal

main.cpp

Committer:
kswanson31
Date:
2016-12-10
Revision:
11:f49250a7e4c3
Parent:
10:8593877172d4

File content as of revision 11:f49250a7e4c3:

#include "mbed.h"
#include "SDFileSystem.h"
#include "uLCD_4DGL.h"
#include "LSM9DS1.h"
#include <fstream>
#include <iomanip>
using namespace std;

#define START_S 1480719111

# define PI   3.14159

#define LEFT  0xA
#define RIGHT 0xB
#define STOP  0xC
#define GO    0xD

int lightState;

DigitalOut leftSignal(p22);
DigitalOut rightSignal(p23);
DigitalOut brakeLight(p21);
Timer blinkT;

AnalogIn flex(p20);
LSM9DS1 imu(p9, p10, 0xD6, 0x3C);

SDFileSystem sd(p11, p12, p13, p14, "sd");  //mosi -> DI, miso <- DO, slck -> sclck, CS -> CS
uLCD_4DGL lcd(p28, p27, p29);

// speed sensor
InterruptIn hallSensor(p8);
Timer hallT;
int stopped;

float miles = 0;
float speed = 0;
float maxSpeed = 0;
time_t seconds;

Serial pc(USBTX, USBRX);

void store_trip();
void recall_trips();
int get_state();
void pass();

int main() {    
    // open the file for reading and appending records
    // recall last trip
    lcd.cls();
    recall_trips();
    wait(1);
    lcd.cls();
    
    
    imu.begin();
    if (!imu.begin()) {
        lcd.printf("Failed to communicate with LSM9DS1.\n");
    }
    imu.calibrate();
    
    // normal operation loop here
    int going = 1; // cyclist is moving
    set_time(START_S);  // Set RTC time
    
    float theta = 0;
    
    hallSensor.fall(&pass);
    hallT.start();     // start the hall sensor timer
        
    leftSignal = 0;
    rightSignal = 0;
    brakeLight = 0;

    while(going) {
        
        seconds = time(NULL) - START_S; // return the seconds passed since start
        
        if (hallT.read() > 6.0 && !stopped) {
            speed = 0;
            stopped = 1;
        }

        going = (hallT.read() > 200.0 && stopped) ? 0 : 1;
        maxSpeed = (speed > maxSpeed) ? speed : maxSpeed;
        
        lcd.locate(0, 1);
        lcd.color(BLUE);
        lcd.printf("Distance : %3.1f mi\n\n", miles);
        lcd.color(GREEN);
        lcd.printf("Speed : %2.1f mph\n\n", speed);
        lcd.color(LGREY);
        lcd.printf("Time : %3.1f min\n\n", (float)seconds / 60);
        
        lcd.circle(64, 128, 64, GREEN);
        lcd.line(64, 128, 64 +  62*cos(theta), 128 - 62*sin(theta), BLACK);
        theta = PI - (speed / 9.536);
        lcd.line(64, 128, 64 +  62*cos(theta), 128 - 62*sin(theta), WHITE);
        
        
        // light states code
        lightState = get_state();
        pc.printf("STATE %d\n\r", lightState);
        
        if (lightState == STOP) {
            brakeLight = 1;
        } else if (lightState == GO) {
            brakeLight = 0;
            rightSignal = 0;
            leftSignal = 0;
        } else {
            if (lightState == RIGHT) {
                rightSignal = 1;
            } else {
                leftSignal = 1;
            }
        }
        wait(1);
    }
    
    // store this trip
    lcd.cls();
    store_trip();
    
    // end everything
}

void recall_trips(void) {
    // display the most recent trip made on the screen
    // display the most impressive trip (longest distance, best speed, least time)
    
    float f_miles;
    float f_maxSpeed;
    float f_minutes;
    ifstream file;
    
    // read out the most recent trip
    file.open("/sd/records/recent.txt");
    
    lcd.color(WHITE);
    
    if (!file.is_open()) {
        lcd.locate(0, 1);
        lcd.printf("Could not open file\n");
    } else {
        file >> f_miles >> f_maxSpeed >> f_minutes;
        lcd.locate(0, 1);
        lcd.printf("PRIOR TRIP\n\n");
        lcd.printf("Dist : %3.1f mi\n\n", f_miles);
        lcd.printf("High : %2.1f mph\n\n", f_maxSpeed);
        lcd.printf("Time : %3.1f min\n\n", f_minutes);
    }
    
    file.close();
    wait(0.5);
    
    // display the best trip
    
    file.open("/sd/records/best-of.txt");

    if(!file.is_open()) {
        lcd.printf("Could not open file\n");
    } else {
        // show the best trip
        file >> f_miles >> f_maxSpeed >> f_minutes;
        lcd.printf("BEST TRIP\n\n");
        lcd.printf("Dist : %3.1f mi\n\n", f_miles);
        lcd.printf("High : %2.1f mph\n\n", f_maxSpeed);
        lcd.printf("Time : %3.1f min\n\n", f_minutes);
    }

    file.close();
    wait(0.5);
}

void store_trip(void) {
    // store the most recent trip completed
    // determine whether this trip was a record, and indicate if so
    
    float minutes;
    float f_miles;
    float f_maxSpeed;
    float f_minutes;
    fstream file;
    
    file.open("/sd/records/recent.txt");
    
    lcd.color(WHITE);
    
    if (!file.is_open()) {
        lcd.locate(0, 1);
        lcd.printf("Could not open file\n");
    } else {
        minutes = (float)seconds / 60;
        lcd.locate(0, 1);
        lcd.printf("This trip\n\n");
        lcd.printf("Distance : %3.1f mi\n\n", miles);
        lcd.printf("Top speed : %2.1f mph\n\n", maxSpeed);
        lcd.printf("Time : %3.1f min\n\n", minutes);
        // overwrite most recent
        file << fixed << setprecision(1) << miles << " " << maxSpeed << " " << minutes << endl;
    }
    
    file.close();
    wait(0.5);
    
    file.open("/sd/records/best-of.txt");
    
    if (!file.is_open()) {
        lcd.locate(0, 1);
        lcd.printf("Could not open file\n");
    } else {
        // retrieve the previous record
        file >> f_miles >> f_maxSpeed >> f_minutes;
        // check if you beat your best
        if (miles >= f_miles && maxSpeed >= f_maxSpeed && minutes >= f_minutes) {
            lcd.printf("A new record!");
            file << fixed << setprecision(1) << miles << " " << maxSpeed << " " << minutes << endl;
        }
    }
    
    file.close();
    wait(0.5);
}

int get_state(void) {
    imu.readAccel();
    float f = flex.read();
    int x = imu.ax, y = imu.ay, z = imu.az;
    pc.printf("x: %d, y: %d, z: %d, flex: %f\n\r", x,y,z,f);
    if (z > 0 && z > abs(y) && z > abs(x) && y < 0 && f >= 0.87)
        return STOP;
//    if (x < 0 && abs(x) > abs(z) && abs(x) > abs(y) && f <= 0.87)
    if (x < 0 && abs(x) > abs(z) && abs(x) > abs(y))
        return LEFT;
    if (y > 0 && y > abs(z) && y > abs(x) && f >= 0.87)
        return RIGHT;
    return GO;
}

void pass(void) {
    // interrupt, performed when the hallsensor passes the magnet
    stopped = 0; // reset the global
    hallT.stop();
    speed = 0.00136364 / (hallT.read() / 3600); // current speed
    miles += 0.00136364; // circumference of the tire in miles
    hallT.reset();
    hallT.start();
}