Weather application for ECE4180 Project.

Dependencies:   NetServices mbed HTTPClient 4DGL-uLCD-SE spxml

Files at this revision

API Documentation at this revision

Comitter:
franceslee0518
Date:
Fri Dec 07 18:54:26 2018 +0000
Parent:
0:4a917644acc4
Commit message:
iWeather (Frances, Sherry)

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
HTTPClient.lib Show annotated file Show diff for this revision Revisions of this file
emic2.h 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/4DGL-uLCD-SE.lib	Fri Dec 07 18:54:26 2018 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
--- a/HTTPClient.lib	Fri May 25 00:57:24 2012 +0000
+++ b/HTTPClient.lib	Fri Dec 07 18:54:26 2018 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/donatien/code/HTTPClient/#d0be6af2d1db
+https://os.mbed.com/users/mamezu/code/HTTPClient/#62fac7f06c8d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emic2.h	Fri Dec 07 18:54:26 2018 +0000
@@ -0,0 +1,41 @@
+#define speakf printf
+class emic2 : public Stream
+{
+public :
+    emic2(PinName tx, PinName rx): _cmd(tx,rx) {
+        _cmd.baud(9600);
+        _cmd.putc('X'); //stop talking if reset and not a power on
+        _cmd.putc('\r'); // Send a CR in case the system is already up
+        wait(1); //delay for emic power on boot or reset respone
+        while (_cmd.getc() != ':');   // When the Emic 2 has initialized and is ready, it will send a single ':'
+        while (_cmd.readable()) _cmd.getc();//flush out buffer just in case
+    };
+    void ready() {
+        while (_cmd.getc() != ':');
+        while (_cmd.readable()) _cmd.getc();//flush out recieve buffer just in case
+    };
+    int readable() {
+        return _cmd.readable();
+    };
+    int getc() {
+        return _cmd.getc();
+    }
+    void volume(int x) {
+        speakf("V%D\r",x);
+        ready();
+    }
+    void voice(int x) {
+        speakf("N%D\r",x);
+        ready();
+    }
+protected :
+    Serial     _cmd;
+    //used by printf - supply it and printf works!
+    virtual int _putc(int c) {
+        _cmd.putc(c);
+        return 0;
+    };
+    virtual int _getc() {
+        return -1;
+    };
+};
--- a/main.cpp	Fri May 25 00:57:24 2012 +0000
+++ b/main.cpp	Fri Dec 07 18:54:26 2018 +0000
@@ -4,11 +4,12 @@
 #include "spdomparser.hpp"
 #include "spxmlnode.hpp"
 #include "spxmlhandle.hpp"
-#include "NokiaLCD.h"
-// Internet of Things weather display example: LCD displays LA current weather via internet Google API
-// Adapted for LCD from http://mbed.org/users/hlipka/programs/spxmltest_weather/lif782
+#include "uLCD_4DGL.h"
+#include "emic2.h"
+#define speakf printf
 
-NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type
+uLCD_4DGL lcd(p9,p10,p11); 
+emic2 myTTS(p13, p14);
 EthernetNetIf eth;
 HTTPClient http;
 HTTPResult result;
@@ -18,32 +19,110 @@
     completed = true;
 }
 
