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
Diff: Barometer.cpp
- 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(); +} + + +