A Weather station designed to read the values of temperature and pressure from the sensor (BMP180), data displayed via a nokia N5110 display.

Dependencies:   BMP180 N5110 PowerControl mbed

Barometer.cpp

Committer:
amiraseman
Date:
2015-05-09
Revision:
25:fa65a9cc78f0
Parent:
24:51cbed3fbf5c
Child:
26:c0d8d2f68406

File content as of revision 25:fa65a9cc78f0:

/**
@file Barometer.cpp

@brief Member functions implementations

*/
#include "mbed.h"
#include "Barometer.h"


///
void button1Pressed()  //ISR to subtract 1 from the value of choice when the first button is pressed
{
    if (debounce.read_ms()>200) // only allow if debounce timer
        button1Flag=1; // has passed 200 ms
    debounce.reset(); // restart timer when the toggle is performed
}


///
void button2Pressed() //ISR to add 1 to the value of the choice when the second button is pressed
{
    if (debounce.read_ms()>200) // only allow if debounce timer
        button2Flag=1; // has passed 200 ms
    debounce.reset(); // restart timer when the toggle is performed
}


///
void button3Pressed()
{
    if (debounce.read_ms()>200) // only allow if debounce timer
        button3Flag=1; // has passed 200 ms
    debounce.reset(); // restart timer when the toggle is performed
}


///
void button4Pressed()
{
    if (debounce.read_ms()>200) // only allow if debounce timer
        button4Flag=1; // has passed 200 ms
    debounce.reset(); // restart timer when the toggle is performed
}



/// ISR called by the timer to set the timer flag to 1 (flag is used to update the values of pressure and temperature every second for the live data function)
void timerExpired()
{
    yellowLED = 0;
    timerFlag=1;

}


///An ISR called by data logger timer to set the dataLoggerFlag to 1
void dataLoggerTimerExpired ()
{
    yellowLED = 0;
    dataLoggerFlag = 1 ;

}


/// open a local file and print the recieved char arrays in the stream
void saveToFile(char *data,char *data1,char *data2,char *data3)
{
    FILE* pFile = fopen("/local/textfile.csv","w"); // open file access
    fprintf (pFile, "%s\n%s\n%s\n%s", data,data1,data2,data3);
    fclose (pFile);
}


/// Gets the current time and stores them in bufferTime and bufferDate
void updateTime()
{
    time_t seconds = time(NULL); // get current time
// format time into a string (time and date)
    currentTime = seconds ; // sets the current time to an integer for alarm clock check
    //serial.printf("current time :%i \n",currentTime);
    //serial.printf("Unix date :%i \n",UNIXdate);
    strftime(bufferTime, 14 , "%H:%M", localtime(&seconds));
    strftime(bufferDate, 14 , "%d/%m/%y", localtime(&seconds));
}


/// Displays the screen buffers on the lcd
void display()
{
    lcd.clear();
    lcd.printString(buffer0,0,0);
    lcd.printString(buffer1,0,1);
    lcd.printString(buffer2,0,2);
    lcd.printString(buffer3,0,3);
    lcd.printString(buffer4,0,4);
    lcd.printString(buffer5,0,5);
    wait(0.1);

}



///Imports the data and saves them to the bufferss
void readData()
{

    Measurement measurement;  // measurement structure declared in BMP180 class

    measurement = bmp180.readValues();
    // serial.printf("T = %.2f C P = %.2f mb\n",measurement.temperature,measurement.pressure);


    if (unitFlag==1 || unitFlag==2 ) { //c

        temperature = measurement.temperature;
        int length = sprintf(bufferT,"%0.1f",temperature); // print formatted data to buffer
        // it is important the format specifier ensures the length will fit in the buffer
    }
    if (unitFlag==3 || unitFlag==4 ) {//f
        temperature =( measurement.temperature*(9/5))+32;
        int length = sprintf(bufferT,"%0.1f",temperature); // print formatted data to buffer
        // it is important the format specifier ensures the length will fit in the buffer
    }




    if (unitFlag==1 || unitFlag==3 ) {//mb
        pressure = measurement.pressure;  // same idea with float
        int  length = sprintf(bufferP,"%.2f",pressure); // print formatted data to buffer
        // it is important the format specifier ensures the length will fit in the buffer
    }
    if (unitFlag==2 || unitFlag==4 ) {//atm
        pressure = measurement.pressure*0.0009869;  // same idea with floats
        int length = sprintf(bufferP,"%.2f",pressure); // print formatted data to buffer
        // it is important the format specifier ensures the length will fit in the buffer
    }

}




