Weather application for ECE4180 Project.

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

Committer:
franceslee0518
Date:
Fri Dec 07 18:54:26 2018 +0000
Revision:
1:6f7f146715e4
Parent:
0:4a917644acc4
iWeather (Frances, Sherry)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
4180_1 0:4a917644acc4 1 #include "mbed.h"
4180_1 0:4a917644acc4 2 #include "EthernetNetIf.h"
4180_1 0:4a917644acc4 3 #include "HTTPClient.h"
4180_1 0:4a917644acc4 4 #include "spdomparser.hpp"
4180_1 0:4a917644acc4 5 #include "spxmlnode.hpp"
4180_1 0:4a917644acc4 6 #include "spxmlhandle.hpp"
franceslee0518 1:6f7f146715e4 7 #include "uLCD_4DGL.h"
franceslee0518 1:6f7f146715e4 8 #include "emic2.h"
franceslee0518 1:6f7f146715e4 9 #define speakf printf
4180_1 0:4a917644acc4 10
franceslee0518 1:6f7f146715e4 11 uLCD_4DGL lcd(p9,p10,p11);
franceslee0518 1:6f7f146715e4 12 emic2 myTTS(p13, p14);
4180_1 0:4a917644acc4 13 EthernetNetIf eth;
4180_1 0:4a917644acc4 14 HTTPClient http;
4180_1 0:4a917644acc4 15 HTTPResult result;
4180_1 0:4a917644acc4 16 bool completed = false;
4180_1 0:4a917644acc4 17 void request_callback(HTTPResult r) {
4180_1 0:4a917644acc4 18 result = r;
4180_1 0:4a917644acc4 19 completed = true;
4180_1 0:4a917644acc4 20 }
4180_1 0:4a917644acc4 21
franceslee0518 1:6f7f146715e4 22 // RGB Setup
franceslee0518 1:6f7f146715e4 23 class LEDColor
franceslee0518 1:6f7f146715e4 24 {
franceslee0518 1:6f7f146715e4 25 public:
franceslee0518 1:6f7f146715e4 26 LEDColor(float r, float g, float b);
franceslee0518 1:6f7f146715e4 27 float red;
franceslee0518 1:6f7f146715e4 28 float green;
franceslee0518 1:6f7f146715e4 29 float blue;
franceslee0518 1:6f7f146715e4 30 };
franceslee0518 1:6f7f146715e4 31 LEDColor:: LEDColor(float r, float g, float b)
franceslee0518 1:6f7f146715e4 32 : red(r), green(g), blue(b)
franceslee0518 1:6f7f146715e4 33 {
franceslee0518 1:6f7f146715e4 34 }
franceslee0518 1:6f7f146715e4 35 //Operator overload to adjust brightness with no color change
franceslee0518 1:6f7f146715e4 36 LEDColor operator * (const LEDColor& x, const float& b)
franceslee0518 1:6f7f146715e4 37 {
franceslee0518 1:6f7f146715e4 38 return LEDColor(x.red*b,x.green*b,x.blue*b);
franceslee0518 1:6f7f146715e4 39 }
franceslee0518 1:6f7f146715e4 40 //Operator overload to add colors
franceslee0518 1:6f7f146715e4 41 LEDColor operator + (const LEDColor& x, const LEDColor& y)
franceslee0518 1:6f7f146715e4 42 {
franceslee0518 1:6f7f146715e4 43 return LEDColor(x.red+y.red,x.green+y.green,x.blue+y.blue);
franceslee0518 1:6f7f146715e4 44 }
franceslee0518 1:6f7f146715e4 45
franceslee0518 1:6f7f146715e4 46 //Class to control an RGB LED using three PWM pins
franceslee0518 1:6f7f146715e4 47 class RGBLed
franceslee0518 1:6f7f146715e4 48 {
franceslee0518 1:6f7f146715e4 49 public:
franceslee0518 1:6f7f146715e4 50 RGBLed(PinName redpin, PinName greenpin, PinName bluepin);
franceslee0518 1:6f7f146715e4 51 void write(float red,float green, float blue);
franceslee0518 1:6f7f146715e4 52 void write(LEDColor c);
franceslee0518 1:6f7f146715e4 53 RGBLed operator = (LEDColor c) {
franceslee0518 1:6f7f146715e4 54 write(c);
franceslee0518 1:6f7f146715e4 55 return *this;
franceslee0518 1:6f7f146715e4 56 };
franceslee0518 1:6f7f146715e4 57 private:
franceslee0518 1:6f7f146715e4 58 PwmOut _redpin;
franceslee0518 1:6f7f146715e4 59 PwmOut _greenpin;
franceslee0518 1:6f7f146715e4 60 PwmOut _bluepin;
franceslee0518 1:6f7f146715e4 61 };
franceslee0518 1:6f7f146715e4 62
franceslee0518 1:6f7f146715e4 63 RGBLed::RGBLed (PinName redpin, PinName greenpin, PinName bluepin)
franceslee0518 1:6f7f146715e4 64 : _redpin(redpin), _greenpin(greenpin), _bluepin(bluepin)
franceslee0518 1:6f7f146715e4 65 {
franceslee0518 1:6f7f146715e4 66 //50Hz PWM clock default a bit too low, go to 2000Hz (less flicker)
franceslee0518 1:6f7f146715e4 67 _redpin.period(0.0005);
franceslee0518 1:6f7f146715e4 68 }
franceslee0518 1:6f7f146715e4 69
franceslee0518 1:6f7f146715e4 70 void RGBLed::write(float red,float green, float blue)
franceslee0518 1:6f7f146715e4 71 {
franceslee0518 1:6f7f146715e4 72 _redpin = red;
franceslee0518 1:6f7f146715e4 73 _greenpin = green;
franceslee0518 1:6f7f146715e4 74 _bluepin = blue;
franceslee0518 1:6f7f146715e4 75 }
franceslee0518 1:6f7f146715e4 76 void RGBLed::write(LEDColor c)
franceslee0518 1:6f7f146715e4 77 {
franceslee0518 1:6f7f146715e4 78 _redpin = c.red;
franceslee0518 1:6f7f146715e4 79 _greenpin = c.green;
franceslee0518 1:6f7f146715e4 80 _bluepin = c.blue;
franceslee0518 1:6f7f146715e4 81 }
franceslee0518 1:6f7f146715e4 82
franceslee0518 1:6f7f146715e4 83
franceslee0518 1:6f7f146715e4 84 RGBLed myRGBled(p23,p22,p21);
franceslee0518 1:6f7f146715e4 85 const LEDColor blue(0.0,0.0,1.0);
franceslee0518 1:6f7f146715e4 86 const LEDColor yellow(0.2,1.0,0.0);
franceslee0518 1:6f7f146715e4 87 //Setup a new class for TMP36 sensor
franceslee0518 1:6f7f146715e4 88 class TMP36
franceslee0518 1:6f7f146715e4 89 {
franceslee0518 1:6f7f146715e4 90 public:
franceslee0518 1:6f7f146715e4 91 TMP36(PinName pin);
franceslee0518 1:6f7f146715e4 92 TMP36();
franceslee0518 1:6f7f146715e4 93 operator float ();
franceslee0518 1:6f7f146715e4 94 float read();
franceslee0518 1:6f7f146715e4 95 private:
franceslee0518 1:6f7f146715e4 96 //class sets up the AnalogIn pin
franceslee0518 1:6f7f146715e4 97 AnalogIn _pin;
franceslee0518 1:6f7f146715e4 98 };
franceslee0518 1:6f7f146715e4 99
franceslee0518 1:6f7f146715e4 100 TMP36::TMP36(PinName pin) : _pin(pin)
franceslee0518 1:6f7f146715e4 101 {
franceslee0518 1:6f7f146715e4 102 // _pin(pin) means pass pin to the AnalogIn constructor
franceslee0518 1:6f7f146715e4 103 }
franceslee0518 1:6f7f146715e4 104
franceslee0518 1:6f7f146715e4 105 float TMP36::read()
franceslee0518 1:6f7f146715e4 106 {
franceslee0518 1:6f7f146715e4 107 //convert sensor reading to temperature in degrees C
franceslee0518 1:6f7f146715e4 108 return ((_pin.read()*3.3)-0.500)*100.0;
franceslee0518 1:6f7f146715e4 109 }
franceslee0518 1:6f7f146715e4 110 //overload of float conversion (avoids needing to type .read() in equations)
franceslee0518 1:6f7f146715e4 111 TMP36::operator float ()
franceslee0518 1:6f7f146715e4 112 {
franceslee0518 1:6f7f146715e4 113 //convert sensor reading to temperature in degrees C
franceslee0518 1:6f7f146715e4 114 return ((_pin.read()*3.3)-0.500)*100.0;
franceslee0518 1:6f7f146715e4 115 }
franceslee0518 1:6f7f146715e4 116
franceslee0518 1:6f7f146715e4 117 //use the new class to set p15 to analog input to read and convert TMP36 sensor's voltage output
franceslee0518 1:6f7f146715e4 118 TMP36 myTMP36(p15);
franceslee0518 1:6f7f146715e4 119
franceslee0518 1:6f7f146715e4 120 int main() {
franceslee0518 1:6f7f146715e4 121 lcd.background_color(WHITE);
franceslee0518 1:6f7f146715e4 122 lcd.textbackground_color(WHITE);
4180_1 0:4a917644acc4 123 lcd.cls();
4180_1 0:4a917644acc4 124 lcd.locate(0,2);
franceslee0518 1:6f7f146715e4 125 lcd.color(BLACK);
4180_1 0:4a917644acc4 126 lcd.printf("net setup");
4180_1 0:4a917644acc4 127 lcd.locate(0,3);
4180_1 0:4a917644acc4 128 EthernetErr ethErr = eth.setup();
4180_1 0:4a917644acc4 129 if (ethErr) {
4180_1 0:4a917644acc4 130 lcd.printf("Error in setup");
4180_1 0:4a917644acc4 131 return -1;
4180_1 0:4a917644acc4 132 }
4180_1 0:4a917644acc4 133 lcd.printf("net ok");
4180_1 0:4a917644acc4 134
4180_1 0:4a917644acc4 135 SP_XmlDomParser parser;
4180_1 0:4a917644acc4 136 HTTPStream stream;
4180_1 0:4a917644acc4 137
4180_1 0:4a917644acc4 138 char BigBuf[512 + 1] = {0};
franceslee0518 1:6f7f146715e4 139 stream.readNext((byte*)BigBuf, 512);
franceslee0518 1:6f7f146715e4 140 HTTPResult r = http.get("http://api.openweathermap.org/data/2.5/weather?q=Atlanta,us&appid=8df1acdaba0957258c46ced41ce2eedc&mode=xml", &stream, request_callback);
4180_1 0:4a917644acc4 141 while (!completed) {
franceslee0518 1:6f7f146715e4 142 Net::poll();
4180_1 0:4a917644acc4 143 if (stream.readable()) {
franceslee0518 1:6f7f146715e4 144 BigBuf[stream.readLen()] = 0;
franceslee0518 1:6f7f146715e4 145 parser.append( BigBuf, strlen(BigBuf));
franceslee0518 1:6f7f146715e4 146 stream.readNext((byte*)BigBuf, 512);
4180_1 0:4a917644acc4 147 }
4180_1 0:4a917644acc4 148 }
4180_1 0:4a917644acc4 149 lcd.cls();
4180_1 0:4a917644acc4 150 lcd.locate(0,2);
4180_1 0:4a917644acc4 151 if (result == HTTP_OK) {
4180_1 0:4a917644acc4 152 lcd.printf(" Read complete");
4180_1 0:4a917644acc4 153 } else {
franceslee0518 1:6f7f146715e4 154 lcd.printf(" Error %d", http.getHTTPResponseCode());
4180_1 0:4a917644acc4 155 return -1;
4180_1 0:4a917644acc4 156 }
4180_1 0:4a917644acc4 157
4180_1 0:4a917644acc4 158 SP_XmlHandle rootHandle( parser.getDocument()->getRootElement() );
franceslee0518 1:6f7f146715e4 159 //temp
franceslee0518 1:6f7f146715e4 160 SP_XmlElementNode * temp = rootHandle.getChild(1).toElement();
franceslee0518 1:6f7f146715e4 161 lcd.cls();
franceslee0518 1:6f7f146715e4 162 lcd.locate(0,1);
franceslee0518 1:6f7f146715e4 163 lcd.text_bold(ON);
franceslee0518 1:6f7f146715e4 164 lcd.text_char('A', 0, 1, BLACK);
franceslee0518 1:6f7f146715e4 165 lcd.text_bold(ON);
franceslee0518 1:6f7f146715e4 166 lcd.text_char('T', 1, 1, BLACK);
franceslee0518 1:6f7f146715e4 167 lcd.text_bold(ON);
franceslee0518 1:6f7f146715e4 168 lcd.text_char('L', 2, 1, BLACK);
franceslee0518 1:6f7f146715e4 169 lcd.locate(0,2);
franceslee0518 1:6f7f146715e4 170 float mytmp = myTMP36/10;
franceslee0518 1:6f7f146715e4 171 lcd.printf("Indoor Temp: %5.1FC", mytmp);
franceslee0518 1:6f7f146715e4 172 lcd.locate(0,3);
franceslee0518 1:6f7f146715e4 173 //temperature
franceslee0518 1:6f7f146715e4 174 float temperature = atof(temp->getAttrValue("value"))-273.15;
franceslee0518 1:6f7f146715e4 175 lcd.printf("Outdoor Temp: %.1f C ", temperature );
franceslee0518 1:6f7f146715e4 176 //humidity
franceslee0518 1:6f7f146715e4 177 SP_XmlElementNode * humidity = rootHandle.getChild(2).toElement();
franceslee0518 1:6f7f146715e4 178 lcd.locate(0,5);
franceslee0518 1:6f7f146715e4 179 string humid = humidity->getAttrValue("value");
franceslee0518 1:6f7f146715e4 180 lcd.printf("Humidity: %s%% ", humid);
franceslee0518 1:6f7f146715e4 181 //condition
franceslee0518 1:6f7f146715e4 182 SP_XmlElementNode * condition = rootHandle.getChild(8).toElement();
franceslee0518 1:6f7f146715e4 183 string cond = condition->getAttrValue("value");
franceslee0518 1:6f7f146715e4 184 //wind
franceslee0518 1:6f7f146715e4 185 lcd.locate(0,7);
franceslee0518 1:6f7f146715e4 186 SP_XmlElementNode * wind = rootHandle.getChild(4).getChild(0).toElement();
franceslee0518 1:6f7f146715e4 187 string windy = wind->getAttrValue("name");
franceslee0518 1:6f7f146715e4 188 lcd.printf("Weather: %s & %s ", cond, windy);
franceslee0518 1:6f7f146715e4 189 //rain
franceslee0518 1:6f7f146715e4 190 SP_XmlElementNode * rain = rootHandle.getChild(7).toElement();
franceslee0518 1:6f7f146715e4 191 string rainy = rain->getAttrValue("mode");
franceslee0518 1:6f7f146715e4 192
franceslee0518 1:6f7f146715e4 193 // RGB: Blue if raining, yellow if not raining
franceslee0518 1:6f7f146715e4 194 if (rainy.compare("yes")) {
franceslee0518 1:6f7f146715e4 195 myRGBled = blue; //blue
franceslee0518 1:6f7f146715e4 196 } else if (rainy.compare("no")) {
franceslee0518 1:6f7f146715e4 197 myRGBled = yellow; //yellow
4180_1 0:4a917644acc4 198 }
franceslee0518 1:6f7f146715e4 199
franceslee0518 1:6f7f146715e4 200 myTTS.volume(10);
franceslee0518 1:6f7f146715e4 201 myTTS.voice(6);
franceslee0518 1:6f7f146715e4 202 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);
franceslee0518 1:6f7f146715e4 203 myTTS.ready();
franceslee0518 1:6f7f146715e4 204 if (temperature < 15.0) {
franceslee0518 1:6f7f146715e4 205 myTTS.speakf("SBring a jacket with you\r");
franceslee0518 1:6f7f146715e4 206 myTTS.ready();
franceslee0518 1:6f7f146715e4 207 } else if(temperature > 25.0) {
franceslee0518 1:6f7f146715e4 208 myTTS.speakf("SIt's hot outside, bring water with you\r");
franceslee0518 1:6f7f146715e4 209 myTTS.ready();
franceslee0518 1:6f7f146715e4 210 } else {
franceslee0518 1:6f7f146715e4 211 myTTS.speakf("SThe temperature is pleasant outside\r");
franceslee0518 1:6f7f146715e4 212 myTTS.ready();
4180_1 0:4a917644acc4 213 }
franceslee0518 1:6f7f146715e4 214 if (rainy == "yes") {
franceslee0518 1:6f7f146715e4 215 myTTS.speakf("SBring your rain gear with you. It is currently raining outside.\r");
franceslee0518 1:6f7f146715e4 216 myTTS.ready();
franceslee0518 1:6f7f146715e4 217 }
franceslee0518 1:6f7f146715e4 218
franceslee0518 1:6f7f146715e4 219 myRGBled.write(0.0, 0.0, 0.0);
4180_1 0:4a917644acc4 220 }