ELEC2645 Year 2 Project Arnau Segura Doncel 200867010

Dependencies:   N5110 SRF02 TMP102 mbed

main.cpp

Committer:
ollie140
Date:
2016-05-05
Revision:
0:4a66fd16c223

File content as of revision 0:4a66fd16c223:

/**
@file main.cpp
@brief program implementation

*/
#include "main.h"

int main()
{
    introScreen();
    while (1) {
        if (g_timer2_flag) {
            g_timer2_flag = 0;
            if (current_screen == menu_state) { //Main menu
                mainMenu();
            } else if (current_screen == modes_state) { //modes menu
                modesMenu();
            } else if (current_screen == peripherals_state) { // peripherals menu
                peripheralsMenu();
            } else if (current_screen == brightness_state) { // brightness menu
                brightnessMenu();
            } else if (current_screen == sound_state) { // sound menu
                soundMenu();
            } else if (current_screen == ledMenu_state) { // LED menu
                LEDMenu();
            } else if (current_screen == nightMenu_state) { // night menu
                nightMenu();
            } else if (current_screen == parkingMode_state) { // parking mode setup
                printBars();
            } else if (current_screen == numericMode_state) { // numeric mode setup
                numericMode();
            }
        }
        sleep();
    }
}


float getDistance()
{

    emptyVariable = 0; // initialise the empty variable

    for (int i = 0 ; i<10; i++) { // intitialises the measurement for loop

        realDistance = srf.getDistanceCm(); // get a distance measurement for every i value
        emptyVariable = emptyVariable + realDistance ; // add all these measurements up
    }

    distance = emptyVariable/10.0; // divide all the measurements by 10 to take the average
    return distance; // return the distance

}

void drawCar()
{
    lcd.drawRect(1,8,56,32,1);  // main car rectangle
    lcd.drawRect(15,6,9,1,1);   // right front wheel
    lcd.drawRect(40,6,9,1,1);   // right back wheel
    lcd.drawRect(15,41,9,1,1);  // left front wheel
    lcd.drawRect(40,41,9,1,1);  // left back wheel
    lcd.drawRect(20,14,9,20,2); // front window
    lcd.drawRect(42,16,6,16,2);  // back window

}

void reallyCloseDistance()
{
    lcd.drawRect(60,8,3,32,1);  // really close bar
    lcd.drawRect(66,8,3,32,1);  // close bar
    lcd.drawRect(72,8,3,32,1);  // medium bar
    lcd.drawRect(78,8,3,32,1);  // far bar
}

void closeDistance()
{
    lcd.drawRect(66,8,3,32,1);  // close bar
    lcd.drawRect(72,8,3,32,1);  // medium bar
    lcd.drawRect(78,8,3,32,1);  // far bar
}

void mediumDistance()
{
    lcd.drawRect(72,8,3,32,1);  // medium bar
    lcd.drawRect(78,8,3,32,1);  // far bar
}

void farDistance()
{
    lcd.drawRect(78,8,3,32,1);  // far bar
}

