Level 2 Project Range Device

Dependencies:   N5110 SDFileSystem SRF02 TMP102 mbed

main.cpp

Committer:
el15pjt
Date:
2016-05-05
Revision:
14:204562d1fac8
Parent:
12:0171e8723d9d

File content as of revision 14:204562d1fac8:


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

#include "main.h"

int main()
{
    setup();
    lcd.init(); // Initiate LCD
    int d = 0;
    int myarray[5] {999,999,999,999,999}; /// initilised to any possitive integer to prevent random values at start up triggering an alert

    // Load settings from SD Card\\\\\\\\\\
    FILE *fp; // file pointer
    fp = fopen("/sd/settings.txt", "r");
    if (fp == NULL) {  // if it can't open the file then print error message
        serial.printf("Error! Unable to open file!\n");
    } else {
        serial.printf("Reading file....\n");

        while (fscanf(fp, "%f,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,",&bright,&units,&offset,&check_flag,&r1,&r2,&r3,&r4,&r5,&r6,&r7) != EOF) {
            serial.printf("%f,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i, \n",bright,units,offset,check_flag,r1,r2,r3,r4,r5,r6,r7);
        }
        serial.printf("Done.\n");
        fclose(fp);  // ensure you close the file after reading
    }

    //Startup Screen

    lcd.printString("ELEC 2645",0,0);
    lcd.printString("Project Ranger",0,1);
    lcd.printString("Phil Thompson",0,2);
    lcd.printString("SID 200971914 ",0,3);
    wait (3);


    lcd.setBrightness(bright); //Set brightness of screen on startup from loaded value from SD Card

    // Main while loop of the Ranger
    while(1) {
        if (g_sw1_flag) { /// Event triggered inturupt to call the menu and reset page numbers
            g_sw1_flag = 0;
            page = 0;
            subpage = 0;
            lcd.clear();
            menu();
        }
        if (g_timer_flag_srf02) {
            g_timer_flag_srf02 = 0;  // if it has, clear the flag
            if (units == 1) { // if units = 1 metric measurment are retrived from SFR02
                distance = srf02.getDistanceCm();
                distance = distance-(offset*c);
            } else { //If units = 0 imperial measurments retrived from SFR02
                distance = srf02.getDistannceInch();
                distance = distance -(offset*c);
            } // close else breaket
        } // close if inteurrupt bracket


        //Function to average last 5 readings
        if (d == 4) {
            d = 0;
        } else {
            d++;
        }
        myarray[d] = distance;
        totaldistance =0;
        for (int i = 0; i < 5; i++) {
            totaldistance = totaldistance + myarray[i];
        }
        avgdistance = (totaldistance/5);


        /*Debugging\\
        Uncomment to use button 2 to toggle thru alert levels for debugging and comment out setalert();
        serial.printf("TOATAL DISTANCE %i\n", totaldistance);
        serial.printf("DISTANCE %i\n", distance);
        serial.printf("AVERAGE DISTANCE %f\n", avgdistance);
        serial.printf("ARRAY ELEMENT = %i\n", d);
        serial.printf("myarray %i\n", myarray[d]);
        if (g_sw2_flag) { /// Event triggered inturupt to call the menu and reset page numbers
            g_sw2_flag = 0;
            if (alert ==8) {
                alert =0;
            } else {
                alert++;
            }
            serial.printf("ALERT LEVEL %i\n", alert);
        }*/



        setalert();
        //serial.printf("ALERT LEVEL %i\n", alert);
        lcdoutput();

        if (alert !=0) { // no buzzer needed at alert == 0 path clear
            if (buzz_flag == 0) {// flag keeps buzz from being called durig it's off period
                setbuzzer();
            }
        }
        setleds(); // Function called to set LED outputs
        sleep(); // Sleep till nest interupt
    }
}

