Weather application for ECE4180 Project.
Dependencies: NetServices mbed HTTPClient 4DGL-uLCD-SE spxml
main.cpp@1:6f7f146715e4, 2018-12-07 (annotated)
- 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?
User | Revision | Line number | New 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 | } |