/// Called by the powerSaverTimeout to turn off the lcd and put the mbed in sleep mode
void powerSaverExpired()
{
    powerSaverFlag = 1;
}






/// Checks if the power saver option is set by the user, if yes attach a timeout to call save power; if its not set detach the timeout
void powerSaverCheck()   // checks if the powersaverFlag is set
{
    if (powerSaverFlag == 1) {
        while (1) {
            alarmClockCheck();
            updateTime();
            loggerData();

            if (button1Flag || button2Flag || button3Flag || button4Flag) { // if any of the buttons are pressed
                powerSaverTimeout.attach(&powerSaverExpired, powerSaverTime); // setup a timeiut to call the savePower function
                powerSaverFlag = 0;
                lcd.init();
                button1Flag = 0 ;
                button2Flag = 0 ;
                button3Flag = 0 ;
                button4Flag = 0 ;
                break;
            }
            lcd.turnOff();
            Sleep();
        }
    }
}



/// Displays the live values of temperature and pressure, refreshes every 1 second
void liveData()
{
    timerFlag=1;
    timer.attach(&timerExpired,1.0);
    while (1) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        loggerData();
        if (timerFlag) {

            yellowLED = 1;
            timerFlag=0;
            readData();
            thresholdCheck();
            strncpy(buffer1, bufferTime, 14);
            strncpy(buffer2, bufferDate, 14);
            strncpy(buffer3, bufferT, 14);
            strncpy(buffer4, bufferP, 14);
            int dispaly = sprintf (buffer5, "");//convert integer to buffer str
            int dispaly1 = sprintf (buffer0, "");//convert integer to buffer str
            display();
        }
        yellowLED = 0;
        if (button3Flag) {
            button3Flag = 0;
            timer.detach();
            break;
        }
    }
}