void setalert()
{
    if (avgdistance >= (r6*c) && avgdistance < (r7*c)) {  // r6 150 and r7 200
        alert = 1; /// alert 1 avgdistance between preset 150Cm to 200Cm
    } else if (avgdistance >= (r5*c) && avgdistance  < (r6*c)) {
        alert = 2; /// alert 2 when between preset 90Cm to 150Cm
    } else if (avgdistance >= (r4*c) && avgdistance < (r5*c)) {
        alert = 3; /// alert 3 when avgdistance between 60Cm to 90Cm
    } else if (avgdistance >= (r3*c) && avgdistance < (r4*c)) {
        alert = 4; /// alert 4 when avgdistance between 40Cm and 60Cm
    } else if (avgdistance >= (r2*c) && avgdistance < (r3*c)) {
        alert = 5; ///alert 5 when avgdistance between 20Cm and 40m
    } else if (avgdistance >= (r1*c) && avgdistance <= (r2*c)) { //r1 3 and r2 20
        alert = 6; ///alert 6 when avgdistance between 1 and 20
    } else if (avgdistance <=(r1*c)) {
        alert = 7; ///alert 7 when avgdistance below 1Cm
        if (check_flag ==0) {
            save();
        }
        check_flag = 1;
    } else {
        alert = 0; /// alert 0 all else
    }
}
void lcdoutput()
{
    // if alert == 0 no need to display range path is clear
    if (alert == 0) {
        lcd.clear();
        if (g_timer_flag_standby) {
            g_timer_flag_standby = 0;
            Traw = tmp102.get_temperature();
            standby++;
            if (standby >2) {
                standby = 2;
            }
        }
        switch (standby) {
            case 0:
                if (check_flag == 1) {
                    lcd.printString("COLLISIONCHECK",0,5);
                }
                lcd.printString("**PATH CLEAR**",0,0);
                lcd.refresh();
                break;
            case 1:
                if (check_flag == 1) {
                    lcd.printString("COLLISIONCHECK",0,5);
                }
                if (units == 0) {
                    T = (Traw*1.8000)+32.00;
                    sprintf(buffer3,"TEMP = %.2fF",T);
                    sprintf(buffer2,"TEMPERATER");
                } else {
                    T=Traw;
                    sprintf(buffer3,"TEMP = %.2fC",T);
                    sprintf(buffer2,"TEMPERATER");
                }
                lcd.printString(buffer3,4,3);
                lcd.printString(buffer2,12,2);
                lcd.refresh();
                break;
            case 2:
                if (check_flag == 1) {
                    lcd.printString("COLLISIONCHECK",0,5);
                }
                if (units == 0) {
                    T = (Traw*1.8000)+32.00;
                    sprintf(buffer3,"TEMP = %.2fF",T);
                    sprintf(buffer2,"TEMPERATER");
                } else {
                    T=Traw;
                    sprintf(buffer3,"TEMP = %.2fC",T);
                    sprintf(buffer2,"TEMPERATER");
                }
                lcd.printString(buffer3,4,3);
                lcd.printString(buffer2,12,2);
                lcd.refresh();
                lcd.setBrightness(0);
                break;
        } //close switch
    } else {
        //If alert isn't 0 then the distance is to be dispayed alonng with the the distance bar
        lcd.setBrightness(bright);
        standby = 0;
        lcd.clear();
        if (units == 1) {
            sprintf(buffer2,"%0.2f Cm",avgdistance);
        } else {
            sprintf(buffer2,"%0.2f In",avgdistance);
        }
        lcd.printString(buffer2,22,2);
        lcd.printString("****RANGE!****",0,0);
        lcd.printString("DISTANCE",18,1);
        lcd.printString("Menu",0,5);
        float h;
        h = (r7*c)/84; ///Maps length of bar to largest set range r7
        distbar = (avgdistance*h)-2;
        //drawRect(int x0,int y0,int width,int height,int fill);
        lcd.drawRect(0,29,distbar,7,1); //
//  serial.printf("H = %f, r7 = %i",h,r7);
// serial.printf("distbar %f",distbar);
        lcd.refresh();
    }
}//close function


void setleds()
{
    int flash = 0; ///Variable to toggle LEDs high low
    if (g_timer_flag_led) {
        g_timer_flag_led = 0;
        flash = !flash; // if it has, clear the flag
    }
    if(Alertlevel[alert].fa_led == HIGH) {
        a_led = flash;
    } else {
        a_led = Alertlevel[alert].sa_led;
    }
    if (Alertlevel[alert].frr_led == HIGH) {
        rr_led = flash;
    } else {
        rr_led = Alertlevel[alert].srr_led;
    }
    if(Alertlevel[alert].fgg_led == HIGH) {
        gg_led = flash;
    } else {
        gg_led = Alertlevel[alert].sgg_led;
    }
}

void setbuzzer()
{
    /**
    control the PWM to drive the buzzer
    @param buzzer.period frequncy 1KHz
    @param buzzer duty cycle equal on/off max volume
    @param Alertlevel[alert].toneon controls how long the tone will last depending on alert
    */
    buzzer.period (1.0/1000.0);
    buzzer = 0.5;
    buzzoff.attach(&flip, Alertlevel[alert].toneon);
}

void flip()
{
    buzz_flag = 1;
    buzzer = 0.0;
    buzzon.attach(&buzzflag, Alertlevel[alert].toneoff);
}

void buzzflag()
{
    buzz_flag = 0;
    return;
}

