Fork from Alex
Dependencies: mbed MbedJSONValue mbed-rtos 4DGL-uLCD-SE ESP8266NodeMCUInterface
main.cpp@5:b77a717feada, 2019-04-01 (annotated)
- Committer:
- alexhrao
- Date:
- Mon Apr 01 15:27:46 2019 +0000
- Revision:
- 5:b77a717feada
- Parent:
- 4:55f0c303f56a
- Child:
- 6:ec7829f7cd38
Get rid of hard-coded User/Pass
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
alexhrao | 0:4ffa136585a2 | 1 | #include "mbed.h" |
alexhrao | 1:0620ba35d2e8 | 2 | #include "uLCD_4DGL.h" |
alexhrao | 1:0620ba35d2e8 | 3 | #include "ESP8266Interface.h" |
alexhrao | 1:0620ba35d2e8 | 4 | #include "TCPSocketConnection.h" |
alexhrao | 1:0620ba35d2e8 | 5 | #include "rtos.h" |
alexhrao | 3:7bf41989ff8f | 6 | #include "MbedJSONValue.h" |
alexhrao | 3:7bf41989ff8f | 7 | #include <string> |
alexhrao | 3:7bf41989ff8f | 8 | |
alexhrao | 3:7bf41989ff8f | 9 | #define BUF_SIZE 4096 |
alexhrao | 1:0620ba35d2e8 | 10 | |
alexhrao | 1:0620ba35d2e8 | 11 | // We need this for being able to reset the MBED (similar to watch dogs) |
alexhrao | 1:0620ba35d2e8 | 12 | extern "C" void mbed_reset(); |
alexhrao | 1:0620ba35d2e8 | 13 | |
alexhrao | 1:0620ba35d2e8 | 14 | // LCD Screen |
alexhrao | 1:0620ba35d2e8 | 15 | uLCD_4DGL uLCD(p9, p10, p11); |
alexhrao | 1:0620ba35d2e8 | 16 | Mutex lcd_lock; |
alexhrao | 1:0620ba35d2e8 | 17 | |
alexhrao | 1:0620ba35d2e8 | 18 | // File System |
alexhrao | 1:0620ba35d2e8 | 19 | LocalFileSystem fs("local"); |
alexhrao | 1:0620ba35d2e8 | 20 | |
alexhrao | 1:0620ba35d2e8 | 21 | // Bluetooth |
alexhrao | 1:0620ba35d2e8 | 22 | RawSerial pc(USBTX, USBRX); |
alexhrao | 1:0620ba35d2e8 | 23 | RawSerial dev(p28,p27); |
alexhrao | 1:0620ba35d2e8 | 24 | Thread dev_thread; |
alexhrao | 1:0620ba35d2e8 | 25 | |
alexhrao | 1:0620ba35d2e8 | 26 | // Error LED |
alexhrao | 1:0620ba35d2e8 | 27 | DigitalOut err_led(LED1); |
alexhrao | 1:0620ba35d2e8 | 28 | |
alexhrao | 1:0620ba35d2e8 | 29 | // WiFi |
alexhrao | 1:0620ba35d2e8 | 30 | ESP8266Interface wifi(p13, p14, p15, 9600, 10000); |
alexhrao | 1:0620ba35d2e8 | 31 | |
alexhrao | 1:0620ba35d2e8 | 32 | // Time |
alexhrao | 1:0620ba35d2e8 | 33 | Thread time_thread; |
alexhrao | 1:0620ba35d2e8 | 34 | |
alexhrao | 3:7bf41989ff8f | 35 | // Location |
alexhrao | 3:7bf41989ff8f | 36 | double latitude = 0; |
alexhrao | 3:7bf41989ff8f | 37 | double longitude = 0; |
alexhrao | 0:4ffa136585a2 | 38 | |
alexhrao | 4:55f0c303f56a | 39 | // Credentials |
alexhrao | 4:55f0c303f56a | 40 | char ssid[256]; |
alexhrao | 4:55f0c303f56a | 41 | char pass[256]; |
alexhrao | 4:55f0c303f56a | 42 | char ip_api_key[256]; |
alexhrao | 4:55f0c303f56a | 43 | char time_api_key[256]; |
alexhrao | 4:55f0c303f56a | 44 | char weather_api_key[256]; |
alexhrao | 4:55f0c303f56a | 45 | |
alexhrao | 1:0620ba35d2e8 | 46 | void time_updater() { |
alexhrao | 1:0620ba35d2e8 | 47 | // We're not an interrupt, so take as much time as we need. Infinite loop |
alexhrao | 1:0620ba35d2e8 | 48 | // but wait 1 second between each loop |
alexhrao | 1:0620ba35d2e8 | 49 | struct tm* ltm; |
alexhrao | 1:0620ba35d2e8 | 50 | time_t now; |
alexhrao | 1:0620ba35d2e8 | 51 | |
alexhrao | 1:0620ba35d2e8 | 52 | now = time(NULL); |
alexhrao | 1:0620ba35d2e8 | 53 | ltm = localtime(&now); |
alexhrao | 1:0620ba35d2e8 | 54 | |
alexhrao | 1:0620ba35d2e8 | 55 | // Buffer for time string. Max length is 23:59 + \0 |
alexhrao | 4:55f0c303f56a | 56 | int max_time_len = 8; |
alexhrao | 1:0620ba35d2e8 | 57 | char ftime[max_time_len]; |
alexhrao | 4:55f0c303f56a | 58 | ftime[0] = ' '; |
alexhrao | 4:55f0c303f56a | 59 | ftime[1] = ' '; |
alexhrao | 1:0620ba35d2e8 | 60 | int min = -1; |
alexhrao | 1:0620ba35d2e8 | 61 | |
alexhrao | 1:0620ba35d2e8 | 62 | while (true) { |
alexhrao | 1:0620ba35d2e8 | 63 | // if the minute has changed, update. |
alexhrao | 1:0620ba35d2e8 | 64 | now = time(NULL); |
alexhrao | 1:0620ba35d2e8 | 65 | ltm = localtime(&now); |
alexhrao | 1:0620ba35d2e8 | 66 | if(ltm->tm_min != min) { |
alexhrao | 1:0620ba35d2e8 | 67 | // Get the new time |
alexhrao | 4:55f0c303f56a | 68 | strftime(ftime + 2, max_time_len, "%H:%M", ltm); |
alexhrao | 1:0620ba35d2e8 | 69 | // Update time! Lock the lcd mutex |
alexhrao | 1:0620ba35d2e8 | 70 | lcd_lock.lock(); |
alexhrao | 1:0620ba35d2e8 | 71 | uLCD.text_width(2); |
alexhrao | 1:0620ba35d2e8 | 72 | uLCD.text_height(2); |
alexhrao | 1:0620ba35d2e8 | 73 | uLCD.text_string(ftime, 0, 2, FONT_8X8, GREEN); |
alexhrao | 1:0620ba35d2e8 | 74 | // Done updating - unlock! |
alexhrao | 1:0620ba35d2e8 | 75 | lcd_lock.unlock(); |
alexhrao | 1:0620ba35d2e8 | 76 | min = ltm->tm_min; |
alexhrao | 1:0620ba35d2e8 | 77 | } |
alexhrao | 1:0620ba35d2e8 | 78 | // Wait 1 second |
alexhrao | 1:0620ba35d2e8 | 79 | Thread::wait(1.0f); |
alexhrao | 1:0620ba35d2e8 | 80 | } |
alexhrao | 1:0620ba35d2e8 | 81 | } |
alexhrao | 1:0620ba35d2e8 | 82 | |
alexhrao | 4:55f0c303f56a | 83 | /* |
alexhrao | 1:0620ba35d2e8 | 84 | void weather_updater() { |
alexhrao | 4:55f0c303f56a | 85 | // get the weather |
alexhrao | 4:55f0c303f56a | 86 | // first get the current weather |
alexhrao | 4:55f0c303f56a | 87 | // Weather data is _long_ |
alexhrao | 4:55f0c303f56a | 88 | dev.printf("Hello, World!\n"); |
alexhrao | 4:55f0c303f56a | 89 | |
alexhrao | 4:55f0c303f56a | 90 | char forecast_buf[4096]; |
alexhrao | 4:55f0c303f56a | 91 | TCPSocketConnection forecast_sck; |
alexhrao | 4:55f0c303f56a | 92 | // http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6&cnt=8 |
alexhrao | 4:55f0c303f56a | 93 | forecast_sck.connect("api.openweathermap.org", 80); |
alexhrao | 4:55f0c303f56a | 94 | char cmd[256]; |
alexhrao | 4:55f0c303f56a | 95 | sprintf(cmd, |
alexhrao | 4:55f0c303f56a | 96 | "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=6971e1ebfcc60f29c8dcc617c532b1b6&cnt=8\r\nHost: api.openweathermap.org\r\n\r\n", |
alexhrao | 4:55f0c303f56a | 97 | latitude, longitude); |
alexhrao | 4:55f0c303f56a | 98 | forecast_sck.send_all(cmd, strlen(cmd)); |
alexhrao | 4:55f0c303f56a | 99 | wait(10); |
alexhrao | 4:55f0c303f56a | 100 | int len_read = wifi.recv(forecast_buf, 4096 - 1, 0); |
alexhrao | 4:55f0c303f56a | 101 | forecast_buf[len_read] = '\0'; |
alexhrao | 4:55f0c303f56a | 102 | dev.printf(forecast_buf); |
alexhrao | 3:7bf41989ff8f | 103 | return; |
alexhrao | 4:55f0c303f56a | 104 | // http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6 |
alexhrao | 4:55f0c303f56a | 105 | // Get current weather |
alexhrao | 4:55f0c303f56a | 106 | char current_buf[4096]; |
alexhrao | 4:55f0c303f56a | 107 | sprintf(cmd, |
alexhrao | 4:55f0c303f56a | 108 | "GET /data/2.5/forecast?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n", |
alexhrao | 4:55f0c303f56a | 109 | latitude, longitude, weather_api_key); |
alexhrao | 4:55f0c303f56a | 110 | sck.send_all(cmd, strlen(cmd)); |
alexhrao | 4:55f0c303f56a | 111 | wait(10); |
alexhrao | 4:55f0c303f56a | 112 | int buf_len = wifi.recv(current_buf, 4096 - 1, 0); |
alexhrao | 4:55f0c303f56a | 113 | current_buf[buf_len] = '\0'; |
alexhrao | 4:55f0c303f56a | 114 | // we'll always want to update the LCD - don't worry about the previous |
alexhrao | 4:55f0c303f56a | 115 | // weather |
alexhrao | 4:55f0c303f56a | 116 | int curr_temp = 0; |
alexhrao | 4:55f0c303f56a | 117 | int high_temp = 0; |
alexhrao | 4:55f0c303f56a | 118 | int low_temp = 0; |
alexhrao | 4:55f0c303f56a | 119 | char buf[12]; |
alexhrao | 4:55f0c303f56a | 120 | sprintf(buf, "%d %d/%d", curr_temp, high_temp, low_temp); |
alexhrao | 4:55f0c303f56a | 121 | // lock |
alexhrao | 4:55f0c303f56a | 122 | lcd_lock.lock(); |
alexhrao | 4:55f0c303f56a | 123 | uLCD.text_width(2); |
alexhrao | 4:55f0c303f56a | 124 | uLCD.text_height(2); |
alexhrao | 4:55f0c303f56a | 125 | // include null! |
alexhrao | 4:55f0c303f56a | 126 | uLCD.text_string(buf, 0, 5, FONT_7X8, WHITE); |
alexhrao | 4:55f0c303f56a | 127 | // done! unlock |
alexhrao | 4:55f0c303f56a | 128 | lcd_lock.unlock(); |
alexhrao | 1:0620ba35d2e8 | 129 | } |
alexhrao | 4:55f0c303f56a | 130 | */ |
alexhrao | 1:0620ba35d2e8 | 131 | |
alexhrao | 1:0620ba35d2e8 | 132 | void dev_recv() { |
alexhrao | 1:0620ba35d2e8 | 133 | // Continually check if we have stuff... |
alexhrao | 1:0620ba35d2e8 | 134 | char buf[1024]; |
alexhrao | 1:0620ba35d2e8 | 135 | int ind = 0; |
alexhrao | 1:0620ba35d2e8 | 136 | while (true) { |
alexhrao | 1:0620ba35d2e8 | 137 | while (true) { |
alexhrao | 1:0620ba35d2e8 | 138 | // get stuff. If we encounter \r or \n, that's a complete command! |
alexhrao | 1:0620ba35d2e8 | 139 | char tmp = dev.getc(); |
alexhrao | 1:0620ba35d2e8 | 140 | if (tmp == '\n' || tmp == '\r') { |
alexhrao | 1:0620ba35d2e8 | 141 | break; |
alexhrao | 1:0620ba35d2e8 | 142 | } |
alexhrao | 1:0620ba35d2e8 | 143 | buf[ind++] = tmp; |
alexhrao | 1:0620ba35d2e8 | 144 | Thread::wait(0.01); |
alexhrao | 1:0620ba35d2e8 | 145 | } |
alexhrao | 1:0620ba35d2e8 | 146 | buf[ind] = '\0'; |
alexhrao | 1:0620ba35d2e8 | 147 | // read command and respond |
alexhrao | 1:0620ba35d2e8 | 148 | if (strcmp(buf, "reset") == 0) { |
alexhrao | 1:0620ba35d2e8 | 149 | dev.printf("Are you sure? y/[n]\n"); |
alexhrao | 1:0620ba35d2e8 | 150 | } |
alexhrao | 1:0620ba35d2e8 | 151 | buf[0] = '\0'; |
alexhrao | 1:0620ba35d2e8 | 152 | ind = 0; |
alexhrao | 1:0620ba35d2e8 | 153 | //if (strcmp(buf, "reset") != 0) { |
alexhrao | 1:0620ba35d2e8 | 154 | Thread::wait(0.01); |
alexhrao | 1:0620ba35d2e8 | 155 | } |
alexhrao | 2:f7d19812bdc5 | 156 | } |
alexhrao | 0:4ffa136585a2 | 157 | |
alexhrao | 4:55f0c303f56a | 158 | int kelvin2farenheit(int temp) { |
alexhrao | 4:55f0c303f56a | 159 | return (int)((((temp - 273.15f) * 9.0f) / 5.0f) + 32.0f); |
alexhrao | 4:55f0c303f56a | 160 | } |
alexhrao | 4:55f0c303f56a | 161 | |
alexhrao | 4:55f0c303f56a | 162 | void clock_init() { |
alexhrao | 1:0620ba35d2e8 | 163 | // Set up bluetooth |
alexhrao | 1:0620ba35d2e8 | 164 | dev.baud(9600); |
alexhrao | 1:0620ba35d2e8 | 165 | pc.baud(9600); |
alexhrao | 2:f7d19812bdc5 | 166 | |
alexhrao | 1:0620ba35d2e8 | 167 | // Tell user we're initializing... |
alexhrao | 1:0620ba35d2e8 | 168 | lcd_lock.lock(); |
alexhrao | 1:0620ba35d2e8 | 169 | uLCD.cls(); |
alexhrao | 1:0620ba35d2e8 | 170 | uLCD.text_height(2); |
alexhrao | 1:0620ba35d2e8 | 171 | uLCD.text_string("PLEASE WAIT", 0, 2, FONT_7X8, WHITE); |
alexhrao | 1:0620ba35d2e8 | 172 | lcd_lock.unlock(); |
alexhrao | 2:f7d19812bdc5 | 173 | |
alexhrao | 1:0620ba35d2e8 | 174 | // Need to get wifi settings. If we don't have local file, then ask! |
alexhrao | 4:55f0c303f56a | 175 | FILE* fid = fopen("/local/settings.txt", "r"); |
alexhrao | 3:7bf41989ff8f | 176 | |
alexhrao | 4:55f0c303f56a | 177 | if (fid != NULL) { |
alexhrao | 2:f7d19812bdc5 | 178 | // Read WiFi Settings |
alexhrao | 2:f7d19812bdc5 | 179 | char settings_buf[1024]; |
alexhrao | 4:55f0c303f56a | 180 | // Guaranteed to be 5 lines |
alexhrao | 2:f7d19812bdc5 | 181 | // |
alexhrao | 2:f7d19812bdc5 | 182 | fgets(settings_buf, 1024, fid); |
alexhrao | 2:f7d19812bdc5 | 183 | // find \n |
alexhrao | 2:f7d19812bdc5 | 184 | int settings_ind = 0; |
alexhrao | 2:f7d19812bdc5 | 185 | int counter = 0; |
alexhrao | 2:f7d19812bdc5 | 186 | while (settings_buf[counter] != '\n') { |
alexhrao | 2:f7d19812bdc5 | 187 | ssid[settings_ind++] = settings_buf[counter++]; |
alexhrao | 2:f7d19812bdc5 | 188 | } |
alexhrao | 2:f7d19812bdc5 | 189 | ssid[settings_ind] = '\0'; |
alexhrao | 2:f7d19812bdc5 | 190 | settings_ind = 0; |
alexhrao | 4:55f0c303f56a | 191 | fgets(settings_buf, 1024, fid); |
alexhrao | 4:55f0c303f56a | 192 | counter = 0; |
alexhrao | 2:f7d19812bdc5 | 193 | while (settings_buf[counter] != '\n') { |
alexhrao | 2:f7d19812bdc5 | 194 | pass[settings_ind++] = settings_buf[counter++]; |
alexhrao | 2:f7d19812bdc5 | 195 | } |
alexhrao | 2:f7d19812bdc5 | 196 | pass[settings_ind] = '\0'; |
alexhrao | 2:f7d19812bdc5 | 197 | settings_ind = 0; |
alexhrao | 4:55f0c303f56a | 198 | fgets(settings_buf, 1024, fid); |
alexhrao | 4:55f0c303f56a | 199 | counter = 0; |
alexhrao | 4:55f0c303f56a | 200 | while (settings_buf[counter] != '\n') { |
alexhrao | 4:55f0c303f56a | 201 | ip_api_key[settings_ind++] = settings_buf[counter++]; |
alexhrao | 4:55f0c303f56a | 202 | } |
alexhrao | 4:55f0c303f56a | 203 | ip_api_key[settings_ind] = '\0'; |
alexhrao | 4:55f0c303f56a | 204 | settings_ind = 0; |
alexhrao | 4:55f0c303f56a | 205 | fgets(settings_buf, 1024, fid); |
alexhrao | 4:55f0c303f56a | 206 | counter = 0; |
alexhrao | 2:f7d19812bdc5 | 207 | while (settings_buf[counter] != '\n') { |
alexhrao | 4:55f0c303f56a | 208 | time_api_key[settings_ind++] = settings_buf[counter++]; |
alexhrao | 2:f7d19812bdc5 | 209 | } |
alexhrao | 4:55f0c303f56a | 210 | time_api_key[settings_ind] = '\0'; |
alexhrao | 4:55f0c303f56a | 211 | settings_ind = 0; |
alexhrao | 4:55f0c303f56a | 212 | fgets(settings_buf, 1024, fid); |
alexhrao | 4:55f0c303f56a | 213 | counter = 0; |
alexhrao | 4:55f0c303f56a | 214 | while (settings_buf[counter] != '\n') { |
alexhrao | 4:55f0c303f56a | 215 | weather_api_key[settings_ind++] = settings_buf[counter++]; |
alexhrao | 4:55f0c303f56a | 216 | } |
alexhrao | 4:55f0c303f56a | 217 | weather_api_key[settings_ind] = '\0'; |
alexhrao | 2:f7d19812bdc5 | 218 | fclose(fid); |
alexhrao | 1:0620ba35d2e8 | 219 | } else { |
alexhrao | 1:0620ba35d2e8 | 220 | lcd_lock.lock(); |
alexhrao | 1:0620ba35d2e8 | 221 | uLCD.cls(); |
alexhrao | 1:0620ba35d2e8 | 222 | uLCD.text_height(2); |
alexhrao | 1:0620ba35d2e8 | 223 | uLCD.text_width(2); |
alexhrao | 1:0620ba35d2e8 | 224 | uLCD.text_string("SEE", 0, 2, FONT_7X8, RED); |
alexhrao | 1:0620ba35d2e8 | 225 | uLCD.text_string("DEVICE", 0, 5, FONT_7X8, RED); |
alexhrao | 1:0620ba35d2e8 | 226 | lcd_lock.unlock(); |
alexhrao | 2:f7d19812bdc5 | 227 | |
alexhrao | 1:0620ba35d2e8 | 228 | // Ask! |
alexhrao | 1:0620ba35d2e8 | 229 | dev.printf("Please provide the name of a WiFi Network\n"); |
alexhrao | 2:f7d19812bdc5 | 230 | |
alexhrao | 1:0620ba35d2e8 | 231 | // Wait for them to respond |
alexhrao | 1:0620ba35d2e8 | 232 | while (!dev.readable()) { |
alexhrao | 1:0620ba35d2e8 | 233 | wait(0.001); |
alexhrao | 1:0620ba35d2e8 | 234 | } |
alexhrao | 1:0620ba35d2e8 | 235 | int ind = 0; |
alexhrao | 2:f7d19812bdc5 | 236 | |
alexhrao | 1:0620ba35d2e8 | 237 | // Read response |
alexhrao | 1:0620ba35d2e8 | 238 | while (ind < 255) { |
alexhrao | 1:0620ba35d2e8 | 239 | char tmp = dev.getc(); |
alexhrao | 1:0620ba35d2e8 | 240 | if (tmp == '\n' || tmp == '\r') { |
alexhrao | 1:0620ba35d2e8 | 241 | break; |
alexhrao | 1:0620ba35d2e8 | 242 | } |
alexhrao | 1:0620ba35d2e8 | 243 | ssid[ind++] = tmp; |
alexhrao | 1:0620ba35d2e8 | 244 | wait(0.01); |
alexhrao | 1:0620ba35d2e8 | 245 | } |
alexhrao | 1:0620ba35d2e8 | 246 | ssid[ind] = '\0'; |
alexhrao | 1:0620ba35d2e8 | 247 | |
alexhrao | 1:0620ba35d2e8 | 248 | // flush device |
alexhrao | 1:0620ba35d2e8 | 249 | while (dev.readable()) { |
alexhrao | 1:0620ba35d2e8 | 250 | dev.getc(); |
alexhrao | 1:0620ba35d2e8 | 251 | wait(0.01); |
alexhrao | 1:0620ba35d2e8 | 252 | } |
alexhrao | 1:0620ba35d2e8 | 253 | |
alexhrao | 2:f7d19812bdc5 | 254 | // Get the password |
alexhrao | 1:0620ba35d2e8 | 255 | dev.printf("Please provide the password\n"); |
alexhrao | 1:0620ba35d2e8 | 256 | while (!dev.readable()) { |
alexhrao | 1:0620ba35d2e8 | 257 | wait(0.001); |
alexhrao | 1:0620ba35d2e8 | 258 | } |
alexhrao | 1:0620ba35d2e8 | 259 | ind = 0; |
alexhrao | 1:0620ba35d2e8 | 260 | while (ind < 255) { |
alexhrao | 1:0620ba35d2e8 | 261 | char tmp = dev.getc(); |
alexhrao | 1:0620ba35d2e8 | 262 | if (tmp == '\n' || tmp == '\r') { |
alexhrao | 1:0620ba35d2e8 | 263 | break; |
alexhrao | 1:0620ba35d2e8 | 264 | } |
alexhrao | 1:0620ba35d2e8 | 265 | pass[ind++] = tmp; |
alexhrao | 1:0620ba35d2e8 | 266 | wait(0.01); |
alexhrao | 1:0620ba35d2e8 | 267 | } |
alexhrao | 1:0620ba35d2e8 | 268 | pass[ind] = '\0'; |
alexhrao | 2:f7d19812bdc5 | 269 | |
alexhrao | 2:f7d19812bdc5 | 270 | // Get the API key |
alexhrao | 4:55f0c303f56a | 271 | dev.printf("Please provide the IP Stack API key\n"); |
alexhrao | 2:f7d19812bdc5 | 272 | while (!dev.readable()) { |
alexhrao | 2:f7d19812bdc5 | 273 | wait(0.001); |
alexhrao | 2:f7d19812bdc5 | 274 | } |
alexhrao | 2:f7d19812bdc5 | 275 | ind = 0; |
alexhrao | 2:f7d19812bdc5 | 276 | while (ind < 255) { |
alexhrao | 2:f7d19812bdc5 | 277 | char tmp = dev.getc(); |
alexhrao | 2:f7d19812bdc5 | 278 | if (tmp == '\n' || tmp == '\r') { |
alexhrao | 2:f7d19812bdc5 | 279 | break; |
alexhrao | 2:f7d19812bdc5 | 280 | } |
alexhrao | 4:55f0c303f56a | 281 | ip_api_key[ind++] = tmp; |
alexhrao | 4:55f0c303f56a | 282 | wait(0.01); |
alexhrao | 4:55f0c303f56a | 283 | } |
alexhrao | 4:55f0c303f56a | 284 | |
alexhrao | 4:55f0c303f56a | 285 | ip_api_key[ind] = '\0'; |
alexhrao | 4:55f0c303f56a | 286 | |
alexhrao | 4:55f0c303f56a | 287 | dev.printf("Please provide the TimeZoneDB API key\n"); |
alexhrao | 4:55f0c303f56a | 288 | while (!dev.readable()) { |
alexhrao | 4:55f0c303f56a | 289 | wait(0.001); |
alexhrao | 4:55f0c303f56a | 290 | } |
alexhrao | 4:55f0c303f56a | 291 | ind = 0; |
alexhrao | 4:55f0c303f56a | 292 | while (ind < 255) { |
alexhrao | 4:55f0c303f56a | 293 | char tmp = dev.getc(); |
alexhrao | 4:55f0c303f56a | 294 | if (tmp == '\r' || tmp == '\n') { |
alexhrao | 4:55f0c303f56a | 295 | break; |
alexhrao | 4:55f0c303f56a | 296 | } |
alexhrao | 4:55f0c303f56a | 297 | time_api_key[ind++] = tmp; |
alexhrao | 2:f7d19812bdc5 | 298 | wait(0.01); |
alexhrao | 2:f7d19812bdc5 | 299 | } |
alexhrao | 4:55f0c303f56a | 300 | time_api_key[ind] = '\0'; |
alexhrao | 4:55f0c303f56a | 301 | |
alexhrao | 4:55f0c303f56a | 302 | dev.printf("Please provide the OpenWeather API key\n"); |
alexhrao | 4:55f0c303f56a | 303 | while (!dev.readable()) { |
alexhrao | 4:55f0c303f56a | 304 | wait(0.001); |
alexhrao | 4:55f0c303f56a | 305 | } |
alexhrao | 4:55f0c303f56a | 306 | ind = 0; |
alexhrao | 4:55f0c303f56a | 307 | while (ind < 255) { |
alexhrao | 4:55f0c303f56a | 308 | char tmp = dev.getc(); |
alexhrao | 4:55f0c303f56a | 309 | if (tmp == '\r' || tmp == '\n') { |
alexhrao | 4:55f0c303f56a | 310 | break; |
alexhrao | 4:55f0c303f56a | 311 | } |
alexhrao | 4:55f0c303f56a | 312 | weather_api_key[ind++] = tmp; |
alexhrao | 4:55f0c303f56a | 313 | wait(0.01); |
alexhrao | 4:55f0c303f56a | 314 | } |
alexhrao | 4:55f0c303f56a | 315 | weather_api_key[ind] = '\0'; |
alexhrao | 4:55f0c303f56a | 316 | |
alexhrao | 4:55f0c303f56a | 317 | |
alexhrao | 4:55f0c303f56a | 318 | |
alexhrao | 1:0620ba35d2e8 | 319 | // Because this is a simple proof of concept, we store the password in |
alexhrao | 1:0620ba35d2e8 | 320 | // plaintext. It should be noted, however, that you **should never do |
alexhrao | 1:0620ba35d2e8 | 321 | // this in "real life"** |
alexhrao | 4:55f0c303f56a | 322 | fid = fopen("/local/settings.txt", "w"); |
alexhrao | 4:55f0c303f56a | 323 | fprintf(fid, "%s\n%s\n%s\n%s\n%s\n", ssid, pass, ip_api_key, time_api_key, weather_api_key); |
alexhrao | 4:55f0c303f56a | 324 | fclose(fid); |
alexhrao | 1:0620ba35d2e8 | 325 | } |
alexhrao | 4:55f0c303f56a | 326 | |
alexhrao | 4:55f0c303f56a | 327 | dev.printf("\r\n** CREDENTIALS **\r\n"); |
alexhrao | 4:55f0c303f56a | 328 | dev.printf("SSID: **%s** (%d)\r\n", ssid, strlen(ssid)); |
alexhrao | 4:55f0c303f56a | 329 | dev.printf("PASS: **%s** (%d)\r\n", pass, strlen(pass)); |
alexhrao | 4:55f0c303f56a | 330 | dev.printf("IP STACK: **%s**\r\n", ip_api_key); |
alexhrao | 4:55f0c303f56a | 331 | dev.printf("TIMEZONEDB: **%s**\r\n", time_api_key); |
alexhrao | 4:55f0c303f56a | 332 | dev.printf("WEATHERMAP: **%s**\r\n", weather_api_key); |
alexhrao | 4:55f0c303f56a | 333 | |
alexhrao | 1:0620ba35d2e8 | 334 | bool res = wifi.init(); |
alexhrao | 4:55f0c303f56a | 335 | |
alexhrao | 1:0620ba35d2e8 | 336 | // Set up the WiFi Access Point |
alexhrao | 1:0620ba35d2e8 | 337 | dev.printf("Connecting to WiFi %s with Password %s\n", ssid, pass); |
alexhrao | 4:55f0c303f56a | 338 | |
alexhrao | 5:b77a717feada | 339 | res = wifi.connect(ssid, pass); |
alexhrao | 2:f7d19812bdc5 | 340 | if (!res) { |
alexhrao | 2:f7d19812bdc5 | 341 | dev.printf("Connection Failed... Resetting Device\n"); |
alexhrao | 2:f7d19812bdc5 | 342 | err_led = 1; |
alexhrao | 2:f7d19812bdc5 | 343 | mbed_reset(); |
alexhrao | 2:f7d19812bdc5 | 344 | } |
alexhrao | 4:55f0c303f56a | 345 | |
alexhrao | 2:f7d19812bdc5 | 346 | dev.printf("Connected with IP Address: %s\n", wifi.getIPAddress()); |
alexhrao | 2:f7d19812bdc5 | 347 | |
alexhrao | 4:55f0c303f56a | 348 | /** API REQUESTS **/ |
alexhrao | 4:55f0c303f56a | 349 | |
alexhrao | 4:55f0c303f56a | 350 | int header_ind = 0; |
alexhrao | 4:55f0c303f56a | 351 | int footer_ind = 0; |
alexhrao | 4:55f0c303f56a | 352 | int read_len = 0; |
alexhrao | 4:55f0c303f56a | 353 | char buffer[BUF_SIZE]; |
alexhrao | 4:55f0c303f56a | 354 | char cmd[512]; |
alexhrao | 4:55f0c303f56a | 355 | |
alexhrao | 3:7bf41989ff8f | 356 | dev.printf("Getting the current location...\n"); |
alexhrao | 3:7bf41989ff8f | 357 | TCPSocketConnection tcp; |
alexhrao | 3:7bf41989ff8f | 358 | tcp.connect("api.ipstack.com", 80); |
alexhrao | 4:55f0c303f56a | 359 | //af9319bf6435ddd9bb640f763ff64d34 |
alexhrao | 4:55f0c303f56a | 360 | sprintf(cmd, |
alexhrao | 4:55f0c303f56a | 361 | "GET /check?access_key=%s HTTP/1.1\r\nHost: api.ipstack.com\r\n\r\n", |
alexhrao | 4:55f0c303f56a | 362 | ip_api_key); |
alexhrao | 4:55f0c303f56a | 363 | tcp.send_all(cmd, strlen(cmd)); |
alexhrao | 3:7bf41989ff8f | 364 | |
alexhrao | 4:55f0c303f56a | 365 | wait(5); |
alexhrao | 3:7bf41989ff8f | 366 | |
alexhrao | 4:55f0c303f56a | 367 | read_len = wifi.recv(buffer, BUF_SIZE - 1, 0); |
alexhrao | 3:7bf41989ff8f | 368 | buffer[read_len] = '\0'; |
alexhrao | 3:7bf41989ff8f | 369 | |
alexhrao | 4:55f0c303f56a | 370 | // Cleanup |
alexhrao | 4:55f0c303f56a | 371 | |
alexhrao | 4:55f0c303f56a | 372 | while (header_ind < read_len) { |
alexhrao | 4:55f0c303f56a | 373 | // if we are \r, look ahead to see \n\r\n: |
alexhrao | 4:55f0c303f56a | 374 | if(buffer[header_ind] == '\r' && |
alexhrao | 4:55f0c303f56a | 375 | buffer[header_ind+1] == '\n' && |
alexhrao | 4:55f0c303f56a | 376 | buffer[header_ind+2] == '\r' && |
alexhrao | 4:55f0c303f56a | 377 | buffer[header_ind+3] == '\n') { |
alexhrao | 4:55f0c303f56a | 378 | // Increment header_ind, look for JSON |
alexhrao | 4:55f0c303f56a | 379 | // Now just look for { |
alexhrao | 4:55f0c303f56a | 380 | header_ind += 4; |
alexhrao | 4:55f0c303f56a | 381 | while (header_ind < read_len) { |
alexhrao | 4:55f0c303f56a | 382 | if (buffer[header_ind] == '{') { |
alexhrao | 4:55f0c303f56a | 383 | // we got it! |
alexhrao | 4:55f0c303f56a | 384 | break; |
alexhrao | 4:55f0c303f56a | 385 | } |
alexhrao | 4:55f0c303f56a | 386 | header_ind++; |
alexhrao | 4:55f0c303f56a | 387 | } |
alexhrao | 4:55f0c303f56a | 388 | break; |
alexhrao | 4:55f0c303f56a | 389 | } |
alexhrao | 4:55f0c303f56a | 390 | header_ind++; |
alexhrao | 4:55f0c303f56a | 391 | } |
alexhrao | 4:55f0c303f56a | 392 | for (footer_ind = read_len - 1; footer_ind > header_ind; footer_ind--) { |
alexhrao | 4:55f0c303f56a | 393 | if(buffer[footer_ind] == '}') { |
alexhrao | 4:55f0c303f56a | 394 | break; |
alexhrao | 4:55f0c303f56a | 395 | } |
alexhrao | 4:55f0c303f56a | 396 | } |
alexhrao | 4:55f0c303f56a | 397 | buffer[footer_ind + 1] = '\0'; |
alexhrao | 4:55f0c303f56a | 398 | dev.printf(buffer); |
alexhrao | 3:7bf41989ff8f | 399 | MbedJSONValue parser; |
alexhrao | 4:55f0c303f56a | 400 | parse(parser, buffer + header_ind); |
alexhrao | 2:f7d19812bdc5 | 401 | |
alexhrao | 4:55f0c303f56a | 402 | latitude = parser["latitude"].get<double>(); |
alexhrao | 3:7bf41989ff8f | 403 | longitude = parser["longitude"].get<double>(); |
alexhrao | 3:7bf41989ff8f | 404 | |
alexhrao | 4:55f0c303f56a | 405 | // Get the Time |
alexhrao | 4:55f0c303f56a | 406 | TCPSocketConnection time_tcp; |
alexhrao | 4:55f0c303f56a | 407 | |
alexhrao | 4:55f0c303f56a | 408 | //http://api.timezonedb.com/v2.1/get-time-zone?key=YOUR_API_KEY&format=json&by=zone&zone=America/Chicago |
alexhrao | 4:55f0c303f56a | 409 | time_tcp.connect("api.timezonedb.com", 80); |
alexhrao | 4:55f0c303f56a | 410 | //VFHNS0FSUJVN |
alexhrao | 4:55f0c303f56a | 411 | sprintf(cmd, |
alexhrao | 4:55f0c303f56a | 412 | "GET /v2.1/get-time-zone?key=%s&format=json&by=position&lat=%0.4f&lng=%0.4f HTTP/1.1\r\nHost: api.timezonedb.com\r\n\r\n", |
alexhrao | 4:55f0c303f56a | 413 | time_api_key, |
alexhrao | 4:55f0c303f56a | 414 | latitude, |
alexhrao | 4:55f0c303f56a | 415 | longitude); |
alexhrao | 4:55f0c303f56a | 416 | |
alexhrao | 4:55f0c303f56a | 417 | time_tcp.send_all(cmd, strlen(cmd)); |
alexhrao | 4:55f0c303f56a | 418 | wait(5); |
alexhrao | 4:55f0c303f56a | 419 | read_len = wifi.recv(buffer, BUF_SIZE - 1, 0); |
alexhrao | 3:7bf41989ff8f | 420 | buffer[read_len] = '\0'; |
alexhrao | 4:55f0c303f56a | 421 | |
alexhrao | 4:55f0c303f56a | 422 | // Cleanup |
alexhrao | 4:55f0c303f56a | 423 | |
alexhrao | 4:55f0c303f56a | 424 | // Clean up front |
alexhrao | 4:55f0c303f56a | 425 | // Read through headers (\r\n\r\n) |
alexhrao | 4:55f0c303f56a | 426 | header_ind = 0; |
alexhrao | 4:55f0c303f56a | 427 | while (header_ind < read_len) { |
alexhrao | 4:55f0c303f56a | 428 | // if we are \r, look ahead to see \n\r\n: |
alexhrao | 4:55f0c303f56a | 429 | if(buffer[header_ind] == '\r' && |
alexhrao | 4:55f0c303f56a | 430 | buffer[header_ind+1] == '\n' && |
alexhrao | 4:55f0c303f56a | 431 | buffer[header_ind+2] == '\r' && |
alexhrao | 4:55f0c303f56a | 432 | buffer[header_ind+3] == '\n') { |
alexhrao | 4:55f0c303f56a | 433 | // Increment header_ind, look for JSON |
alexhrao | 4:55f0c303f56a | 434 | // Now just look for { |
alexhrao | 4:55f0c303f56a | 435 | header_ind += 4; |
alexhrao | 4:55f0c303f56a | 436 | while (header_ind < read_len) { |
alexhrao | 4:55f0c303f56a | 437 | if (buffer[header_ind] == '{') { |
alexhrao | 4:55f0c303f56a | 438 | // we got it! |
alexhrao | 4:55f0c303f56a | 439 | break; |
alexhrao | 4:55f0c303f56a | 440 | } |
alexhrao | 4:55f0c303f56a | 441 | header_ind++; |
alexhrao | 4:55f0c303f56a | 442 | } |
alexhrao | 4:55f0c303f56a | 443 | break; |
alexhrao | 4:55f0c303f56a | 444 | } |
alexhrao | 4:55f0c303f56a | 445 | header_ind++; |
alexhrao | 4:55f0c303f56a | 446 | } |
alexhrao | 4:55f0c303f56a | 447 | |
alexhrao | 4:55f0c303f56a | 448 | for (footer_ind = read_len - 1; footer_ind > header_ind; footer_ind--) { |
alexhrao | 4:55f0c303f56a | 449 | if(buffer[footer_ind] == '}') { |
alexhrao | 4:55f0c303f56a | 450 | break; |
alexhrao | 4:55f0c303f56a | 451 | } |
alexhrao | 4:55f0c303f56a | 452 | } |
alexhrao | 4:55f0c303f56a | 453 | buffer[footer_ind + 1] = '\0'; |
alexhrao | 2:f7d19812bdc5 | 454 | |
alexhrao | 4:55f0c303f56a | 455 | MbedJSONValue time_parser; |
alexhrao | 4:55f0c303f56a | 456 | parse(time_parser, buffer + header_ind); |
alexhrao | 4:55f0c303f56a | 457 | |
alexhrao | 4:55f0c303f56a | 458 | // Add 5 so that we make up for the wait(5) |
alexhrao | 4:55f0c303f56a | 459 | set_time(time_parser["timestamp"].get<int>() + 5); |
alexhrao | 4:55f0c303f56a | 460 | // Now that we know what time it is, set up our Time Thread |
alexhrao | 4:55f0c303f56a | 461 | time_thread.start(time_updater); |
alexhrao | 4:55f0c303f56a | 462 | TCPSocketConnection forecast_sck; |
alexhrao | 4:55f0c303f56a | 463 | // http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6&cnt=8 |
alexhrao | 4:55f0c303f56a | 464 | forecast_sck.connect("api.openweathermap.org", 80); |
alexhrao | 4:55f0c303f56a | 465 | //6971e1ebfcc60f29c8dcc617c532b1b6 |
alexhrao | 4:55f0c303f56a | 466 | sprintf(cmd, |
alexhrao | 4:55f0c303f56a | 467 | "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s&cnt=8\r\nHost: api.openweathermap.org\r\n\r\n", |
alexhrao | 4:55f0c303f56a | 468 | latitude, longitude, weather_api_key); |
alexhrao | 4:55f0c303f56a | 469 | forecast_sck.send_all(cmd, strlen(cmd)); |
alexhrao | 4:55f0c303f56a | 470 | wait(5); |
alexhrao | 4:55f0c303f56a | 471 | int len_read = wifi.recv(buffer, BUF_SIZE - 1, 0); |
alexhrao | 4:55f0c303f56a | 472 | buffer[len_read] = '\0'; |
alexhrao | 4:55f0c303f56a | 473 | |
alexhrao | 4:55f0c303f56a | 474 | |
alexhrao | 4:55f0c303f56a | 475 | //buffer[footer_ind + 1] = '\0'; |
alexhrao | 4:55f0c303f56a | 476 | char* ind = strstr(buffer, "temp"); |
alexhrao | 4:55f0c303f56a | 477 | for (int m = 0; m < 15; m++) { |
alexhrao | 4:55f0c303f56a | 478 | dev.putc(ind[m]); |
alexhrao | 4:55f0c303f56a | 479 | } |
alexhrao | 4:55f0c303f56a | 480 | char num_buf[16]; |
alexhrao | 4:55f0c303f56a | 481 | int num_ind = 0; |
alexhrao | 4:55f0c303f56a | 482 | // go until we find numbers |
alexhrao | 4:55f0c303f56a | 483 | while (char tmp = *ind++) { |
alexhrao | 4:55f0c303f56a | 484 | if (tmp > '0' && tmp < '9') { |
alexhrao | 4:55f0c303f56a | 485 | num_buf[num_ind++] = tmp; |
alexhrao | 4:55f0c303f56a | 486 | break; |
alexhrao | 4:55f0c303f56a | 487 | } |
alexhrao | 4:55f0c303f56a | 488 | } |
alexhrao | 4:55f0c303f56a | 489 | // Keep moving until no more numbers |
alexhrao | 4:55f0c303f56a | 490 | while (char tmp = *ind++) { |
alexhrao | 4:55f0c303f56a | 491 | if (tmp > '9' || tmp < '0') { |
alexhrao | 4:55f0c303f56a | 492 | num_buf[num_ind] = '\0'; |
alexhrao | 4:55f0c303f56a | 493 | break; |
alexhrao | 4:55f0c303f56a | 494 | } else { |
alexhrao | 4:55f0c303f56a | 495 | num_buf[num_ind++] = tmp; |
alexhrao | 4:55f0c303f56a | 496 | } |
alexhrao | 4:55f0c303f56a | 497 | } |
alexhrao | 4:55f0c303f56a | 498 | int temp = atoi(num_buf); |
alexhrao | 4:55f0c303f56a | 499 | // Convert |
alexhrao | 4:55f0c303f56a | 500 | temp = (((temp - 273.15f) * 9.0f) / 5.0f) + 32.0f; |
alexhrao | 4:55f0c303f56a | 501 | char temp_buf[12]; |
alexhrao | 4:55f0c303f56a | 502 | sprintf(temp_buf, " %dF", temp); |
alexhrao | 2:f7d19812bdc5 | 503 | lcd_lock.lock(); |
alexhrao | 4:55f0c303f56a | 504 | uLCD.text_width(2); |
alexhrao | 4:55f0c303f56a | 505 | uLCD.text_height(2); |
alexhrao | 4:55f0c303f56a | 506 | uLCD.text_string(temp_buf, 0, 5, FONT_8X8, WHITE); |
alexhrao | 4:55f0c303f56a | 507 | // done! unlock |
alexhrao | 2:f7d19812bdc5 | 508 | lcd_lock.unlock(); |
alexhrao | 2:f7d19812bdc5 | 509 | |
alexhrao | 1:0620ba35d2e8 | 510 | |
alexhrao | 1:0620ba35d2e8 | 511 | // Start up weather service! |
alexhrao | 3:7bf41989ff8f | 512 | //weather_thread.start(weather_updater); |
alexhrao | 1:0620ba35d2e8 | 513 | |
alexhrao | 1:0620ba35d2e8 | 514 | // Listen on bluetooth. |
alexhrao | 4:55f0c303f56a | 515 | //dev_thread.start(dev_recv); |
alexhrao | 1:0620ba35d2e8 | 516 | while(true) { |
alexhrao | 3:7bf41989ff8f | 517 | time_t curr_time = time(NULL); |
alexhrao | 4:55f0c303f56a | 518 | if (true) { |
alexhrao | 4:55f0c303f56a | 519 | sprintf(cmd, |
alexhrao | 4:55f0c303f56a | 520 | "GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n", |
alexhrao | 4:55f0c303f56a | 521 | latitude, longitude, weather_api_key); |
alexhrao | 4:55f0c303f56a | 522 | forecast_sck.connect("api.openweathermap.org", 80); |
alexhrao | 4:55f0c303f56a | 523 | wait(10); |
alexhrao | 4:55f0c303f56a | 524 | forecast_sck.send_all(cmd, strlen(cmd)); |
alexhrao | 4:55f0c303f56a | 525 | wait(5); |
alexhrao | 4:55f0c303f56a | 526 | |
alexhrao | 4:55f0c303f56a | 527 | len_read = wifi.recv(buffer, BUF_SIZE - 1, 0); |
alexhrao | 4:55f0c303f56a | 528 | |
alexhrao | 4:55f0c303f56a | 529 | buffer[len_read] = '\0'; |
alexhrao | 4:55f0c303f56a | 530 | |
alexhrao | 4:55f0c303f56a | 531 | |
alexhrao | 4:55f0c303f56a | 532 | dev.printf(buffer); |
alexhrao | 4:55f0c303f56a | 533 | |
alexhrao | 4:55f0c303f56a | 534 | ind = strstr(buffer, "temp"); |
alexhrao | 4:55f0c303f56a | 535 | for (int m = 0; m < 15; m++) { |
alexhrao | 4:55f0c303f56a | 536 | dev.putc(ind[m]); |
alexhrao | 4:55f0c303f56a | 537 | } |
alexhrao | 4:55f0c303f56a | 538 | num_ind = 0; |
alexhrao | 4:55f0c303f56a | 539 | // go until we find numbers |
alexhrao | 4:55f0c303f56a | 540 | while (char tmp = *ind++) { |
alexhrao | 4:55f0c303f56a | 541 | dev.printf("CHAR: %c\r\n", tmp); |
alexhrao | 4:55f0c303f56a | 542 | if (tmp > '0' && tmp < '9') { |
alexhrao | 4:55f0c303f56a | 543 | num_buf[num_ind++] = tmp; |
alexhrao | 4:55f0c303f56a | 544 | break; |
alexhrao | 4:55f0c303f56a | 545 | } |
alexhrao | 4:55f0c303f56a | 546 | } |
alexhrao | 4:55f0c303f56a | 547 | // Keep moving until no more numbers |
alexhrao | 4:55f0c303f56a | 548 | while (char tmp = *ind++) { |
alexhrao | 4:55f0c303f56a | 549 | if (tmp > '9' || tmp < '0') { |
alexhrao | 4:55f0c303f56a | 550 | num_buf[num_ind] = '\0'; |
alexhrao | 4:55f0c303f56a | 551 | break; |
alexhrao | 4:55f0c303f56a | 552 | } else { |
alexhrao | 4:55f0c303f56a | 553 | num_buf[num_ind++] = tmp; |
alexhrao | 4:55f0c303f56a | 554 | } |
alexhrao | 4:55f0c303f56a | 555 | } |
alexhrao | 4:55f0c303f56a | 556 | temp = atoi(num_buf); |
alexhrao | 4:55f0c303f56a | 557 | dev.printf("Temperature: %s (%d)\r\n", num_buf, temp); |
alexhrao | 4:55f0c303f56a | 558 | // Convert |
alexhrao | 4:55f0c303f56a | 559 | temp = (((temp - 273.15f) * 9.0f) / 5.0f) + 32.0f; |
alexhrao | 4:55f0c303f56a | 560 | sprintf(temp_buf, " %dF", temp); |
alexhrao | 4:55f0c303f56a | 561 | lcd_lock.lock(); |
alexhrao | 4:55f0c303f56a | 562 | uLCD.text_width(2); |
alexhrao | 4:55f0c303f56a | 563 | uLCD.text_height(2); |
alexhrao | 4:55f0c303f56a | 564 | uLCD.text_string(temp_buf, 0, 5, FONT_8X8, WHITE); |
alexhrao | 4:55f0c303f56a | 565 | // done! unlock |
alexhrao | 4:55f0c303f56a | 566 | lcd_lock.unlock(); |
alexhrao | 3:7bf41989ff8f | 567 | } |
alexhrao | 4:55f0c303f56a | 568 | |
alexhrao | 1:0620ba35d2e8 | 569 | err_led = !err_led; |
alexhrao | 0:4ffa136585a2 | 570 | } |
alexhrao | 0:4ffa136585a2 | 571 | } |
alexhrao | 4:55f0c303f56a | 572 | |
alexhrao | 4:55f0c303f56a | 573 | int main() { |
alexhrao | 4:55f0c303f56a | 574 | clock_init(); |
alexhrao | 4:55f0c303f56a | 575 | } |