void printBars()
{
    potTicker.detach(); // detach the potentiometer ticker 

    sensorTicker.attach(&timer_isr,0.7); // attach a ticker that will be called every 0.7 seconds

    while (current_screen == parkingMode_state) { // while the parking mode menu is true 

        dist = getDistance(); // get the distance in cm

        T = tmp102.get_temperature(); // get the temperature in C

        temp = floor(T); // floor the temperature to get an integer value

        LED = 0; // Set the LED to off

        if (g_timer_flag) { // if the timer event is called

            g_timer_flag = 0; // reset flag back to 0

            lcd.clear();// clear the screen

            length2 = sprintf(buffer2,"%dC",temp); // assign a value to the string lenght

            if (length2 <= 14) { // if string will fit on display
                lcd.printString(buffer2,66,0); // print the desired string
            }

            if (dist > 140) { // if distance is more than 140 cm
                drawCar(); // draw the car shape
                buzzerOFF();
            } else if (dist <= 140 && dist > 100) { // if distance is between 140 cm and 100 cm
                drawCar(); // draw the car shape
                farDistance(); // draw 1 bar
                buzzerOFF();
            } else if (dist <= 100 && dist > 70) { // if distance is between 100 cm and 70 cm
                drawCar(); // draw the car shape
                mediumDistance(); // draw 2 bars
                buzzerOFF();
            } else if (dist <= 70 && dist > 40) { // if distance is between 70 cm and 40 cm
                drawCar(); // draw the car shape
                closeDistance(); // draw 3 bars
                buzzerOFF();
            } else { // if distance is less than 40 cm
                drawCar(); // draw the car shape
                reallyCloseDistance(); // draw 4 bars
                
                if (buzzer_state == buzzerON_state) {
                    buzzerON();
                } else {
                    buzzerOFF();
                }
                
                if (led_state == LEDON_state) { // if the state of the LED menu is on 
                    LED = 1; // turn on the LED
                } else {
                    LED = 0; // keep the LED off
                }
            }

            if (g_botButton_flag) { // if the button is pressed
                g_botButton_flag = 0; // reset the flag

                LED = 0; // turn off the LED
                
                buzzerOFF(); // sets the duty cycle to 0
                
                sensorTicker.detach(); // detach the sensor ticker to save computing powr and battery

                current_screen = menu_state; // go back to the main menu

                potTicker.attach(&timer2_isr,0.2); // attach the potentiometer ticker

            }
            lcd.refresh(); // refresh the screen
        }
        sleep(); // send the MCU back to sleep to save power
    }

}

void numericMode()
{
    potTicker.detach(); // detanch the ticker potentiometer

    sensorTicker.attach(&timer_isr,0.7); // attach the sensor ticker to be called every 0.7 seconds

    while (current_screen == numericMode_state) {

        dist = getDistance(); // get the distance in cm

        T = tmp102.get_temperature(); // get the temperature in C

        if (g_timer_flag) { // if time event is triggered

            lcd.clear(); // clear the LCD

            length1 = sprintf(buffer,"D = %.2f cm",dist); // assign a lenght integer for the distance string

            length2 = sprintf(buffer2,"T = %.2f C",T); // assign a lenght integer for the temperature string

            if (length1 <= 14) { // if string will fit on display
                lcd.printString(buffer,0,2);
            }
            if (length2 <= 14) { // if string will fit on display
                lcd.printString(buffer2,0,4);
            }

            if (g_botButton_flag) { // if the event trigger is activated by pressing the bottom button
                g_botButton_flag = 0; // reset the flag 
                
                sensorTicker.detach(); // detach the sensor ticker

                current_screen = menu_state; // go back to the main menu

                potTicker.attach(&timer2_isr,0.2); // attach the potentiometer ticker

            }

            lcd.refresh(); // refresh the LCD
        }
        sleep(); // save power by sending the MCU to sleep
    }
}


void introScreen()
{

    init_K64F(); // intialise all of the K64F's on board peripherals
    init_serial();
    potTicker.attach(&timer2_isr,0.2); // attach a ticker for the potentiometer
    tmp102.init(); // initialise the temperature sensor
    lcd.init(); // initialise the LCD display
    lcd.setBrightness(1.0);
    lcd.printString("PARKING",21,0); 
    lcd.printString("SENSOR",25,2);
    lcd.printString("BY",36,3);
    lcd.printString("ARNAU SEGURA",6,4); 
    led_state = LEDON_state; // start with the warning LED on the ON state
    buzzer.period(1/1000.0);
    buzzer_state = buzzerON_state;
    wait(3); // wait 3 seconds
    lcd.clear(); // clear the LCD
    lcd.refresh(); // refresh the LCD

}