void backlight ()
{
    if (bright == 1.0) {
        bright = 0;
    } else {
        bright += 0.2;
    }
    lcd.setBrightness(bright);
}

void menu()
{
    while(1) {
        if (g_sw1_flag) {
            g_sw1_flag = 0;
            page++; // Moves page
            lcd.clear();
        }
        switch (page) {
            case 0:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;  // if it has, clear the flag
                    backlight();
                    lcd.clear();
                }
                int lightbar = bright*84;
                sprintf(buffer2,"%.0f%%",bright*100);
                lcd.drawRect(0,26,lightbar,7,1);  // move bar up!!!!!!!!!!!!!!!!
                lcd.printString("BACKLIGHT",0,1);
                lcd.printString(buffer2,0,2);
                lcd.printString("NEXT       ADJ",0,5);
                lcd.refresh();
                break;
            case 1:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;  // if it has, clear the flag
                    if (offset == 20) {
                        offset = 0;
                        lcd.clear();
                    } else {
                        offset += 1;
                    }
                }
                sprintf(buffer2,"%i",offset);
                lcd.printString("OFFSET",0,1);
                sprintf(buffer4,"NEXT       ADJ");
                lcd.printString(buffer4,0,5);
                break;
            case 2:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;  // if it has, clear the flag
                    if (units == 1) {
                        units = 0;
                        c = 0.3937;
                    } else {
                        units = 1;
                        c = 1;
                        lcd.clear();
                    }
                }
                if (units == 0) {
                    sprintf(buffer2,"IMPERIAL");
                } else {
                    sprintf(buffer2,"METRIC");
                }
                lcd.printString("NEXT       ADJ",0,5);
                lcd.printString("UNITS",0,1);
                break;
            case 3:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;  // if it has, clear the flag
                    check_flag =0;
                    lcd.clear();
                }
                if (check_flag == 0) {
                    sprintf(buffer2,"COLLISION");
                    lcd.printString("NO",0,1);
                    sprintf(buffer4,"NEXT     ");
                } else {
                    sprintf(buffer2,"COLLISION");
                    lcd.printString("CLEAR",0,1);
                    sprintf(buffer4,"NEXT     CLEAR");
                }

                lcd.printString(buffer4,0,5);
                break;
            case 4:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;  // if it has, clear the flag
                    bright = 1.0;
                    offset = 0;
                    units = 1;
                    r1 = 03;// Upper limit of alert 1
                    r2 = 10;// Upper limit of alert 2
                    r3 = 20;// Upper limit of alert 3
                    r4 = 30;// Upper limit of alert 4
                    r5 = 50;// Upper limit of alert 5
                    r6 = 60;// Upper limit of alert 6
                    r7 = 80;// Upper limit of alert 7
                    lcd.clear();
                    lcd.printString("SETTINGS",0,1);
                    lcd.printString("RESET",0,2);
                    wait(1);
                    return;
                }
                sprintf(buffer2,"SETTINGS");
                lcd.printString("RESET",0,1);
                lcd.printString("NEXT     RESET",0,5);
                break;
            case 5:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;  // if it has, clear the flag
                    submenu();
                }
                sprintf(buffer2,"PARAMETERS");
                lcd.printString("RANGE",0,1);
                lcd.printString("EXIT       ADJ",0,5);
                break;
            default:
                lcd.clear();
                save ();
                lcd.printString("    SAVING    ",0,2);
                lcd.printString("   SETTINGS   ",0,3);
                wait (1);
                return;
        }// switch bracket
        lcd.printString(buffer2,0,2);
        lcd.printString("*****MENU*****",0,0);
        lcd.refresh();
    }//while braket
}//functon bracket

