simple weather app that uses sensor and forecast data from opeanweather.org . The results are shown on TFT and published on Thingspeak. (there may be some of my charts at https://thingspeak.com/channels/26357) This was built to show using k64F ethernet capabilities for K64F roadtest at http://www.element14.com/community/groups/roadtest (there will be a write there shortly)

Dependencies:   DHT EthernetInterface HTTPClient NTPClient SDFileSystem SPI_TFT_ILI9341 TFT_fonts mbed-rtos mbed picojson

Committer:
colinmeikle
Date:
Fri Mar 20 14:24:06 2015 +0000
Revision:
0:9ab281898a9b
this is a simple weather app that displays the weather on TFT and publishes results on thingspeak. This was built for K64F roadtest http://www.element14.com/community/groups/roadtest

Who changed what in which revision?

UserRevisionLine numberNew contents of line
colinmeikle 0:9ab281898a9b 1 #include "mbed.h"
colinmeikle 0:9ab281898a9b 2 #include "SPI_TFT_ILI9341.h"
colinmeikle 0:9ab281898a9b 3 #include "sansSerif19x20.h"
colinmeikle 0:9ab281898a9b 4 #include "DHT.h"
colinmeikle 0:9ab281898a9b 5 #include "EthernetInterface.h"
colinmeikle 0:9ab281898a9b 6 #include "NTPClient.h"
colinmeikle 0:9ab281898a9b 7 #include "HTTPClient.h"
colinmeikle 0:9ab281898a9b 8 #include "picojson.h"
colinmeikle 0:9ab281898a9b 9 #include "SDFileSystem.h"
colinmeikle 0:9ab281898a9b 10 //IMPORTANT YOU NEED TO SET THE API KEY for thingspeak look for "your key here"
colinmeikle 0:9ab281898a9b 11 //TAKE CARE URL doesn't excced buffer size
colinmeikle 0:9ab281898a9b 12 //sd card
colinmeikle 0:9ab281898a9b 13 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCLK, SSEL
colinmeikle 0:9ab281898a9b 14 //Ethernet Interface
colinmeikle 0:9ab281898a9b 15 EthernetInterface eth;
colinmeikle 0:9ab281898a9b 16 //NTP service for date and Time used to set boards RTC
colinmeikle 0:9ab281898a9b 17 NTPClient ntp;
colinmeikle 0:9ab281898a9b 18 //HTTP Client for interfacing to web services
colinmeikle 0:9ab281898a9b 19 HTTPClient http;
colinmeikle 0:9ab281898a9b 20 char resp[1024]; //buffer for the responce
colinmeikle 0:9ab281898a9b 21 //On board LED
colinmeikle 0:9ab281898a9b 22 DigitalOut myled(LED_GREEN);
colinmeikle 0:9ab281898a9b 23 //serial over USB for debug and Info
colinmeikle 0:9ab281898a9b 24 Serial pc(USBTX, USBRX);
colinmeikle 0:9ab281898a9b 25 //temperature sensor
colinmeikle 0:9ab281898a9b 26 DHT sensor(PTB18,DHT22); // there are several libraries available, this reports CRC error sometimes
colinmeikle 0:9ab281898a9b 27 //320x240 Display ILI9341 controller (look on ebay)
colinmeikle 0:9ab281898a9b 28 SPI_TFT_ILI9341 TFT(PTD2, PTD3, PTD1,PTC3 ,PTC4 ,PTD0 ,"TFT"); // mosi, miso, sclk, cs, reset, dc
colinmeikle 0:9ab281898a9b 29
colinmeikle 0:9ab281898a9b 30 int main()
colinmeikle 0:9ab281898a9b 31 {
colinmeikle 0:9ab281898a9b 32 int cnt = 0;
colinmeikle 0:9ab281898a9b 33 int err;
colinmeikle 0:9ab281898a9b 34 int ret=0;
colinmeikle 0:9ab281898a9b 35 char val[4][16];
colinmeikle 0:9ab281898a9b 36 //used to parse the json data
colinmeikle 0:9ab281898a9b 37 picojson::value v;
colinmeikle 0:9ab281898a9b 38 char * json;
colinmeikle 0:9ab281898a9b 39 HTTPMap map;
colinmeikle 0:9ab281898a9b 40 HTTPText inText(resp, 1024);
colinmeikle 0:9ab281898a9b 41 char sdfile[32];
colinmeikle 0:9ab281898a9b 42 FILE *fp;
colinmeikle 0:9ab281898a9b 43 pc.printf("Weather Reporter\n");
colinmeikle 0:9ab281898a9b 44
colinmeikle 0:9ab281898a9b 45
colinmeikle 0:9ab281898a9b 46 //eithernet init
colinmeikle 0:9ab281898a9b 47 eth.init(); //Use DHCP
colinmeikle 0:9ab281898a9b 48 ret= eth.connect();
colinmeikle 0:9ab281898a9b 49 if (!ret) {
colinmeikle 0:9ab281898a9b 50 pc.printf("Connected, IP: %s, MASK: %s, GW: %s\n",
colinmeikle 0:9ab281898a9b 51 eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
colinmeikle 0:9ab281898a9b 52 } else {
colinmeikle 0:9ab281898a9b 53 pc.printf("Error eth.connect() - ret = %d\n", ret);
colinmeikle 0:9ab281898a9b 54 }
colinmeikle 0:9ab281898a9b 55
colinmeikle 0:9ab281898a9b 56
colinmeikle 0:9ab281898a9b 57 //setup the TFT DISPLAY
colinmeikle 0:9ab281898a9b 58 TFT.claim(stdout); // send stdout to the TFT display
colinmeikle 0:9ab281898a9b 59 //ensure the output is write and not buffered
colinmeikle 0:9ab281898a9b 60 setvbuf ( stdout , NULL , _IONBF , NULL );
colinmeikle 0:9ab281898a9b 61 //TFT.claim(stderr); // send stderr to the TFT display
colinmeikle 0:9ab281898a9b 62 TFT.set_orientation(1);
colinmeikle 0:9ab281898a9b 63 TFT.background(Black); // set background to black
colinmeikle 0:9ab281898a9b 64 //centerx = TFT.width() >> 1;
colinmeikle 0:9ab281898a9b 65 //centery = TFT.height() >> 1;
colinmeikle 0:9ab281898a9b 66
colinmeikle 0:9ab281898a9b 67
colinmeikle 0:9ab281898a9b 68 TFT.cls();
colinmeikle 0:9ab281898a9b 69 TFT.locate(0,0);
colinmeikle 0:9ab281898a9b 70 TFT.set_font((unsigned char*) sansserif);
colinmeikle 0:9ab281898a9b 71 //printf will now for to TFT because of the TFT.claim(stdout)
colinmeikle 0:9ab281898a9b 72 printf("Weather Test\n");
colinmeikle 0:9ab281898a9b 73 //setup the RTC with date and time
colinmeikle 0:9ab281898a9b 74 printf("Trying to update time...\r\n");
colinmeikle 0:9ab281898a9b 75 time_t ctTime;
colinmeikle 0:9ab281898a9b 76 NTPResult result;
colinmeikle 0:9ab281898a9b 77 result = ntp.setTime("pool.ntp.org");
colinmeikle 0:9ab281898a9b 78 if (result == NTP_OK) {
colinmeikle 0:9ab281898a9b 79 time(&ctTime);
colinmeikle 0:9ab281898a9b 80 printf("Time is set to (UTC):\n%s\n", ctime(&ctTime));
colinmeikle 0:9ab281898a9b 81 strcpy(sdfile,"/sd/results/default_results"); //could use time in name
colinmeikle 0:9ab281898a9b 82 }else{
colinmeikle 0:9ab281898a9b 83 printf("Error setting Time\n");
colinmeikle 0:9ab281898a9b 84 strcpy(sdfile,"/sd/results/default_results");
colinmeikle 0:9ab281898a9b 85 }
colinmeikle 0:9ab281898a9b 86
colinmeikle 0:9ab281898a9b 87 //write to sdcard, we could use the time and date in the filename defained above to give a new file for every session
colinmeikle 0:9ab281898a9b 88 mkdir("/sd/results", 0777);
colinmeikle 0:9ab281898a9b 89 fp = fopen(sdfile, "w");
colinmeikle 0:9ab281898a9b 90 if (fp == NULL) {
colinmeikle 0:9ab281898a9b 91 pc.printf("Unable to write the file \n");
colinmeikle 0:9ab281898a9b 92 } else {
colinmeikle 0:9ab281898a9b 93 pc.printf("Writing data to SDCARD \n");
colinmeikle 0:9ab281898a9b 94 //time,temp,humidity,forcast,pressure
colinmeikle 0:9ab281898a9b 95 fprintf(fp, "time,temperature,humidity,forcastTemp,forcastPressure\n");
colinmeikle 0:9ab281898a9b 96 fclose(fp);
colinmeikle 0:9ab281898a9b 97 }
colinmeikle 0:9ab281898a9b 98
colinmeikle 0:9ab281898a9b 99 float humidity=0;
colinmeikle 0:9ab281898a9b 100 float temperature=-100;
colinmeikle 0:9ab281898a9b 101 float forcastTemp=0;
colinmeikle 0:9ab281898a9b 102 float forcastPressure;
colinmeikle 0:9ab281898a9b 103 wait(10);
colinmeikle 0:9ab281898a9b 104 pc.printf("\r\nDHT Test program");
colinmeikle 0:9ab281898a9b 105 pc.printf("\r\n******************\r\n");
colinmeikle 0:9ab281898a9b 106 wait(1); // wait 1 second for device stable status
colinmeikle 0:9ab281898a9b 107 while(1){
colinmeikle 0:9ab281898a9b 108
colinmeikle 0:9ab281898a9b 109 //GET forcast data
colinmeikle 0:9ab281898a9b 110 pc.printf("\nTrying to fetch page...\n");
colinmeikle 0:9ab281898a9b 111 //try getting the weather, 5 second timeout
colinmeikle 0:9ab281898a9b 112 ret = http.get("http://api.openweathermap.org/data/2.5/weather?q=Strathaven,uk", resp, 5000);
colinmeikle 0:9ab281898a9b 113 if(!ret){
colinmeikle 0:9ab281898a9b 114 pc.printf("responce=%s",resp);
colinmeikle 0:9ab281898a9b 115 json=&resp[0];
colinmeikle 0:9ab281898a9b 116 pc.printf("parsing");
colinmeikle 0:9ab281898a9b 117 string err = picojson::parse(v, json, json + strlen(json));
colinmeikle 0:9ab281898a9b 118 if(err.empty()){
colinmeikle 0:9ab281898a9b 119 forcastTemp=v.get("main").get("temp").get<double>();
colinmeikle 0:9ab281898a9b 120 forcastTemp=forcastTemp-273.15;
colinmeikle 0:9ab281898a9b 121 forcastPressure=v.get("main").get("pressure").get<double>();
colinmeikle 0:9ab281898a9b 122 // printf("Forcast temp: %f\n", forcastTemp);
colinmeikle 0:9ab281898a9b 123 }
colinmeikle 0:9ab281898a9b 124 else{
colinmeikle 0:9ab281898a9b 125 pc.printf("error parsing");
colinmeikle 0:9ab281898a9b 126 }
colinmeikle 0:9ab281898a9b 127 }
colinmeikle 0:9ab281898a9b 128 else{
colinmeikle 0:9ab281898a9b 129 pc.printf("ERROR=%d", ret);
colinmeikle 0:9ab281898a9b 130 }
colinmeikle 0:9ab281898a9b 131
colinmeikle 0:9ab281898a9b 132 err = sensor.readData();
colinmeikle 0:9ab281898a9b 133 if (err == 0) {
colinmeikle 0:9ab281898a9b 134 TFT.cls();
colinmeikle 0:9ab281898a9b 135 TFT.locate(0,0);
colinmeikle 0:9ab281898a9b 136 time(&ctTime);
colinmeikle 0:9ab281898a9b 137 printf("%s\n", ctime(&ctTime));
colinmeikle 0:9ab281898a9b 138 temperature=sensor.ReadTemperature(CELCIUS);
colinmeikle 0:9ab281898a9b 139 humidity=sensor.ReadHumidity();
colinmeikle 0:9ab281898a9b 140 printf("Temperature: %4.2f C \r\n",temperature);
colinmeikle 0:9ab281898a9b 141 printf("Forcast Temp: %4.2f C \r\n",forcastTemp);
colinmeikle 0:9ab281898a9b 142 printf("Temperature is %4.2f F \r\n",sensor.ReadTemperature(FARENHEIT));
colinmeikle 0:9ab281898a9b 143 printf("Humidity is %4.2f \r\n",humidity);
colinmeikle 0:9ab281898a9b 144 printf("Dew point is %4.2f \r\n",sensor.CalcdewPoint(sensor.ReadTemperature(CELCIUS), sensor.ReadHumidity()));
colinmeikle 0:9ab281898a9b 145 printf("Forcast Pressure: %4.2f C \r\n",forcastPressure);
colinmeikle 0:9ab281898a9b 146 myled = 1;
colinmeikle 0:9ab281898a9b 147 } else{
colinmeikle 0:9ab281898a9b 148 pc.printf("\r\nErr %i \n",err);
colinmeikle 0:9ab281898a9b 149 myled = 0;
colinmeikle 0:9ab281898a9b 150 }
colinmeikle 0:9ab281898a9b 151
colinmeikle 0:9ab281898a9b 152
colinmeikle 0:9ab281898a9b 153 //sent to thingsspeak
colinmeikle 0:9ab281898a9b 154 if(cnt==10){ //don't update as often
colinmeikle 0:9ab281898a9b 155 cnt=0;
colinmeikle 0:9ab281898a9b 156 memset(resp, '\0', sizeof(resp));
colinmeikle 0:9ab281898a9b 157 //POST data
colinmeikle 0:9ab281898a9b 158 if(temperature!=-100){ //just check we have a valid temp
colinmeikle 0:9ab281898a9b 159 map.put("api_key","YOUR KEY HERE");
colinmeikle 0:9ab281898a9b 160 sprintf(val[0],"%4.1f",temperature);
colinmeikle 0:9ab281898a9b 161 map.put("field1", val[0]);
colinmeikle 0:9ab281898a9b 162 sprintf(val[1],"%4.1f",humidity);
colinmeikle 0:9ab281898a9b 163 map.put("field2", val[1]);
colinmeikle 0:9ab281898a9b 164 sprintf(val[2],"%4.1f",forcastTemp);
colinmeikle 0:9ab281898a9b 165 map.put("field3", val[2]);
colinmeikle 0:9ab281898a9b 166 sprintf(val[3],"%4.1f",forcastPressure);
colinmeikle 0:9ab281898a9b 167 map.put("field4", val[3]);
colinmeikle 0:9ab281898a9b 168 pc.printf("\nTrying to post data...\n");
colinmeikle 0:9ab281898a9b 169 ret = http.post("https://api.thingspeak.com/update", map, &inText);
colinmeikle 0:9ab281898a9b 170 if (!ret)
colinmeikle 0:9ab281898a9b 171 {
colinmeikle 0:9ab281898a9b 172 pc.printf("Executed POST successfully - read %d characters\n", strlen(resp));
colinmeikle 0:9ab281898a9b 173 pc.printf("Result: %s\n", resp);
colinmeikle 0:9ab281898a9b 174 }
colinmeikle 0:9ab281898a9b 175 else
colinmeikle 0:9ab281898a9b 176 {
colinmeikle 0:9ab281898a9b 177 pc.printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
colinmeikle 0:9ab281898a9b 178 }
colinmeikle 0:9ab281898a9b 179 //Write Data to SDCARD
colinmeikle 0:9ab281898a9b 180 fp = fopen(sdfile, "a");
colinmeikle 0:9ab281898a9b 181 if (fp == NULL) {
colinmeikle 0:9ab281898a9b 182 pc.printf("Unable to write the file \n");
colinmeikle 0:9ab281898a9b 183 } else {
colinmeikle 0:9ab281898a9b 184 pc.printf("Writing data to SDCARD \n");
colinmeikle 0:9ab281898a9b 185 //time,temp,humidity,forcast,pressure
colinmeikle 0:9ab281898a9b 186 fprintf(fp, "%s,%4.1f,%4.1f,%4.1f,%4.1f\n", ctime(&ctTime),temperature,humidity,forcastTemp,forcastPressure);
colinmeikle 0:9ab281898a9b 187 fclose(fp);
colinmeikle 0:9ab281898a9b 188 }
colinmeikle 0:9ab281898a9b 189 }
colinmeikle 0:9ab281898a9b 190
colinmeikle 0:9ab281898a9b 191 }
colinmeikle 0:9ab281898a9b 192
colinmeikle 0:9ab281898a9b 193 cnt++;
colinmeikle 0:9ab281898a9b 194 wait_ms(6000);
colinmeikle 0:9ab281898a9b 195 }
colinmeikle 0:9ab281898a9b 196 }