void mainMenu()
{

    lcd.clear(); // clear the LCD
    lcd.printString("MENU",28,0); 
    lcd.printString("MODES",25,2); 
    lcd.printString("PERIPHERALS",9,4);
    
    g_botButton_flag = 0; // set the flag to 0 on the main menu so that if the bottom button is accidentally pressed the bug where the user would be forced to stay in main menu is solved

    if (pot < 0.5f) { // if the potentiometer is normalised to less than 0.5
        MenuLine2(); // invert pixels in bank 3
        selected_option = modes_state;
    } else {
        MenuLine4(); // invert pixels in bank 5
        selected_option = peripherals_state;
    }
    goToSelectedOption(); // if the top button is pressed go to the selected option
    lcd.refresh();
}

void peripheralsMenu()
{
    lcd.clear();
    lcd.printString("PERIPHERALS",9,0);
    lcd.printString("BRIGHTNESS",12,2);
    lcd.printString("SOUND",25,3);
    lcd.printString("LEDs",28,4);
    lcd.printString("NIGHT LCD",15,5);
    if (pot <= 0.25f) {
        MenuLine2(); // invert pixels in bank 3
        selected_option = brightness_state;
    } else if (pot <= 0.5f) {
        MenuLine3(); // invert pixels in bank 4
        selected_option = sound_state;
    } else if (pot <= 0.75f) {
        MenuLine4(); // invert pixels in bank 5
        selected_option = ledMenu_state;
    } else {
        MenuLine5(); // invert pixels in bank 6
        selected_option = nightMenu_state;
    }
    goToMainMenu(); // if bottom button is pressed go back to main menu
    goToSelectedOption(); // if the top button is pressed go to the selected option
    lcd.refresh();
}

void modesMenu()
{
    lcd.clear();
    lcd.printString("MODES",25,0);
    lcd.printString("PARKING MODE",6,2);
    lcd.printString("NUMERIC MODE",6,4);

    if (pot <= 0.5f) {
        MenuLine2(); // invert pixels in bank 3
        selected_option = parkingMode_state;
    } else {
        MenuLine4(); // invert pixels in bank 5
        selected_option = numericMode_state;
    }
    goToMainMenu(); // go back to main menu
    goToSelectedOption(); // go to selected option
    lcd.refresh();
}

void soundMenu()
{
    lcd.clear();
    lcd.printString("SOUND MENU",12,0);
    lcd.printString("SOUND ON",18,3);
    lcd.printString("SOUND OFF",15,5);

    if (pot <= 0.5f) {
        MenuLine3Short(); // partially inverts bank 4 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;
            
            buzzer_state = buzzerON_state;
            circle_position_SOUND = 27; // set y position for the circle to be drawed
        }
    } else {
        MenuLine5Short(); // partially inverts bank 6 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;
            
            buzzer_state = buzzerOFF_state;
            circle_position_SOUND = 43; // set y position for the circle to be drawed
        }
    }
    
    lcd.drawCircle(4,circle_position_SOUND,2,1); // draw a circle next to the selected option for the respective y position
    lcd.drawCircle(80,circle_position_SOUND,2,1); // draw a circle next to the selected option for the respective y position
    goToMainMenu(); // go back to main menu
    lcd.refresh();
}

void buzzerON()
{
    buzzer.write(0.5); // set the buzzers duty cycle to 50%
}

void buzzerOFF()
{
    buzzer.write(0.0); // set the buzzers duty cycle to 0%
}

void LEDMenu()
{

    lcd.clear();
    lcd.printString("LED MENU",18,0);
    lcd.printString("LED ON",24,3);
    lcd.printString("LED OFF",21,5);

    if (pot <= 0.5f) {
        MenuLine3Short(); // partially inverts bank 4 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;

            circle_position_LED = 27; // set y position for the circle to be drawn
            led_state = LEDON_state; // set the empty led state variable to the LED On state
        }

    } else {
        MenuLine5Short(); // partially inverts bank 6 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;

            circle_position_LED = 43; // set y position for the circle to be drawn
            led_state = LEDOFF_state; // set the empty led state variable to the LED Off state
        }
    }
    
    lcd.drawCircle(4,circle_position_LED,2,1); // draw a circle next to the selected option for the respective y position
    lcd.drawCircle(80,circle_position_LED,2,1); // draw a circle next to the selected option for the respective y position
    goToMainMenu(); // go to main menu
    lcd.refresh();

}