void submenu()
{
    while(1) {
        /// interupt used to shift page
        if (g_sw1_flag) {
            g_sw1_flag = 0;
            subpage++;
        }
        switch (subpage) {  ///interupt used to adjust range
            case 0:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;           // if it has, clear the flag
                    if (r2 == r3) {
                        r2 = 3;
                    } else {
                        r2 = r2+1;
                    }
                }
                sprintf(buffer4,"1Cm to %iCm",r2);
                lcd.printString("*****MENU*****",0,0);
                lcd.printString("RANGE",0,1);
                lcd.printString("PARAMETERS",0,2);
                lcd.printString(buffer4,0,3);
                lcd.printString("NEXT       ADJ",0,5);
                break;
            case 1:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;           // if it has, clear the flag
                    if (r3 == r4) {
                        r3 = r2;
                    } else {
                        r3 += 1;
                    }
                }
                sprintf(buffer4,"%iCm to %iCm",r2,r3);
                lcd.printString("*****MENU*****",0,0);
                lcd.printString("RANGE",0,1);
                lcd.printString("PARAMETERS",0,2);
                lcd.printString(buffer4,0,3);
                lcd.printString("NEXT       ADJ",0,5);
                break;
            case 2:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;           // if it has, clear the flag
                    if (r4 == r5) {
                        r4 = r3;
                    } else {
                        r4 += 1;
                    }
                }
                sprintf(buffer4,"%iCm to %iCm",r3,r4);
                lcd.printString("*****MENU*****",0,0);
                lcd.printString("RANGE",0,1);
                lcd.printString("PARAMETERS",0,2);
                lcd.printString(buffer4,0,3);
                lcd.printString("NEXT       ADJ",0,5);
                break;
            case 3:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;           // if it has, clear the flag
                    if (r5 == r6) {
                        r5 = r4;
                    } else {
                        r5 += 1;
                    }
                }
                sprintf(buffer4,"%iCm to %iCm",r4,r5);
                lcd.printString("*****MENU*****",0,0);
                lcd.printString("RANGE",0,1);
                lcd.printString("PARAMETERS",0,2);
                lcd.printString(buffer4,0,3);
                lcd.printString("NEXT       ADJ",0,5);
                break;
            case 4:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;           // if it has, clear the flag
                    if (r6 == r7) {
                        r6 = r5;
                    } else {
                        r6 += 1;
                    }
                }
                sprintf(buffer4,"%iCm to %iCm",r5,r6);
                lcd.printString("*****MENU*****",0,0);
                lcd.printString("RANGE",0,1);
                lcd.printString("PARAMETERS",0,2);
                lcd.printString(buffer4,0,3);
                lcd.printString("NEXT       ADJ",0,5);
                break;
            case 5:
                if (g_sw2_flag) {
                    g_sw2_flag = 0;           // if it has, clear the flag
                    if (r7 == 300) {
                        r7 = r6;
                    } else {
                        r7 += 1;
                    }
                }
                sprintf(buffer4,"%iCm to %iCm",r6,r7);
                lcd.printString("*****MENU*****",0,0);
                lcd.printString("RANGE",0,1);
                lcd.printString("PARAMETERS",0,2);
                lcd.printString(buffer4,0,3);
                lcd.printString("EXIT       ADJ",0,5);
                break;
            default:
                lcd.clear();
                return;
        }//switch breaket
    }//while bracket
}//function bracket

void save()
{
    fp = fopen("/sd/settings.txt", "w");
    if (fp == NULL) {  // if it can't open the file then print error message
        serial.printf("Error! Unable to open file!\n");
    } else {  // opened file so can write
        serial.printf("Writing to file....");
        fprintf(fp, "%f,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i",bright,units,offset,check_flag,r1,r2,r3,r4,r5,r6,r7); // ensure data type matches
        serial.printf("Done.\n");
        fclose(fp);  // ensure you close the file after writing
    }
}

void setup()
{
    serial.baud(115200);  // full-speed!
    ticker.attach(&timer_isr_led,0.35); /// Attach the ticker for the flashig LEDs
    ticker_srf02.attach(&timer_isr_srf02,0.2);/// Attach the ticker for collecting a range reading
    ticker_standby.attach(&timer_isr_standby,5.0);
    sw1.rise(&sw1_isr); /// sw1_isr called when button presed on the rising edge
    sw2.rise(&sw2_isr); /// sw2_isr called when button presed on the rising edge
    r_led = 1; //Onboard leds
    b_led = 1; //Onboard leds
    g_led = 1; //Onboard leds
    rr_led = 0; //PCB LEDS
    a_led = 0; //PCB LEDS
    gg_led = 0; //PCB LEDS
    sw2.mode(PullDown); //Turns on use of the pulldown resistors for use with the PCB buttons
    sw1.mode(PullDown); //Turns on use of the pulldown resistors for use with the PCB buttons
}

void sw2_isr()
{
    g_sw2_flag = 1;   /** set flag in ISR by button 2 @param g_sw2_flag 0 or 1*/
}

void sw1_isr()
{
    g_sw1_flag = 1;   /** set flag in ISR by button 2 @param g_sw1_flag 0 or 1*/
}

void timer_isr_led()
{
    g_timer_flag_led = 1;   /** set flag in ISR by timer_isr_led @param g_timer_flag_led 0 or 1 */
}

void timer_isr_srf02()
{
    g_timer_flag_srf02 = 1;   /** set flag in ISR by ticker_srf02 @param g_timer_flag_srf02 0 or 1 */
}

void timer_isr_standby()
{
    g_timer_flag_standby = 1; /** set flag in ISR by ticker_tone @param g_timer_flag_tone 0 or 1 */
}