Simple Weather Station. Data Logger and gives primitive weather predictions.

Dependencies:   BMP180 N5110 PowerControl beep mbed

Files at this revision

API Documentation at this revision

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