void brightnessMenu()
{
    lcd.clear();
    lcd.printString("BRIGHTNESS",12,0);
    lcd.printString("0%",36,1);
    lcd.printString("25%",33,2);
    lcd.printString("50%",33,3);
    lcd.printString("75%",33,4);
    lcd.printString("100%",30,5);

    if (pot <= 0.2f) {
        MenuLine1Short(); // partially inverts bank 2 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;
            circle_position_brightness = 11; // set y position for circle
            screenLED.write(0.0); // set the brighness to 0%
        }
    } else if (pot <= 0.4f) {
        MenuLine2Short(); // partially inverts bank 3 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;
            circle_position_brightness = 19; // set y position for circle
            screenLED.write(0.25); // set the brighness to 25%
        }
    } else if (pot <= 0.6f) {
        MenuLine3Short(); // partially inverts bank 4 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;
            circle_position_brightness = 27; // set y position for circle
            screenLED.write(0.5); // set the brighness to 50%
        }
    } else if (pot <= 0.8f) {
        MenuLine4Short(); // partially inverts bank 5 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;
            circle_position_brightness = 35; // set y position for circle
            screenLED.write(0.75); // set the brighness to 75%
        }
    } else {
        MenuLine5Short(); // partially inverts bank 6 of the LCD
        if (g_topButton_flag) {
            g_topButton_flag = 0;
            circle_position_brightness = 43; // set y position for circle
            screenLED.write(1.0); // set the brighness to 100%
        }
    }
    
    lcd.drawCircle(4,circle_position_brightness,2,1); // draw a circle next to the selected option for the respective y position
    lcd.drawCircle(80,circle_position_brightness,2,1); // draw a circle next to the selected option for the respective y position
    goToMainMenu(); // go back to main menu
    lcd.refresh();
}

void nightMenu()
{
    lcd.clear();
    lcd.printString("NIGHT MODE",12,0);
    lcd.printString("DAY",33,3);
    lcd.printString("NIGHT",27,5);
    
    if (pot <= 0.5f) {
        MenuLine3Short();
        if (g_topButton_flag) {
            g_topButton_flag = 0;

            circle_position_NIGHT = 27; // set y position for circle
            lcd.normalMode(); // set the sreen to normal mode
        }

    } else {
        MenuLine5Short();
        if (g_topButton_flag) {
            g_topButton_flag = 0;

            circle_position_NIGHT = 43; // set y position for circle
            lcd.inverseMode(); // set the screen to inverse mode
        }
    }
    lcd.drawCircle(4,circle_position_NIGHT,2,1); // draw a circle next to the selected option for the respective y position
    lcd.drawCircle(80,circle_position_NIGHT,2,1); // draw a circle next to the selected option for the respective y position
    goToMainMenu(); // go back to main menu
    lcd.refresh();
}

void goToMainMenu()
{
    if (g_botButton_flag) { // if the bottom button is pressed
        g_botButton_flag = 0; // sets the flag to 0

        current_screen = menu_state; // the current screen will go to the main menu (state 0)
    }
}

void goToSelectedOption()
{
    if (g_topButton_flag) {
        g_topButton_flag = 0;

        current_screen = selected_option; // the current screen will go to the selected option

    }
}