///  gets the temperature and pressure data and stores to suitable arrays, saves the arrays to the local file
void loggerData()
{


    if(dataLoggerFlag ==1) {
        int k ;
        int sumTemperature = 0;
        int sumPressure = 0;
        greenLED = 1;
        readData();
        thresholdCheck();
        dataLoggerFlag=0;
//write the data to the arrays (arrays used to plot graphs)
        //read the data from sensor


//reads the saved data back from the local file

        FILE* pFilea = fopen("/local/textfile.csv","r"); // open file access

        if (pFilea) {//checks if any data is available from the previous readings
            fscanf (pFilea, "%s\n %s\n %s\n %s\n", temperatureRecieved,pressureRecieved,timeRecieved,dateRecieved);
            fclose (pFilea);


            //initialises the arrays with the saved data from the past
            strcpy (temperatureSent,temperatureRecieved);
            strcpy (pressureSent,pressureRecieved);
            strcpy (timeSent,timeRecieved);
            strcpy (dateSent,dateRecieved);
        }


//inserts the int values to char arrays to save them to the local file
        strcat(temperatureSent,bufferT);
        strcat(temperatureSent,",");
        strcat(pressureSent,bufferP);
        strcat(pressureSent,",");



        //apends the new time and current stamp to the array with , between them
        strcat(timeSent,bufferTime);
        strcat(timeSent,",");
        strcat (dateSent,bufferDate);
        strcat (dateSent,",");

        //send the arrays above to the local file
        saveToFile(temperatureSent,pressureSent,timeSent,dateSent);
        //serial.printf ("sent temp %s\nsent pressure %s\nsent time %s\nsent date %s\n",temperatureSent,pressureSent,timeSent,dateSent);

//reads the saved data back from the local file

        FILE* pFileb = fopen("/local/textfile.csv","r"); // open file access
        fscanf (pFileb, "%s\n %s\n %s\n %s\n", temperatureRecieved,pressureRecieved,timeRecieved,dateRecieved);
        fclose (pFileb);

        //serial.printf ("rec temp %s\nrec pressure %s\nrec time %s\nrec date %s\n",temperatureRecieved,pressureRecieved,timeRecieved,dateRecieved);


        //seperates the array into tokens(seperated after the delimiter , )
        pch = strtok (timeRecieved,",");//pch is the arguement of the for str
        while (pch != NULL) {
            //serial.printf (" splitted time = %s\n",pch);
            pch = strtok (NULL, ",");
        }
        pch1 = strtok (dateRecieved,",");
        while (pch1 != NULL) {
            //serial.printf (" splitted date= %s\n",pch1);
            pch1 = strtok (NULL, ",");
        }
        pch2 = strtok (temperatureRecieved,",");
        int p=0;
        while (pch2 != NULL) {
            //serial.printf (" splitted temperature = %s\n",pch2);
            arrayT[p]=atof(pch2);
            pch2 = strtok (NULL, ",");
            p++;
        }

        p=0;
        pch3 = strtok (pressureRecieved,",");
        while (pch3 != NULL) {
            // serial.printf (" splitted pressure= %s\n",pch3);
            arrayP[p]=atof(pch3);
            pch3 = strtok (NULL, ",");
            p++;
        }

// calculate the average value of the arrays and save them to an integer



        minTemperature = arrayT[0]; // sets the min to the first value in the array
        minPressure = arrayP[0];
        maxTemperature = arrayT[0];
        maxPressure = arrayP[0];


        for (k = 0 ; k<p ; k++) { // loops through the arrays
            // printf("arrayT = %lf\n",arrayT[k]);
            // printf("arrayP = %lf\n",arrayP[k]);


            if (unitFlag==1 || unitFlag==2 ) { //c
                arrayTG[k]=(arrayT[k]/60);
            }
            if (unitFlag==3 || unitFlag==4 ) {//f
                arrayTG[k]=(arrayT[k]/140);
            }




            if (unitFlag==1 || unitFlag==3 ) {//mb
                arrayPG[k]=(arrayP[k]/1500);
            }
            if (unitFlag==2 || unitFlag==4 ) {//atm
                arrayPG[k]=(arrayP[k]/2);
            }



            sumTemperature += arrayT[k]; // calculates the sum of the stored values
            averageTemperature = sumTemperature/(k+1) ; //calculates the average value

            sumPressure += arrayP[k]; // calculates the sum of the stored values
            averagePressure =(sumPressure/(k+1)) ; //calculates the average value

            if(arrayT[k]>maxTemperature) { // checks if any of the values in the array is bigger than the fist value
                maxTemperature=arrayT[k];  // if any greater values, sets the max value to that
            }
            if(arrayT[k]<minTemperature) { // finds the smallest value of the array
                minTemperature=arrayT[k];
            }
            if(arrayP[k]>maxPressure) { // checks if any of the values in the array is bigger than the fist value
                maxPressure=(arrayP[k]);  // if any greater values, sets the max value to that
            }
            if(arrayP[k]<maxPressure) {
                minPressure=(arrayP[k]);
            }

        }



        if (p>83) { // if the number of reading taken is more than 84 clear the arrays and the local file
            strcpy (temperatureSent,"");
            strcpy (pressureSent,"");
            strcpy (timeSent,"");
            strcpy (dateSent,"");
        }
    }
    greenLED = 0;
}




/// Show a summery of minimum maximum and average values for temperature and pressure as well as the temperature-time and pressure_time graphs
void dataLogger()
{
    int swipe = 1 ;
    while (1) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        if (runLoggerFlag) {


            loggerData();


            if (button4Flag) {
                button4Flag = 0 ;
                swipe ++;
            }
            if (swipe > 4) {
                swipe = 1;
            }

            strncpy(buffer0, bufferTime, 14);
            int display5 = sprintf (buffer5, " Back    Next");//convert integer to buffer str

            switch (swipe) {
                case 1: {
                    int display1 = sprintf (buffer1, "Temperature");
                    int display2 = sprintf (buffer2, "Min = %0.2f", minTemperature);
                    int display3 = sprintf (buffer3, "Max = %0.2f", maxTemperature);
                    int display4 = sprintf (buffer4, "Avg = %0.2f", averageTemperature);
                    display();
                    break;
                }
                case 2 : {
                    lcd.clear();
                    lcd.printString("  Temperature",0,0);
                    lcd.plotArray(arrayTG);
                    break;
                }
                case 3 : {
                    int display11 = sprintf (buffer1, "Pressure");
                    int display22 = sprintf (buffer2, "Min = %0.2f", minPressure);
                    int display33 = sprintf (buffer3, "Max = %0.2f", maxPressure);
                    int display44 = sprintf (buffer4, "Avg = %0.2f", averagePressure);
                    display();
                    break;
                }
                case 4 : {
                    lcd.clear();
                    lcd.printString("   Pressure",0,0);
                    lcd.plotArray(arrayPG);
                    break;
                }
                default :
                    break;
            }
        } else {
            lcd.clear();
            lcd.printString("  To Turn On",0,1);
            lcd.printString("    Go To",0,2);
            lcd.printString("   Settings",0,3);
            lcd.printString ("Back",0,5);

        }

        if (button3Flag) {
            button3Flag=0;
            break;
        }
        wait(0.1);
    }
}



