Basic funcitonality

Dependencies:   mbed mbed-rtos SevenSegmentSerial HC_SR04_Ultrasonic_Library

main.cpp

Committer:
glanier9
Date:
2021-04-30
Revision:
9:1d973bd9786c
Parent:
7:04c8f6b7a42a
Child:
10:a3796a403d28

File content as of revision 9:1d973bd9786c:

//******************************************************
// Mbed to Raspberry Pi     ** Raspberry Pi to Mbed    *
//******************************************************
// 0 - pass starting line   ** S - start race          *
// 1 - pass checkpoint 1    ** R - reset               *
// 2 - pass checkpoint 2    **                         *
// ...                      **                         *
// 9 - end race             **                         *
//******************************************************

#include "mbed.h"
#include "ultrasonic.h"
#include "rtos.h"
#include "SevenSegmentSerial.h"

Thread      thread1;
Thread      thread2;
Serial      pc(USBTX,USBRX);
DigitalOut  led0(p5);
DigitalOut  led1(p6);
DigitalOut  led2(p7);
PwmOut      speaker(p25);
DigitalOut  rgbRed(p23);
DigitalOut  rgbGreen(p24);
DigitalOut  rgbCtrl1(p8);
DigitalOut  rgbCtrl2(p9);
DigitalOut  rgbCtrl3(p10);
SevenSegmentSerial mydisplay(UART_MODE, p28);

#define     B4NOTE  500 //Hz
#define     E5NOTE  659 //Hz

int width[3];           //width of each checkpoint, mm
int threshold[3];       //how much distance has to change, mm
float sensitivity[3] = {0.1,0.1,0.1};
int total_laps = 3;
int current_lap = 0;
int i = 500;

bool early_start = 0;
bool start_done = 0;

int setup[3] = {1,1,1};

//state machine, tracks current position in track
enum state_type {start,past_start,past_cp1,past_cp2};
state_type track_state = start;

//Mbed reset
extern "C" void mbed_reset();

//Starting countdown
void start_race()
{
    // 3
    rgbRed = 1;
    speaker.period(1.0/B4NOTE);
    speaker =0.5;
    rgbCtrl1 = 1;
    Thread::wait(500);
    speaker = 0;
    Thread::wait(500);
    // 2
    speaker =0.5;
    rgbCtrl2 = 1;
    Thread::wait(500);
    speaker = 0;
    Thread::wait(500);
    // 1
    speaker =0.5;
    rgbCtrl3 = 1;
    Thread::wait(500);
    speaker = 0;
    Thread::wait(500);
    // GO!
    rgbRed = 0;
    rgbGreen = 1;
    start_done = 1;
    speaker.period(1.0/E5NOTE);
    speaker =0.5;
    Thread::wait(1000);
    speaker = 0;
    rgbCtrl1 = 0;
    rgbCtrl2 = 0;
    rgbCtrl3 = 0;
}

// Plays bleep for crossing finish line
void play_audio()
{
    speaker.period(1.0/B4NOTE); // 500hz period
    speaker =0.5; //50% duty cycle - max volume
    Thread::wait(150);
    speaker=0.0; // turn off audio
}

//executed when crossing starting line
void start_line(int distance)
{
    if (setup[0]) {
        width[0] = distance;
        threshold[0] = distance*sensitivity[0];
        setup[0] = !setup[0];
        //pc.printf("Setup: Starting Line\n");
        //pc.printf("Distance: %3d\n\n",distance);
    }

    if (width[0] - distance >= threshold[0]) {
        //pc.printf("Past starting line\n");
        led0 = 1;
        led1 = 0;
        led2 = 0;
        current_lap++;
        //pc.printf("%d\n",current_lap);
        track_state = past_start;
        switch (current_lap) {
            case 1 :
                pc.putc('0');
                break;
            case 2 :
                pc.putc('3');
                break;
            case 3 :
                pc.putc('6');
                break;
        }
        thread1.start(&play_audio);
    }
}

//executed when passing checkpoint 1
void checkpoint1(int distance)
{
    if (setup[1]) {
        width[1] = distance;
        threshold[1] = distance*sensitivity[1];
        setup[1] = !setup[1];
        //pc.printf("Setup: Starting Line\n");
        //pc.printf("Distance: %3d\n\n",distance);
    }

    if (width[1] - distance >= threshold[1]) {
        //pc.printf("Past Checkpoint 1\n");
        led1 = 1;
        track_state = past_cp1;
        switch (current_lap) {
            case 1 :
                pc.putc('1');
                break;
            case 2 :
                pc.putc('4');
                break;
            case 3 :
                pc.putc('7');
                break;
        }
        thread1.start(&play_audio);
    }
}

//executed when passing checkpoint 2
void checkpoint2(int distance)
{
    if (setup[2]) {
        width[2] = distance;
        threshold[2] = distance*sensitivity[2];
        setup[2] = !setup[2];
        //pc.printf("Setup: Starting Line\n");
        //pc.printf("Distance: %3d\n\n",distance);
    }

    if (width[2] - distance >= threshold[2]) {
        //pc.printf("Past Checkpoint 2\n");
        led2 = 1;
        track_state = past_cp2;
        switch (current_lap) {
            case 1 :
                pc.putc('2');
                break;
            case 2 :
                pc.putc('5');
                break;
            case 3 :
                pc.putc('8');
                break;
        }
        thread1.start(&play_audio);
    }
}

ultrasonic  sonar0(p15,p16,0.1,0.1,&start_line);      //starting line
ultrasonic  sonar1(p17,p18,0.1,0.1,&checkpoint1);     //checkpoint 1
ultrasonic  sonar2(p21,p22,0.1,0.1,&checkpoint2);     //checkpoint 2

int main()
{
    //sonar initialization
    sonar0.startUpdates();
    sonar1.startUpdates();
    sonar2.startUpdates();

    //sonar calibration
    sonar0.checkDistance();
    sonar1.checkDistance();
    sonar2.checkDistance();

    //wait for start char from Pi
    while (1) {
        if (pc.getc() == 'S') {
            break;
        }
        Thread::wait(50);
    }

    //starting countdown sequence
    thread2.start(&start_race);

    //false start detect
    while(!start_done) {
        if (current_lap) {
            rgbCtrl1 = rgbCtrl2 = rgbCtrl3 = 0;
            led0 = led1 = led2 = 0;
            rgbRed = 1;
            rgbGreen = 0;
            bool other = true;
            speaker.period(1/E5NOTE);
            while (1) {
                rgbCtrl1 = !rgbCtrl1;
                rgbCtrl2 = !rgbCtrl2;
                rgbCtrl3 = !rgbCtrl3;
                led0 = !led0;
                led1 = !led1;
                led2 = !led2;
                speaker = other ? 0.5 : 0.0;
                other = !other;
                if (pc.getc() == 'R') {
                    mbed_reset();
                }
                Thread::wait(50);
            }
        }
        Thread::wait(50);
    }

    while(1) {
        switch (track_state) {
            case start:
                sonar0.checkDistance();
                break;
            case past_start:
                sonar1.checkDistance();
                break;
            case past_cp1:
                sonar2.checkDistance();
                break;
            case past_cp2:
                sonar0.checkDistance();
                break;
        }
        if (current_lap > total_laps) {
            pc.putc('9');
            //pc.printf("Race Over");
            while(1) {
                if (pc.getc() == 'R') {
                    mbed_reset();
                }
                Thread::wait(50);
            }
        }
        Thread::wait(50);
    }
}