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

Revision:
23:a0ce9fa869c2
Child:
24:51cbed3fbf5c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Barometer.cpp	Sat May 09 01:08:16 2015 +0000
@@ -0,0 +1,1322 @@
+/**
+@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));
+    if (alarmClockFlag == 1 ) { // if the the alarm clock flag is set by the user
+        alarmClockCheck();
+    }
+}
+
+
+/// 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
+    }
+
+    if (thresholdAlarmFlag == 1) { // if the flag is set by the user to notify the thresholds
+        serial.printf("thresholds flag checked = 1\n");
+        serial.printf("real values: t %i p %f \n",temperature,pressure);
+        serial.printf("thresholds: mint%i maxt%i minP%i maxP %i \n",fsmH[0].output,fsmH[1].output,fsmH[2].output,fsmH[3].output);
+        thresholdCheck();
+    }
+
+}
+
+
+
+
+/// 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) {
+            thresholdCheck();
+            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) {
+        thresholdCheck();
+        alarmClockCheck();
+        powerSaverCheck();
+        updateTime();
+        loggerData();
+        if (timerFlag) {
+
+            yellowLED = 1;
+            timerFlag=0;
+            readData();
+            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();
+
+        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) {
+        thresholdCheck();
+        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;
+        }
+    }
+}
+
+
+
+/// 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;
+    fsmH[1].output = temperature;
+    fsmH[2].output = pressure;
+    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*2)) { //min temperature
+            fsmH[0].output = -(temperature*2) ;
+        }
+        if (fsmH[1].output>(temperature*2)) { // max temperature
+            fsmH[1].output = -(temperature*2) ;
+        }
+        if (fsmH[2].output>(pressure*2)) { //min pressure
+            fsmH[2].output = -(pressure*2) ;
+        }
+        if (fsmH[3].output>(pressure*2)) { //max pressure
+            fsmH[3].output = -(pressure*2) ;
+        }
+
+
+        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) {
+                    button3Flag=0;
+                    //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);
+                    goto exit;
+                }
+            }
+        }
+    }
+exit:
+    return;
+}
+
+
+
+
+
+/// 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) {
+        thresholdCheck();
+        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) {
+                    button3Flag=0;
+                    goto exit;
+                }
+
+
+                //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];
+                }
+            }
+        }
+    }
+exit:
+    return;
+}
+
+
+
+
+///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) {
+        thresholdCheck();
+        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;
+        }
+        if (button4Flag) {
+            if (state == 0) { // temp and pressure thresholds
+                threshold();
+            }
+            if (state == 1) {// alarm clock
+
+                alarmClock();
+            }
+        }
+        //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];
+        }
+    }
+}
+
+
+
+/// 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) {
+        thresholdCheck();
+        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) {
+        thresholdCheck();
+        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) {
+        thresholdCheck();
+        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) {
+        thresholdCheck();
+        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) {
+
+        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();
+        thresholdCheck();
+        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();
+}
+
+
+