/// Checks if the current temperture and pressure is equal to one of the thresholds set by the user, if yes it triggers the alarm and sets the buzzer
void thresholdCheck()
{
    if (thresholdAlarmFlag) {
        thresholdAlarmFlag = 1;
        if (int(temperature) <= fsmH[0].output) { //if the current temp is less than the set threshold
            while (1) {
                redLED = 0 ;
                strncpy(buffer0, bufferTime, 14);
                int display2 = sprintf (buffer1, "");
                int display0 = sprintf (buffer2, "Threshold");
                int display1 = sprintf (buffer3, "Reached!");
                int display4 = sprintf (buffer4, "%0.1f!",temperature);
                int display5 = sprintf (buffer5, "Stop");
                display();
                for (int i=0; i<=11; i++) {
                    buzzer.period(1/(frequency[i])); // set PWM period
                    buzzer=0.5; // set duty cycle
                    //wait(0.5); // hold for beat period
                    redLED = 1 ;
                    if (button3Flag) {
                        buzzer = 0 ;
                        lcd.setBrightness(0.5);
                        button3Flag=0;
                        goto exit ;
                    }
                }
            }
        }
        if (int(temperature) >= fsmH[1].output) { //if the current temp is greater than the set threshold
            while (1) {
                redLED = 0 ;
                strncpy(buffer0, bufferTime, 14);
                int display2 = sprintf (buffer1, "");
                int display0 = sprintf (buffer2, "Threshold");
                int display1 = sprintf (buffer3, "Reached!");
                int display4 = sprintf (buffer4, "%0.1f!",temperature );
                int display5 = sprintf (buffer5, "Stop");
                display();
                for (int i=0; i<=11; i++) {
                    buzzer.period(1/(frequency[i])); // set PWM period
                    buzzer=0.5; // set duty cycle
                    //wait(0.5); // hold for beat period
                    redLED = 1 ;
                    if (button3Flag) {
                        buzzer = 0 ;
                        lcd.setBrightness(0.5);
                        button3Flag=0;
                        goto exit ;
                    }
                }
            }
        }
        if (int(pressure) <= fsmH[2].output) {  //if the current pressure is less than the set threshold
            while (1) {
                redLED = 0 ;
                strncpy(buffer0, bufferTime, 14);
                int display2 = sprintf (buffer1, "");
                int display0 = sprintf (buffer2, "Threshold");
                int display1 = sprintf (buffer3, "Reached!");
                int display4 = sprintf (buffer4, "%0.1f!",pressure);
                int display5 = sprintf (buffer5, "Stop");
                display();
                for (int i=0; i<=11; i++) {
                    buzzer.period(1/(frequency[i])); // set PWM period
                    buzzer=0.5; // set duty cycle
                    redLED = 1 ;
                    if (button3Flag) {
                        buzzer = 0 ;
                        button3Flag=0;
                        goto exit ;
                    }
                }
            }
        }
        if (int(pressure) >= fsmH[3].output) {  //if the current pressure is greater than the set threshold

            while (1) {
                redLED = 0 ;
                strncpy(buffer0, bufferTime, 14);
                int display2 = sprintf (buffer1, "");
                int display0 = sprintf (buffer2, "Threshold");
                int display1 = sprintf (buffer3, "Reached!");
                int display4 = sprintf (buffer4, "%0.1f!",pressure);
                int display5 = sprintf (buffer5, "Stop");
                display();
                for (int i=0; i<=11; i++) {
                    buzzer.period(1/(frequency[i])); // set PWM period
                    buzzer=1; // set duty cycle
                    redLED = 1 ;
                    if (button3Flag) {
                        buzzer = 0 ;
                        button3Flag=0;
                        goto exit ;
                    }
                }
            }
        }
exit:
        redLED = 0 ;
    }

}

