Simple Weather Station. Data Logger and gives primitive weather predictions.
Dependencies: BMP180 N5110 PowerControl beep mbed
main.cpp
- Committer:
- el13nsp
- Date:
- 2015-05-11
- Revision:
- 7:b92507a1a1e5
- Parent:
- 6:7271c1e8e348
File content as of revision 7:b92507a1a1e5:
/** @file main.cpp @brief Program implementation */ #include "main.h" // Interrupt Service Routine void timerExpired() { timerFlag = 1; } void stateTimerExpired() { stateTimerFlag = 1; } void alarmTimerExpired() { alarmTimerFlag = 1; } void writingTimerExpired() { writingTimerFlag = 1; } void graphTimerExpired() { graphTimerFlag = 1; } void buttonAPressed() { leds = 15; wait(1.0); buttonAFlag = 1; //set flag } void buttonBPressed() { leds = 15; wait(1.0); buttonBFlag = 1; //set flag } void buttonCPressed() { leds = 15; wait(1.0); buttonCFlag = 1; //set flag } void buttonDPressed() //Toggle unit in ISR { leds = 15; unit = !unit; // unti switches between celsius and fahrenheit and mb and hpa } int main() { leds = 15; timer.attach(&timerExpired,2.0); // Call ISR every 2 seconds stateTimer.attach(&stateTimerExpired,300.0); // Call ISR every 5 minutes alarmTimer.attach(&alarmTimerExpired,10.0); // Call ISR every 10 seconds writingTimer.attach(&writingTimerExpired,1800.0); // Call ISR every 30 minutes graphTimer.attach(&graphTimerExpired,600.0); // Call ISR every 10 minutes serial.attach(&serialISR); // attach serial ISR char timebuffer[30]; // buffer used to store time string char datebuffer[30]; // buffer used to store time string //set_time(0); // initialise time to 1st January 1970 PHY_PowerDown(); //int result = semihost_powerdown(); //Sets button to pull up mode buttonB.mode(PullUp); buttonC.mode(PullUp); buttonD.mode(PullUp); // initiliase barometer bmp180.init(); // first need to initialise display lcd.init(); // these are default settings so not strictly needed lcd.normalMode(); // normal colour mode lcd.setBrightness(0.5); // put LED backlight on full lcd.printString("ELEC 2645",15,0); lcd.printString("WeatherStation",1,2); lcd.printString("Nikhil Pillai",1,4); lcd.printString("200800623",15,5); wait(5.0); leds = 0; buttonA.rise(&buttonAPressed); // event generated on rising edge buttonB.rise(&buttonBPressed); // event generated on rising edge buttonC.rise(&buttonCPressed); // event generated on rising edge buttonD.rise(&buttonDPressed); // event generated on rising edge Measurement measurement; // measurement structure declared in BMP180 class float pressureChange = 0; // Initializes the pressure change variable to 0 while(1) { lcd.setBrightness(POT1); // put LED backlight on full float potValue = POT1; char buffer[14]; // each character is 6 pixels wide, screen is 84 pixels (84/6 = 14) // so can display a string of a maximum 14 characters in length //If-else statement to switch the LCD ON or OFF based on potentiometer value if(potValue<0.1) { lcd.turnOff(); Sleep(); initFlag=1; } else if((initFlag == 1) && (potValue >= 0.1)) { initFlag = 0; lcd.init(); } //If state timer flag is set if(stateTimerFlag) { stateTimerFlag = 0; //reset flag // read values (T in Celsius and P in mb) and print over serial port measurement = bmp180.readValues(); //Sets pressure reading in an array to compare over the hour if(j==12) { for (int n = 0; n < 11; n++) { presscompare[n] = presscompare[n+1]; } j=11; } presscompare[j] = measurement.pressure; j++; //If-else statement to check if prediction is possible or not if( presscompare[11] == 0) { prediction = 0; } else prediction = 1; pressureChange = presscompare[11] - presscompare[0]; //Gets pressure change over the hour //If-else if statements to set the state based on pressure change if((pressureChange < 0.1) && (pressureChange > -0.1)) state = 0; else if((pressureChange > 0.1) && (pressureChange <= 0.5)) state = 1; else if((pressureChange > 0.5) && (pressureChange <= 1.17)) state = 2; else if((pressureChange > 1.17) && (pressureChange <= 2.0)) state = 3; else if(pressureChange > 2.0) state = 4; else if((pressureChange < -0.1) && (pressureChange >= -0.5)) state = 5; else if((pressureChange < -0.5) && (pressureChange >= -1.17)) state = 6; else if((pressureChange < -1.17) && (pressureChange >= -2.0)) state = 7; else if(pressureChange < -2.0) state = 8; //Turns alarm ON if weather prediction is stormy if((state == 8) && (prediction == 1)) alarm = 1; else alarm = 0; } //If timer flag is set if(timerFlag) { timerFlag = 0; //reset flag // read values (T in Celsius and P in mb) and print over serial port measurement = bmp180.readValues(); lcd.clear(); // clear display leds = 0; if(unit == celcius) { //If unit is celcius int length = sprintf(buffer,"T = %.2f C",measurement.temperature); // print formatted data to buffer // it is important the format specifier ensures the length will fit in the buffer if (length <= 14) // if string will fit on display lcd.printString(buffer,0,1); // display on screen length = sprintf(buffer,"P = %.2f mb",measurement.pressure); // print formatted data to buffer if (length <= 14) lcd.printString(buffer,0,2); // display on screen } else if(unit == fahrenheit) { //If unit is fahrenheit int length = sprintf(buffer,"T = %.2f F",(((measurement.temperature*9)/5)+32)); // print formatted data to buffer // it is important the format specifier ensures the length will fit in the buffer if (length <= 14) // if string will fit on display lcd.printString(buffer,0,1); // display on screen length = sprintf(buffer,"P = %.1f hpa",measurement.pressure); // print formatted data to buffer if (length <= 14) lcd.printString(buffer,0,2); // display on screen } time_t seconds = time(NULL); // get current time // format time into a string (time and date) strftime(timebuffer, 14 , "%T", localtime(&seconds)); strftime(datebuffer, 14 , "%D", localtime(&seconds)); // Display on LCD lcd.printString(timebuffer,20,4); lcd.printString(datebuffer,20,5); // need to refresh display after setting pixels lcd.refresh(); // format time into a string (time and date) strftime(buffer, 30 , "%X %D", localtime(&seconds)); strftime(timebuffer, 30 , "%X %D", localtime(&seconds)); // print over serial serial.printf("Time = %s\n",buffer); } //If alarm timer flag is set if(alarmTimerFlag) { alarmTimerFlag = 0; //reset flag if(alarm==1) { //If alarm is set buzzer.beep(1000,0.5); // Buzzer beeps redled = 1; // Red led is turned ON } else redled =0; //Red led is turned OFF } //If writing timer flag is set if(writingTimerFlag) { writingTimerFlag = 0; //reset flag // read values (T in Celsius and P in mb) and print over serial port measurement = bmp180.readValues(); if(logSwitch) { // If data logging switch is turned ON writeDataToFile(measurement.temperature, measurement.pressure, timebuffer); // write current value to disk } } //If graph timer flag is set if(graphTimerFlag) { graphTimerFlag = 0; // reset flag //Sets temperature and pressure reading into arrays to display as graphs if(i==84) { for (int n = 0; n < 83; n++) { temparray[n] = temparray[n+1]; pressarray[n] = pressarray[n+1]; } i=83; } temparray[i] = measurement.temperature/65; pressarray[i] = (measurement.pressure-975)/50; i++; } if (buttonAFlag) { // if flag A is set lcd.clear(); lcd.printString("T",0,0); lcd.plotArray(temparray); // Display graph of temperature lcd.refresh(); wait(5.0); buttonAFlag = 0; //reset flag } if (buttonBFlag) { // if flag B is set lcd.clear(); lcd.printString("P",0,0); lcd.plotArray(pressarray); // Display graph if pressure lcd.refresh(); wait(5.0); buttonBFlag = 0; //reset flag } if(buttonCFlag) { // if flag C is set lcd.clear(); if(prediction == 0) { // If prediction is not possible lcd.printString("PREDICTION",10,1); lcd.printString("UNAVAILABLE",8,2); lcd.printString("INSUFFICIENT",5,4); lcd.printString("DATA",28,5); } else { setState(); //Calls function to give prediciton } lcd.refresh(); wait(5.0); buttonCFlag = 0; // reset flag } if (setTimeFlag) { // if updated time has been sent setTimeFlag = 0; // clear flag setTime(); // update time } } } //Function to display weather prediction void setState() { switch(state) { // Displays prediction based on state case 0: cloudySun(); lcd.printString("BeaufortNumber",0,4); lcd.printString("< 4",0,5); break; case 1: sunny(); lcd.printString("BeaufortNumber",0,4); lcd.printString("< 4",0,5); break; case 2: sunny(); lcd.printString("BeaufortNumber",0,4); lcd.printString("4-5",0,5); break; case 3: sunny(); lcd.printString("BeaufortNumber",0,4); lcd.printString("5-7",0,5); break; case 4: sunny(); lcd.printString("BeaufortNumber",0,4); lcd.printString("> 6",0,5); break; case 5: cloudySun(); lcd.printString("BeaufortNumber",0,4); lcd.printString("< 4",0,5); break; case 6: clouds(); lcd.printString("BeaufortNumber",0,4); lcd.printString("4-5",0,5); break; case 7: rainy(); lcd.printString("BeaufortNumber",0,4); lcd.printString("5-7",0,5); break; case 8: stormy(); lcd.printString("BeaufortNumber",0,4); lcd.printString("> 6",0,5); break; } } //Function for setting RTC void setTime() { // print time for debugging serial.printf("set_time - %s",rxString); // atoi() converts a string to an integer int time = atoi(rxString); // update the time set_time(time); } void serialISR() { // when a serial interrupt occurs, read rx string into buffer serial.gets(rxString,16); // set flag setTimeFlag = 1; } void writeDataToFile(float temp,float press,char* time) // Function for logging data into a csv file { greenled = 1; // turn on LEDs for feedback FILE *fp = fopen("/local/Datalog.csv", "a"); // open 'log.txt' for appending // if the file doesn't exist it is created, if it exists, data is appended to the end fprintf(fp,"T = %f C, P = %f mb, Time = %s\n",temp, press, time); // print string to file fclose(fp); // close file greenled = 0; // turn off LEDs to signify file access has finished } //Functions to set pixels for displaying various weather predictions void sunny() { lcd.drawCircle(WIDTH/2,(HEIGHT/2)-10,8,0); // x,y,radius,white fill lcd.drawLine(42,1,42,4,1); lcd.drawLine(42,24,42,27,1); lcd.drawLine(29,14,32,14,1); lcd.drawLine(52,14,55,14,1); lcd.drawLine(32,4,35,7,1); lcd.drawLine(52,4,49,7,1); lcd.drawLine(32,24,35,21,1); lcd.drawLine(52,24,49,21,1); } void clouds() { lcd.drawLine(29,14,55,14,1); lcd.setPixel(28,13); lcd.setPixel(27,12); lcd.setPixel(27,11); lcd.setPixel(28,10); lcd.setPixel(29,9); lcd.setPixel(30,9); lcd.setPixel(31,10); lcd.setPixel(29,8); lcd.setPixel(29,7); lcd.setPixel(29,6); lcd.setPixel(30,5); lcd.setPixel(31,4); lcd.setPixel(32,3); lcd.setPixel(33,2); lcd.setPixel(34,2); lcd.setPixel(35,1); lcd.setPixel(36,1); lcd.setPixel(37,1); lcd.setPixel(38,1); lcd.setPixel(39,1); lcd.setPixel(40,2); lcd.setPixel(41,3); lcd.setPixel(41,4); lcd.setPixel(42,5); lcd.setPixel(42,6); lcd.setPixel(42,7); lcd.setPixel(43,6); lcd.setPixel(44,6); lcd.setPixel(45,7); lcd.setPixel(45,8); lcd.setPixel(45,9); lcd.setPixel(45,10); lcd.setPixel(46,9); lcd.setPixel(47,8); lcd.setPixel(48,8); lcd.setPixel(49,8); lcd.setPixel(50,8); lcd.setPixel(51,9); lcd.setPixel(52,9); lcd.setPixel(53,10); lcd.setPixel(54,11); lcd.setPixel(54,12); lcd.setPixel(54,13); } void rainy() { clouds(); lcd.drawLine(37,19,32,24,1); lcd.drawLine(42,19,37,24,1); lcd.drawLine(47,19,42,24,1); } void stormy() { clouds(); lcd.drawLine(38,16,45,16,1); lcd.drawLine(38,16,36,18,1); lcd.drawLine(36,18,41,23,1); lcd.setPixel(40,24); lcd.drawLine(40,25,39,26,1); lcd.drawLine(45,16,42,19,1); lcd.drawLine(42,19,44,21,1); lcd.drawLine(44,21,41,24,1); } void cloudySun() { clouds(); lcd.setPixel(27,13); lcd.setPixel(26,13); lcd.setPixel(25,12); lcd.setPixel(24,11); lcd.setPixel(24,10); lcd.setPixel(24,9); lcd.setPixel(24,8); lcd.setPixel(25,7); lcd.setPixel(26,6); lcd.setPixel(27,5); lcd.setPixel(28,5); lcd.setPixel(29,5); lcd.drawLine(28,3,28,1,1); lcd.drawLine(24,5,22,3,1); lcd.drawLine(22,9,20,9,1); lcd.drawLine(23,13,21,15,1); lcd.drawLine(28,15,28,17,1); }