-void parseWeather(SP_XmlElementNode *node) {
-    //extracts current weather XML data fields for LCD
-    SP_XmlHandle handle(node);
-    SP_XmlElementNode * condition = handle.getChild( "condition" ).toElement();
+// RGB Setup
+class LEDColor
+{
+public:
+    LEDColor(float r, float g, float b);
+    float red;
+    float green;
+    float blue;
+};
+LEDColor:: LEDColor(float r, float g, float b)
+    : red(r), green(g), blue(b)
+{
+}
+//Operator overload to adjust brightness with no color change
+LEDColor operator * (const LEDColor& x, const float& b)
+{
+    return LEDColor(x.red*b,x.green*b,x.blue*b);
+}
+//Operator overload to add colors
+LEDColor operator + (const LEDColor& x, const LEDColor& y)
+{
+    return LEDColor(x.red+y.red,x.green+y.green,x.blue+y.blue);
+}
+
+//Class to control an RGB LED using three PWM pins
+class RGBLed
+{
+public:
+    RGBLed(PinName redpin, PinName greenpin, PinName bluepin);
+    void write(float red,float green, float blue);
+    void write(LEDColor c);
+    RGBLed operator = (LEDColor c) {
+        write(c);
+        return *this;
+    };
+private:
+    PwmOut _redpin;
+    PwmOut _greenpin;
+    PwmOut _bluepin;
+};
+
+RGBLed::RGBLed (PinName redpin, PinName greenpin, PinName bluepin)
+    : _redpin(redpin), _greenpin(greenpin), _bluepin(bluepin)
+{
+    //50Hz PWM clock default a bit too low, go to 2000Hz (less flicker)
+    _redpin.period(0.0005);
+}
+
+void RGBLed::write(float red,float green, float blue)
+{
+    _redpin = red;
+    _greenpin = green;
+    _bluepin = blue;
+}
+void RGBLed::write(LEDColor c)
+{
+    _redpin = c.red;
+    _greenpin = c.green;
+    _bluepin = c.blue;
+}
+
+
+RGBLed myRGBled(p23,p22,p21);
+const LEDColor blue(0.0,0.0,1.0);
+const LEDColor yellow(0.2,1.0,0.0);
+//Setup a new class for TMP36 sensor
+class TMP36
+{
+public:
+    TMP36(PinName pin);
+    TMP36();
+    operator float ();
+    float read();
+private:
+//class sets up the AnalogIn pin
+    AnalogIn _pin;
+};
+
+TMP36::TMP36(PinName pin) : _pin(pin)
+{
+// _pin(pin) means pass pin to the AnalogIn constructor
+}
+
+float TMP36::read()
+{
+//convert sensor reading to temperature in degrees C
+    return ((_pin.read()*3.3)-0.500)*100.0;
+}
+//overload of float conversion (avoids needing to type .read() in equations)
+TMP36::operator float ()
+{
+//convert sensor reading to temperature in degrees C
+    return ((_pin.read()*3.3)-0.500)*100.0;
+}
+
+//use the new class to set p15 to analog input to read and convert TMP36 sensor's voltage output
+TMP36 myTMP36(p15);
+
+int main() {
+    lcd.background_color(WHITE);
+    lcd.textbackground_color(WHITE);
     lcd.cls();
     lcd.locate(0,2);
-    lcd.printf("LA:");
-    if (condition) {
-        lcd.printf("%s ",condition->getAttrValue("data"));
-    }
-    SP_XmlElementNode * tempf = handle.getChild( "temp_f" ).toElement();
-    if (tempf) {
-        lcd.printf(" %sF",tempf->getAttrValue("data"));
-    }
-    SP_XmlElementNode * humidity = handle.getChild( "humidity" ).toElement();
-    if (humidity) {
-        lcd.locate(0,3);
-        lcd.printf("%s",humidity->getAttrValue("data"));
-    }
-}
-
-int main() {
-    // the eth and HTTP code has be taken directly from the HTTPStream documentation page
-    // see http://mbed.org/cookbook/HTTP-Client-Data-Containers
-    lcd.cls();
-    lcd.locate(0,2);
+    lcd.color(BLACK);
     lcd.printf("net setup");
     lcd.locate(0,3);
     EthernetErr ethErr = eth.setup();
@@ -57,15 +136,14 @@
     HTTPStream stream;
 
     char BigBuf[512 + 1] = {0};
-    stream.readNext((byte*)BigBuf, 512); //Point to buffer for the first read
-    //Google Weather API for Los Angeles - get web page with XML
-    HTTPResult r = http.get("http://www.google.com/ig/api?weather=Los+Angeles", &stream, request_callback);
+    stream.readNext((byte*)BigBuf, 512);
+    HTTPResult r = http.get("http://api.openweathermap.org/data/2.5/weather?q=Atlanta,us&appid=8df1acdaba0957258c46ced41ce2eedc&mode=xml", &stream, request_callback);
     while (!completed) {
-        Net::poll(); //Polls the Networking stack
+        Net::poll(); 
         if (stream.readable()) {
-            BigBuf[stream.readLen()] = 0; //Transform this buffer in a zero-terminated char* string
-            parser.append( BigBuf, strlen(BigBuf)); // stream current buffer data to the XML parser
-            stream.readNext((byte*)BigBuf, 512); //Buffer has been read, now we can put more data in it
+            BigBuf[stream.readLen()] = 0; 
+            parser.append( BigBuf, strlen(BigBuf)); 
+            stream.readNext((byte*)BigBuf, 512); 
         }
     }
     lcd.cls();
@@ -73,18 +151,70 @@
     if (result == HTTP_OK) {
         lcd.printf(" Read complete");
     } else {
-        lcd. printf(" Error %d", result);
+        lcd.printf(" Error %d", http.getHTTPResponseCode());
         return -1;
     }
 
     SP_XmlHandle rootHandle( parser.getDocument()->getRootElement() );
-    SP_XmlElementNode * child2 = rootHandle.getChild( "weather" )
-                                 .getChild( "current_conditions").toElement();
-    if ( child2 ) {
-        parseWeather(child2); //parses XML "current-conditions" info
+    //temp
+    SP_XmlElementNode * temp = rootHandle.getChild(1).toElement();
+    lcd.cls();
+    lcd.locate(0,1);
+    lcd.text_bold(ON);
+    lcd.text_char('A', 0, 1, BLACK);
+    lcd.text_bold(ON);
+    lcd.text_char('T', 1, 1, BLACK);
+    lcd.text_bold(ON);
+    lcd.text_char('L', 2, 1, BLACK);
+    lcd.locate(0,2);
+    float mytmp = myTMP36/10;
+    lcd.printf("Indoor Temp: %5.1FC", mytmp);
+    lcd.locate(0,3);
+    //temperature
+    float temperature = atof(temp->getAttrValue("value"))-273.15;
+    lcd.printf("Outdoor Temp: %.1f C ", temperature );
+    //humidity
+    SP_XmlElementNode * humidity = rootHandle.getChild(2).toElement();
+    lcd.locate(0,5);
+    string humid = humidity->getAttrValue("value");
+    lcd.printf("Humidity: %s%% ", humid);
+    //condition
+    SP_XmlElementNode * condition = rootHandle.getChild(8).toElement();
+    string cond = condition->getAttrValue("value");
+    //wind
+    lcd.locate(0,7);
+    SP_XmlElementNode * wind = rootHandle.getChild(4).getChild(0).toElement();
+    string windy = wind->getAttrValue("name");
+    lcd.printf("Weather: %s & %s ", cond, windy);
+    //rain
+    SP_XmlElementNode * rain = rootHandle.getChild(7).toElement();
+    string rainy = rain->getAttrValue("mode");
+    
+    // RGB: Blue if raining, yellow if not raining
+    if (rainy.compare("yes")) {
+        myRGBled = blue; //blue
+    } else if (rainy.compare("no")) {
+        myRGBled = yellow; //yellow
     }
-
-    if ( NULL != parser.getError() ) {
-        lcd.printf( "\n error: %s\n", parser.getError() );
+    
+    myTTS.volume(10);
+    myTTS.voice(6);
+    myTTS.speakf("SThe current indoor temperature is %5.2f degrees. The current outdoor temperature is %.2f degrees with %s percent humidity. Currently the weather condition is %s with %s\r", mytmp, temperature, humid, cond, windy);
+    myTTS.ready();
+    if (temperature < 15.0) {
+        myTTS.speakf("SBring a jacket with you\r");
+        myTTS.ready();
+    } else if(temperature > 25.0) {
+        myTTS.speakf("SIt's hot outside, bring water with you\r");
+        myTTS.ready();
+    } else {
+        myTTS.speakf("SThe temperature is pleasant outside\r");
+        myTTS.ready();
     }
+    if (rainy == "yes") {
+        myTTS.speakf("SBring your rain gear with you. It is currently raining outside.\r");
+        myTTS.ready();
+    }
+    
+    myRGBled.write(0.0, 0.0, 0.0);
 }