///Allows the user to set the minimum and maximum values of temperature and pressure for the thresholds
void threshold()
{
    state = 0;
    //sets the initial threshhold values to the values recieved from the sensor
    readData();
    fsmH[0].output = temperature-20;
    fsmH[1].output = temperature;
    fsmH[2].output = pressure-100;
    fsmH[3].output = pressure;

    while (1) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        loggerData();



        int display0 = sprintf (buffer0, " Back    Save");//convert integer to buffer str
        int display1 = sprintf (buffer1, "");//convert integer to buffer str
        int display2 = sprintf (buffer2, "");//convert integer to buffer str
        int display3 = sprintf (buffer3, ">>%s %d", fsmH[state].title,fsmH[state].output);//convert integer to buffer str
        int display4 = sprintf (buffer4, "");//convert integer to buffer str
        int display5 = sprintf (buffer5, "");//convert integer to buffer str


        display();



        if (button4Flag) {
            button4Flag= 0;
            fsmH[state].output ++;
        }




        //Navigates to the next5 state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmH[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmH[state].nextState[0];
        }


        //checks the limits of the values
        if (fsmH[0].output >(temperature*1.5)) { //min temperature
            fsmH[0].output = -(temperature*1.5) ;
        }
        if (fsmH[1].output>(temperature*1.5)) { // max temperature
            fsmH[1].output = -(temperature*1.5) ;
        }
        if (fsmH[2].output>(pressure*1.10)) { //min pressure
            fsmH[2].output = -(pressure*1.10) ;
        }
        if (fsmH[3].output>(pressure*1.10)) { //max pressure
            fsmH[3].output = -(pressure*1.10) ;
        }


        if (button3Flag) {//if wants to go back
            button3Flag=0;
            state = 0;
            while (1) { //runs a while loop
                int display0 = sprintf (buffer0, "");
                int display1 = sprintf (buffer1, "");
                int display2 = sprintf (buffer2, "Set Thresholds?"); //asks to set the threshold
                int display3 = sprintf (buffer3, ">>%s", fsmG[state].title); // yes or no (1 or 0 output)
                int display4 = sprintf (buffer4, "");
                int display5 = sprintf (buffer5, "");
                display();
                thresholdAlarmFlag = fsmG[state].output ; //yes or no (1 or 0)


                //Navigates to the next state of the fsm when one of the buttons is pressed
                if (button1Flag == 1) {
                    button1Flag=0;
                    state=fsmG[state].nextState[1];
                }
                if (button2Flag == 1) {
                    button2Flag=0;
                    state=fsmG[state].nextState[0];
                }



                if (button3Flag) {
                    //serial.printf("thresholds flag :%i \n",fsmG[state].output);
                    //serial.printf("thresholds: mint%i maxt%i minP%i maxP %i \n",fsmH[0].output,fsmH[1].output,fsmH[2].output,fsmH[3].output);
                    break;
                }
            }
        }
        if (button3Flag) {
            button3Flag=0;
            break ;
        }
    }
}





/// Compares the time set by the user in the alarm clock section with the current time, turn on the buzzer if they are equal
void alarmClockCheck()
{
    if (alarmClockFlag) {
        if (currentTime == UNIXdate) { //if the current time is equal to the time set by user
            //serial.printf("Alarm clock flag is set\n");
            alarmClockFlag =0 ;
            while (1) {
                int display0 = sprintf (buffer0, "");
                int display1 = sprintf (buffer1, "Alarm !");
                strncpy(buffer2, bufferTime, 14);
                int display2 = sprintf (buffer3, "");
                int display4 = sprintf (buffer4, "");
                int display5 = sprintf (buffer5, "Stop");
                display();
                for (int i=0; i<=11; i++) {
                    buzzer.period(1/(frequency[i])); // set PWM period
                    buzzer=0.5; // set duty cycle
                    wait(0.5); // hold for beat period
                    if (button3Flag) {
                        buzzer = 0 ;
                        lcd.setBrightness(0.5);
                        break;
                    }
                }
                if (button3Flag) {
                    button3Flag=0;
                    break;
                }

            }
        }
    }
}