void MenuLine1()
{
    for (int i = 0; i < WIDTH; i++) { //scans all the pixels in the second bank and inverts them
        for (int j = 8; j <= 14; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void MenuLine1Short()
{
    for (int i = 15; i < 70; i++) { // scans most of the pixels in the second bank and inverts them
        for (int j = 8; j <= 14; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}
void MenuLine2()
{
    for (int i = 0; i < WIDTH; i++) { //scans all the pixels in the third bank and inverts them
        for (int j = 16; j <= 22; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void MenuLine2Short()
{
    for (int i = 15; i < 70; i++) { // scans most of the pixels in the third bank and inverts them
        for (int j = 16; j <= 22; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void MenuLine3()
{
    for (int i = 0; i < WIDTH; i++) { //scans all the pixels in the fourth bank and inverts them
        for (int j = 24; j <= 30; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void MenuLine3Short()
{
    for (int i = 15; i < 70; i++) { // scans most of the pixels in the fourth bank and inverts them
        for (int j = 24; j <= 30; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void MenuLine4()
{
    for (int i = 0; i < WIDTH; i++) { //scans all the pixels in the fifth bank and inverts them
        for (int j = 32; j <= 38; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void MenuLine4Short()
{
    for (int i = 15; i < 70; i++) { // scans most of the pixels in the fifth bank and inverts them
        for (int j = 32; j <= 38; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void MenuLine5()
{
    for (int i = 0; i < WIDTH; i++) { //scans all the pixels in the sixth bank and inverts them
        for (int j = 40; j <= 46; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void MenuLine5Short()
{
    for (int i = 15; i < 70; i++) { // scans most of the pixels in the sixth bank and inverts them
        for (int j = 40; j <= 46; j++) {
            if (lcd.getPixel(i,j)) {

                lcd.clearPixel(i,j);

            } else {

                lcd.setPixel(i,j);
            }
        }
    }
}

void init_serial()
{
    // set to highest baud - ensure terminal software matches
    pc.baud(115200);
}

void init_K64F()
{
    // on-board LEDs are active-low, so set pin high to turn them off.
    r_led = 1;
    g_led = 1;
    b_led = 1;

    // since the on-board switches have external pull-ups, we should disable the internal pull-down
    // resistors that are enabled by default using InterruptIn
    sw2.mode(PullNone);
    sw3.mode(PullNone);

    topButton.mode(PullDown); // set the top button to pull-down mode
    botButton.mode(PullDown); // set the bottom button to pull-down mode
    topButton.rise(&topButton_isr); // recognise the press of the button as a rise up (from mbed pin to 3V3)
    botButton.rise(&botButton_isr); // recognise the press of the button as a rise up (from mbed pin to 3V3)

}

// time-triggered interrupt used for the sensorTicker
void timer_isr()
{
    g_timer_flag = 1;   // set flag in ISR
}

//time triggered interrupt used for the buttonsDebounce ticker
void timer1_isr()
{
    g_timer1_flag = 0;   // set flag in ISR

    buttonsDebounce.detach(); // detach the buttonsDebounce ticker
}

//time triggered interrupt used for the potTicker 
void timer2_isr()
{
    g_timer2_flag = 1;   // set flag in ISR
}

//event triggered interrupt
void botButton_isr()
{
    if (!g_timer1_flag) { // when the button is pressed if the buttonsDebounce flag is on 0

        g_botButton_flag = 1; // set the flag to 1

        g_timer1_flag = 1; // set the flag to 1

        buttonsDebounce.attach(&timer1_isr,0.2); // attach a short delay of 0.2 that will prevent the button from providing multiple inputs to the MCU

    }

}

//event triggered interrupt
void topButton_isr()
{
    if (!g_timer1_flag) { // when the button is pressed if the buttonsDebounce flag is on 0

        g_topButton_flag = 1; // set the flag to 1

        g_timer1_flag = 1; // set the flag to 1

        buttonsDebounce.attach(&timer1_isr,0.2); // attach a short delay of 0.2 that will prevent the button from providing multiple inputs to the MCU

    }

}