
Simple Weather Station. Data Logger and gives primitive weather predictions.
Dependencies: BMP180 N5110 PowerControl beep mbed
Revision 4:1fc40db4c19c, committed 2015-05-04
- Comitter:
- el13nsp
- Date:
- Mon May 04 21:20:17 2015 +0000
- Parent:
- 3:6a6b344f3fb0
- Child:
- 5:cae171557246
- Commit message:
- Data Logging and sleep mode added.
Changed in this revision
beep.lib | Show annotated file Show diff for this revision Revisions of this file |
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/beep.lib Mon May 04 21:20:17 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/dreschpe/code/beep/#d8e14429a95f
--- a/main.cpp Fri May 01 10:41:30 2015 +0000 +++ b/main.cpp Mon May 04 21:20:17 2015 +0000 @@ -1,6 +1,7 @@ #include "mbed.h" #include "N5110.h" #include "BMP180.h" +#include "beep.h" #include "PowerControl/PowerControl.h" #include "PowerControl/EthernetPowerControl.h" @@ -17,13 +18,42 @@ BMP180 bmp180(p28,p27); // SDA, SCL -BusOut leds(LED4,LED3,LED2,LED1); +BusOut leds(LED4,LED3,LED2,LED1); // on-boards LEDs for visual feedback + +LocalFileSystem local("local"); // create local filesystem AnalogIn POT1(p20); +DigitalIn logSwitch(p21); + +DigitalOut redled(p25); +DigitalOut greenled(p24); + +Beep buzzer(p22); + Ticker timer; +Ticker stateTimer; +Ticker alarmTimer; +Ticker writingTimer; +Ticker graphTimer; int timerFlag=0; +int stateTimerFlag=0; +int alarmTimerFlag=0; +int writingTimerFlag=0; +int graphTimerFlag=0; +int setTimeFlag = 0; // flag for ISR +int buttonAFlag = 0; //initialize flag A +int buttonBFlag = 0; //initialize flag B +int buttonCFlag = 0; //initialize flag C +int initFlag = 0; + +int alarm = 0; // Initially no alarm will sound; +int state = 0; // State for weather prediction +int prediction = 0; // Flag to see if prediction is possible or not +int i = 0; +int j = 0; +int unit = celcius; // Initially unit is celcius // Interrupt Service Routine void timerExpired() @@ -31,16 +61,37 @@ timerFlag = 1; } +void stateTimerExpired() +{ + stateTimerFlag = 1; +} + +void alarmTimerExpired() +{ + alarmTimerFlag = 1; +} + +void writingTimerExpired() +{ + writingTimerFlag = 1; +} +void graphTimerExpired() +{ + graphTimerFlag = 1; +} + InterruptIn buttonA(p15); InterruptIn buttonB(p18); +InterruptIn buttonC(p17); InterruptIn buttonD(p16); Serial serial(USBTX,USBRX); void serialISR(); // ISR that is called when serial data is received void setTime(); // function to set the UNIX time +void setState(); // Function that checks the state for weather prediction +void writeDataToFile(float temp,float press,char* time); -int setTimeFlag = 0; // flag for ISR char rxString[16]; // buffer to store received string for time // VCC,SCE,RST,D/C,MOSI,SCLK,LED @@ -48,14 +99,9 @@ // Can also power (VCC) directly from VOUT (3.3 V) - // Can give better performance due to current limitation from GPIO pin -int buttonAFlag = 0; //initialize flag A -int buttonBFlag = 0; //initialize flag B -int unit = celcius; // initially unit is celcius - float temparray[84]; //Array to hold temperature readings float pressarray[84]; //Array to hold pressure readings - -int i = 0; +float presscompare[12]; //Interrupt service routine void buttonAPressed() @@ -72,18 +118,40 @@ 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; } +void sunny(); +void cloudySun(); +void clouds(); +void rainy(); +void stormy(); + + + 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 @@ -92,8 +160,8 @@ PHY_PowerDown(); int result = semihost_powerdown(); - //buttonA.mode(PullUp); buttonB.mode(PullUp); + buttonC.mode(PullUp); buttonD.mode(PullUp); // initiliase barometer @@ -113,30 +181,100 @@ 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; + 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(potValue<0.1) { + + lcd.turnOff(); + Sleep(); + initFlag=1; + + } else if((initFlag == 1) && (potValue >= 0.1)) { + + initFlag = 0; + lcd.init(); + + } + + if(stateTimerFlag) { + + stateTimerFlag = 0; + + // read values (T in Celsius and P in mb) and print over serial port + measurement = bmp180.readValues(); + + if(j==12) { + for (int n = 0; n < 11; n++) { + presscompare[n] = presscompare[n+1]; + } + j=11; + } + + presscompare[j] = measurement.pressure; + j++; + + if( presscompare[11] == 0) { + prediction = 0; + } else + prediction = 1; + + pressureChange = presscompare[11] - presscompare[0]; + + 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; + + if((state == 8) && (prediction == 1)) + alarm = 1; + else + alarm = 0; + + } if(timerFlag) { timerFlag = 0; + // read values (T in Celsius and P in mb) and print over serial port + measurement = bmp180.readValues(); + lcd.clear(); // clear display - 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 leds = 0; - // read values (T in Celsius and P in mb) and print over serial port - measurement = bmp180.readValues(); - if(unit == celcius) { int length = sprintf(buffer,"T = %.2f C",measurement.temperature); // print formatted data to buffer @@ -164,23 +302,58 @@ } 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)); - + + //int test = 3 -20; + //sprintf(buffer,"%d",test); // print formatted data to buffer + //lcd.printString(buffer,0,3); + // 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(alarmTimerFlag) { + alarmTimerFlag = 0; + + if(alarm==1) { + buzzer.beep(1000,0.5); + redled = 1; + } else + redled =0; + + } + + if(writingTimerFlag) { + + writingTimerFlag = 0; + + // read values (T in Celsius and P in mb) and print over serial port + measurement = bmp180.readValues(); + + if(logSwitch) { + writeDataToFile(measurement.temperature, measurement.pressure, timebuffer); // write current value to disk + } + + } + + if(graphTimerFlag) { + + graphTimerFlag = 0; + if(i==84) { for (int n = 0; n < 83; n++) { temparray[n] = temparray[n+1]; @@ -190,13 +363,14 @@ } temparray[i] = measurement.temperature/65; - pressarray[i] = (measurement.pressure-950)/100; + pressarray[i] = (measurement.pressure-975)/50; i++; } if (buttonAFlag) { // if flag A is set - lcd.clear(); // clear display + lcd.clear(); + lcd.printString("T",0,0); lcd.plotArray(temparray); lcd.refresh(); wait(5.0); @@ -204,24 +378,97 @@ } if (buttonBFlag) { // if flag B is set - lcd.clear(); // clear display + lcd.clear(); + lcd.printString("P",0,0); lcd.plotArray(pressarray); lcd.refresh(); wait(5.0); buttonBFlag = 0; //reset flag } - + + if(buttonCFlag) { // if flag C is set + + lcd.clear(); + //prediction = 1; + if(prediction == 0) { + + lcd.printString("PREDICTION",10,1); + lcd.printString("UNAVAILABLE",8,2); + lcd.printString("INSUFFICIENT",5,4); + lcd.printString("DATA",28,5); + + } else { + setState(); + } + + lcd.refresh(); + + wait(5.0); + + buttonCFlag = 0; + } + if (setTimeFlag) { // if updated time has been sent setTimeFlag = 0; // clear flag setTime(); // update time } + } +} - // can also check status of pixels using getPixel(x,y) +void setState() +{ + + switch(state) { - //wait(1.0); + 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; } + } void setTime() @@ -240,4 +487,128 @@ serial.gets(rxString,16); // set flag setTimeFlag = 1; -} \ No newline at end of file +} + +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); + +} + +void writeDataToFile(float temp,float press,char* time) +{ + 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 +} + +//Need to add weather predictions, weather warning, data logging and other power saving features \ No newline at end of file