/// Allows the user to set the time for the alarm clock
void alarmClock ()
{
    state = 0;
    while (1) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        loggerData();


        int display0 = sprintf (buffer0, " Back    Save");//convert integer to buffer str
        int display1 = sprintf (buffer1, "");//convert integer to buffer str
        int display2 = sprintf (buffer2, "" );//convert integer to buffer str
        int display3 = sprintf (buffer3, ">>%s %d", fsmC[state].title,fsmC[state].output);//convert integer to buffer str
        int display4 = sprintf (buffer4, "" );//convert integer to buffer str
        int display5 = sprintf (buffer5, "" );//convert integer to buffer str



        display();



        if (button4Flag) {
            button4Flag= 0;
            fsmC[state].output ++;
            calculateUNIXTime();
        }



//Navigates to the next5 state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmC[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmC[state].nextState[0];
        }



        //checks the limits of the values
        if (fsmC[0].output >23) { //hour
            fsmC[0].output = 0 ;
        }
        if (fsmC[1].output>59) { // minute
            fsmC[1].output = 0 ;
        }
        if (fsmC[3].output>11) { //month
            fsmC[3].output = 0 ;
        }
        if (fsmC[2].output>31) { //day
            fsmC[2].output = 1 ;
        }
        if (fsmC[4].output>2030) { //year
            fsmC[4].output = 2015 ;
        }



        if (button3Flag) {
            button3Flag=0;
            while (1) {
                int display0 = sprintf (buffer0, "");
                int display1 = sprintf (buffer1, "");
                int display2 = sprintf (buffer2, "Set Alarm?");
                int display3 = sprintf (buffer3, ">>%s", fsmG[state].title);
                int display4 = sprintf (buffer4, "");
                int display5 = sprintf (buffer5, "");
                display();
                alarmClockFlag = fsmG[state].output ;
                if (state>1) {
                    state = 0;
                }
                if (state<0) {
                    state = 1;
                }
                if (button3Flag) {
                    break ;
                }


                //Navigates to the next5 state of the fsm when one of the buttons is pressed
                if (button1Flag == 1) {
                    button1Flag=0;
                    state=fsmG[state].nextState[1];
                }
                if (button2Flag == 1) {
                    button2Flag=0;
                    state=fsmG[state].nextState[0];
                }
            }
        }
        if (button3Flag) {
            button3Flag=0;
            break ;
        }
    }
}




///A menu to indicate the alarm options (Alarm clock and thresholds alarm), also allows the user to navigate through the given options
void alarmsMenu ()
{
    state = 0 ;
    while (1) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        loggerData();
        int display0 = sprintf (buffer0, " Back    Next");
        int display1 = sprintf (buffer1, "");
        int display2 = sprintf (buffer2, "");
        int display3 = sprintf (buffer3, ">>%s", fsmF[state].title);
        int display4 = sprintf (buffer4, "");
        int display5 = sprintf (buffer5, "");

        display();



        if (state > 1) {
            state = 0 ;
        }
        if (state < 0) {
            state = 1 ;
        }
        if (button3Flag) {
            button3Flag=0;
            state = 0;
            break;
        }

        switch (state) {
            case 0: //thresholds

                if (button4Flag) {
                    button4Flag=0;
                    threshold();
                }
                break ;

            case 1 :
                if (button4Flag) {
                    button4Flag=0;
                    alarmClock();
                }
                break ;
                default:
                break;
        }

        //Navigates to the next state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmF[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmF[state].nextState[0];
        }
    }
}



/// Allows the user to turn on the data logger and set the time interval between the readings
void dataLoggerSetting()
{
    state = runLoggerFlag ; //inits the state to the saved flag by the user in the past
    while (1) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        loggerData();
        sprintf (buffer0, " Back    Save");
        sprintf (buffer1, "");
        sprintf (buffer2, "Data Logger");
        sprintf (buffer3, ">>%s", fsmE[state].title);
        if (state == 1) {
            sprintf (buffer4, "%i mins", fsmE[state].output/60);
        } else { // if the power saver is off it doesnt show the time
            sprintf (buffer4, "");
        }
        sprintf (buffer5, "");


        display();



        runLoggerFlag = state ; //sets the flag to the value of state (0 is off, 1 is on)
        dataLoggerTime = fsmE[state].output; //sets the timer to to value of output from the fsm
        // serial.printf("data logger Time = %i \n dataLoggerFlag = %i \n",dataLoggerTime , runLoggerFlag);

        if (button4Flag) {
            button4Flag=0;
            fsmE[state].output += 60 ; //adds a minute to the timer when button 4 is pressed
        }
        if (fsmE[state].output > 1800) {
            fsmE[state].output = 60 ;
        }

        if (state > 1) {
            state = 0 ;
        }

        if (button3Flag) {
            if (state == 1) { // if the data logger is swiched on
                dataLoggerTimer.attach(&dataLoggerTimerExpired, dataLoggerTime); // set the timer
            }
            if (state == 0) { // if the data logger is swiched off
                dataLoggerTimer.detach(); // detach the timer
            }
            dataLoggerFlag = 1;
            button3Flag=0;
            state = 0;
            break;
        }
        //Navigates to the next5 state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmE[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmE[state].nextState[0];
        }
    }

}











/// Allows the user to set the power saving option and set the timeout
void powerSaverSetting()
{

    state = powerSaverFlag ; //inits the state to the saved flag by the user in the past
    while (1) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        loggerData();
        sprintf (buffer0, " Back    Save");
        sprintf (buffer1, "");
        sprintf (buffer2, "Power Saver");
        sprintf (buffer3, ">>%s", fsmE[state].title);
        if (state == 1) {
            sprintf (buffer4, "%i mins", fsmE[state].output/60);
        } else { // if the power saver is off it dowsnt show the time
            sprintf (buffer4, "");
        }
        sprintf (buffer5, "");


        display();

        powerSaverTime = fsmE[state].output; //sets the timer to to value of output from the fsm
        //serial.printf("Power Saver Time = %i \n powerSaverFlag = %i \n",powerSaverTime , powerSaverFlag);

        if (button4Flag) {
            button4Flag=0;
            fsmE[state].output += 60 ; //adds a minute to the timer when button 4 is pressed
        }
        if (fsmE[state].output > 600) { // maximum time is 10 minutes
            fsmE[state].output = 60 ;
        }

        if (state > 1) {
            state = 0 ;
        }

        if (button3Flag) {
            button3Flag=0;

            if (state== 1) {
                powerSaverTimeout.attach(&powerSaverExpired, powerSaverTime); // setup a timeiut to call the savePower function
            }
            break;
        }


        //Navigates to the next5 state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmF[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmF[state].nextState[0];
        }
    }
}







/// Converts the entered raw date and time values by the user to create the unix time stamp
void calculateUNIXTime()
{

    time_t rawtime;
    struct tm * timeinfo;

    // get current timeinfo
    time ( &rawtime );
    // convert to struct
    timeinfo = localtime ( &rawtime );
    // now modify the timeinfo to the given date
    timeinfo->tm_year   = (fsmC[4].output) - 1900;
    timeinfo->tm_mon    = (fsmC[3].output) - 1;    //months since January - [0,11]
    timeinfo->tm_mday   = (fsmC[2].output) ;        //day of the month - [1,31]
    timeinfo->tm_hour   = (fsmC[0].output) ;        //hours since midnight - [0,23]
    timeinfo->tm_min    = (fsmC[1].output) ;         //minutes after the hour - [0,59]
    timeinfo->tm_sec    = 0 ;          //seconds after the minute - [0,59]

    //call mktime to create unix time stamp from timeinfo struct
    UNIXdate = mktime ( timeinfo );

}




/// Allows the user to change the units for temperature and pressure
void unitsSetting()
{
    state = 0;
    powerSaverCheck();
    while (1) {
        alarmClockCheck();
        updateTime();
        loggerData();

        sprintf (buffer0, " Back    Save");//convert integer to buffer str
        sprintf (buffer1, "");//convert integer to buffer str
        sprintf (buffer2, "");//convert integer to buffer str
        sprintf (buffer3, ">>%s", fsmD[state].title);//convert integer to buffer str
        sprintf (buffer4, "");//convert integer to buffer str
        sprintf (buffer5, "");//convert integer to buffer str


        unitFlag = fsmD[state].output;

        display();

        if (button3Flag) {
            button3Flag=0;
            state = 0;
            break;
        }

        //Navigates to the next5 state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmD[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmD[state].nextState[0];
        }
    }
}






/// Used by the user to set the current date and time
void timeDateSetting()
{

    state = 0;
    while (1) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        loggerData();

        sprintf (buffer0, " Back    Save");//convert integer to buffer str
        sprintf (buffer1, "");
        sprintf (buffer2, "");
        sprintf (buffer3, ">>%s %d", fsmC[state].title,fsmC[state].output);//convert integer to buffer str
        sprintf (buffer4, "");
        sprintf (buffer5, "");


        display();



        if (button4Flag) {
            button4Flag= 0;
            fsmC[state].output ++;
            calculateUNIXTime();
            set_time(UNIXdate); // initialise time from the calculated UNIX time entered by the user
        }


        //checks the limits of the values
        if (fsmC[0].output >23) { //hour
            fsmC[0].output = 0 ;
        }
        if (fsmC[1].output>59) { // minute
            fsmC[1].output = 0 ;
        }
        if (fsmC[3].output>11) { //month
            fsmC[3].output = 0 ;
        }
        if (fsmC[2].output>31) { //day
            fsmC[2].output = 1 ;
        }
        if (fsmC[4].output>2030) { //year
            fsmC[4].output = 2015 ;
        }



        if (button3Flag) {
            button3Flag=0;
            state = 0;
            break;
        }
        //Navigates to the next5 state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmC[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmC[state].nextState[0];
        }
    }
}


/// The settings menu allows user to change the settings
void settingsMenu()
{
    state = 0;
    while(button3Flag==0) {
        alarmClockCheck();
        powerSaverCheck();
        updateTime();
        loggerData();
        strncpy(buffer0, bufferTime, 14);
        int dispaly = sprintf (buffer1, "Settings");
        int dispaly1 = sprintf (buffer2, "");
        int dispaly2 = sprintf (buffer3, ">>%s", fsmB[state].title);//convert integer to buffer str
        int dispaly3 = sprintf (buffer4, "");
        int dispaly4 = sprintf (buffer5, "");

        display();


        switch (state) {
            case 0:
                if (button4Flag) {
                    button4Flag=0;
                    timeDateSetting();
                }


                break;
            case 1:


                if (button4Flag) {
                    button4Flag=0;
                    unitsSetting();
                }

                break;
            case 2:

                if (button4Flag) {
                    button4Flag = 0;
                    powerSaverSetting();
                }
                break;
            case 3:
                if (button4Flag) {
                    button4Flag = 0;
                    dataLoggerSetting();
                }
                break;
            default:
                break;
        }
        // if (button3Flag) {
//            button3Flag=0;
//            state = 0;
//            break;
//        }
        //Navigates to the next5 state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmB[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmB[state].nextState[0];
        }
    }
}

/// The first main menu
void startMenu()
{
    while(1) {
        updateTime();
        alarmClockCheck();
        powerSaverCheck();
        loggerData();
        button3Flag=0;
        strncpy(buffer0, bufferTime, 14);
        sprintf (buffer1, "Main Menu");
        sprintf (buffer2, "");
        sprintf (buffer3, ">>%s", fsmA[state].title);
        sprintf (buffer4, "");
        sprintf (buffer5, "");
        display();


        switch (state) {
            case 0:
                if (button4Flag) {
                    button4Flag=0;
                    liveData();
                }
                break;
            case 1:
                if (button4Flag) {
                    button4Flag=0;
                    dataLogger();
                }
                break;
            case 2:
                if (button4Flag) {
                    button4Flag=0;
                    alarmsMenu();
                }
                break;
            case 3:
                if (button4Flag) {
                    button4Flag=0;
                    settingsMenu();
                }
                break;
            default:
                break;
        }


        //Navigates to the next5 state of the fsm when one of the buttons is pressed
        if (button1Flag == 1) {
            button1Flag=0;
            state=fsmA[state].nextState[1];
        }
        if (button2Flag == 1) {
            button2Flag=0;
            state=fsmA[state].nextState[0];
        }

    }
}




int main()
{

    /// Initialise barometer
    bmp180.init();
    /// Initialise the lcd
    lcd.init();
    /// call the appropriate ISR on rising edge (when any of the buttons are pressed)
    button1.rise(&button1Pressed);
    button2.rise(&button2Pressed);
    button3.rise(&button3Pressed);
    button4.rise(&button4Pressed);
    debounce.start();
    /// Set frequency at 40kHz for the leds
    redLED.period_us(25);
    yellowLED.period_us(25);
    greenLED.period_us(25);
    state = 0;
    startMenu();
}