Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 #include "mbed.h" 00002 #include "cmsis_os.h" 00003 #include "DHT.h" 00004 #include "SDFileSystem.h" 00005 #include "cc3000.h" 00006 #include "SPI_TFT_ILI9341.h" 00007 #include "Arial12x12.h" 00008 #include "Arial24x23.h" 00009 #include "Arial28x28.h" 00010 //#include "Arial34x40.h" 00011 //#include "Arial48x51.h" 00012 //#include "Arial35x38.h" 00013 #include "font_big.h" 00014 #include "Shell.h" 00015 #include "ini.h" 00016 #include "Utility.h" 00017 #include "HttpClient.h" 00018 #include "JsonParser.h" 00019 00020 00021 #include <vector> 00022 #include <string> 00023 #include <cstring> 00024 00025 #include "TCPSocketConnection.h" 00026 #include "TCPSocketServer.h" 00027 00028 using namespace mbed_cc3000; 00029 00030 typedef struct 00031 { 00032 char startupimage[30]; 00033 char webaddress[256]; 00034 float imagedelay; 00035 } configuration; 00036 00037 typedef struct 00038 { 00039 // Values read from DHT11 00040 double current_temperature; 00041 double current_humidity; 00042 double current_dewpoint; 00043 // Values read from openweathermap.com 00044 int weatherid; 00045 int sunrise; 00046 int sunset; 00047 double temperature; 00048 double humidity; 00049 double pressure; 00050 double windspeed; 00051 double clouds; 00052 std::string icon; 00053 std::string location; 00054 std::string description; 00055 00056 void debug(Stream & strm) 00057 { 00058 strm.printf("Weather id : [%d]\r\n", weatherid); 00059 strm.printf("Current temperature: [%0.2f C]\r\n", current_temperature); 00060 strm.printf("Current humidity: [%0.2f%%]\r\n", current_humidity); 00061 strm.printf("Dew Point : [%0.2f C]\r\n", current_dewpoint); 00062 strm.printf("Temperature: [%0.2f C]\r\n", temperature); 00063 strm.printf("Humidity : [%0.2f%%]\r\n", humidity); 00064 strm.printf("Pressure : [%0.2fhpa]\r\n", pressure); 00065 strm.printf("Wind Speed : [%%0.2f]\r\n", windspeed); 00066 strm.printf("Cloud Coverage: [%0.2f]\r\n", clouds); 00067 strm.printf("Location : [%s]\r\n", location.c_str()); 00068 strm.printf("Description: [%s]\r\n", description.c_str()); 00069 strm.printf("Icon id : [%s]\r\n", icon.c_str()); 00070 } 00071 } weather_info; 00072 00073 /* Define ALL Hardware used here and their pin configuration */ 00074 Serial pc(USBTX, USBRX); // tx, rx 00075 DHT dht(D9, DHT11); 00076 //DigitalOut conLed(D6); // PB_10 00077 DigitalIn shellSwitch(D6); // PB_0 (normally pulled high) 00078 I2C i2c(I2C_SDA, I2C_SCL); // SDA, SCL 00079 SDFileSystem sdcard(PB_15, PB_14, PB_13, PB_1, "sd"); // mosi, miso, sclk, cs, name 00080 // the TFT is connected to SPI pin 5-7 00081 SPI_TFT_ILI9341 TFT(PC_12, PC_11, PC_10, PC_0, PC_2, PC_3,"TFT"); // mosi, miso, sclk, cs, reset, dc 00082 DigitalOut lcdOn(PC_1); 00083 cc3000 wifi(PA_10, PA_8, PB_6, SPI(PA_7, PA_6, PA_5), "dlink-B15C", "fricu35860", WPA, false); //irq, en, cs, spi, irq-port 00084 00085 00086 /** Globals **/ 00087 std::vector<std::string> images; 00088 char webdata[1024]; 00089 configuration cfg; 00090 weather_info winfo; 00091 HeaderInfo info; 00092 00093 00094 static int confighandler(void* user, const char* section, const char* name, 00095 const char* value) 00096 { 00097 configuration* pconfig = (configuration*)user; 00098 00099 #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 00100 if (MATCH("rotator", "imagedelay")) { 00101 pconfig->imagedelay = atof(value); 00102 } else if (MATCH("weather", "webaddress")) { 00103 strncpy(pconfig->webaddress, value, sizeof(pconfig->webaddress)); 00104 } else if (MATCH("boot", "startupimage")) { 00105 strncpy(pconfig->startupimage, value, sizeof(pconfig->startupimage)); 00106 } else { 00107 return 0; /* unknown section/name, error */ 00108 } 00109 return 1; 00110 } 00111 00112 /** 00113 * \brief Setup interrupt priorities for Nucleo board 00114 * \param none 00115 * \return none 00116 */ 00117 void init() 00118 { 00119 // First and last IRQ defined in stm32f401xe.h 00120 int irqnum; 00121 for(irqnum = SysTick_IRQn ; irqnum < SPI4_IRQn + 1 ; irqnum++) 00122 NVIC_SetPriority((IRQn_Type)irqnum, 0x04); 00123 00124 NVIC_SetPriority(SPI1_IRQn, 0x0); 00125 NVIC_SetPriority(FPU_IRQn, 0x1); 00126 NVIC_SetPriority(SPI2_IRQn, 0x2); 00127 NVIC_SetPriority(SPI3_IRQn, 0x02); 00128 NVIC_SetPriority(SysTick_IRQn, 0x3); 00129 } 00130 00131 /** 00132 * \brief Initialize CC3000 00133 * \param none 00134 * \return void 00135 **/ 00136 void init_cc3000() 00137 { 00138 printf("Loading wifi startup settings ...\r\n"); 00139 00140 printf("Initializing cc3000 wifi ...\r\n"); 00141 wifi.init(); 00142 printf("Connecting to AP ...\r\n"); 00143 if (wifi.connect() == -1) { 00144 printf("Failed to connect. Please verify connection details and try again. \r\n"); 00145 } else { 00146 printf("IP address: %s \r\n", wifi.getIPAddress()); 00147 printf("Gateway address: %s \r\n", wifi.getGateway()); 00148 set_ctrl_panel(1, 1); 00149 } 00150 } 00151 00152 /** 00153 * \brief Initialize LCD 00154 * \param none 00155 * \return void 00156 **/ 00157 void init_LCD() 00158 { 00159 printf("Initializing LCD Screen ...\r\n"); 00160 00161 lcdOn = 1; 00162 00163 TFT.claim(stdout); 00164 TFT.set_orientation(1); 00165 TFT.background(Black); // set background to black 00166 TFT.foreground(White); // set chars to white 00167 TFT.cls(); // clear the screen 00168 00169 00170 TFT.set_font((unsigned char*) Arial12x12); 00171 TFT.locate(0,0); 00172 00173 } 00174 /** 00175 * \brief Initialize switch/led panel on I2C bus 00176 * \param none 00177 * \return void 00178 **/ 00179 void init_i2cpanel() 00180 { 00181 char cmd[2]; 00182 // Setup direction reg for panel address 1 00183 cmd[0] = 0x00; // Last bit is input 00184 cmd[1] = 0x00; 00185 // Write to the command register 00186 i2c.write(I2C_CTR_PANEL_ADDR, cmd, 2); 00187 00188 // Setup direction reg for panel address 2 00189 cmd[0] = 0x01; 00190 cmd[1] = 0x00; 00191 00192 i2c.write(I2C_CTR_PANEL_ADDR, cmd, 2); 00193 00194 } 00195 00196 /** 00197 * \brief Counter thread to test rtos 00198 * \param arg arguments to the thread 00199 * \return none 00200 **/ 00201 void counter_thread(void const *args) 00202 { 00203 uint8_t count; 00204 00205 while (true) 00206 { 00207 set_ctrl_panel(0, count); 00208 00209 count++; 00210 00211 osDelay(1000); 00212 } 00213 } 00214 osThreadDef(counter_thread, osPriorityNormal, DEFAULT_STACK_SIZE); 00215 00216 00217 int find_images(const char * root, const char * ext) 00218 { 00219 DIR * dp; 00220 struct dirent * dirp; 00221 FILINFO fileInfo; 00222 00223 dp = opendir(root); 00224 while((dirp = readdir(dp)) != NULL) 00225 { 00226 if (sdcard.stat(dirp->d_name, &fileInfo) == 0) 00227 { 00228 if (!(fileInfo.fattrib & AM_DIR )) 00229 { 00230 std::string filename = dirp->d_name; 00231 std::size_t found = filename.find(ext); 00232 if (found!=std::string::npos) 00233 { 00234 std::string fullpathname = root; 00235 fullpathname += "/"; 00236 fullpathname += filename; 00237 images.push_back(fullpathname); 00238 } 00239 } 00240 } 00241 } 00242 closedir(dp); 00243 00244 return images.size(); 00245 } 00246 00247 bool get_current_weather() 00248 { 00249 // First fetch current weather conditions from sensor 00250 pc.printf("Getting current conditions...\r\n"); 00251 if(dht.readData() == ERROR_NONE) 00252 { 00253 float temperature = dht.ReadTemperature(CELCIUS); 00254 float humidity = dht.ReadHumidity(); 00255 float dewpoint = dht.CalcdewPoint(temperature, humidity); 00256 00257 winfo.current_temperature = temperature; 00258 winfo.current_humidity = humidity; 00259 winfo.current_dewpoint = dewpoint; 00260 00261 pc.printf("Temperature : %.2f\r\n", temperature); 00262 pc.printf("Humidity : %.2f\r\n", humidity); 00263 pc.printf("Dew Point : %.2f\r\n", dewpoint); 00264 00265 return true; 00266 } else 00267 return false; 00268 } 00269 00270 bool get_weather_info() 00271 { 00272 bool retval = false; 00273 HttpClient client("test.com"); 00274 00275 memset(webdata, 0, sizeof(webdata)); 00276 00277 // Fetch page from openweather 00278 pc.printf("\r\nTrying to fetch page [%s]... \r\n", cfg.webaddress); 00279 int ret = client.get(cfg.webaddress, webdata, sizeof(webdata), info); 00280 if (ret > 0) 00281 { 00282 using namespace JSON; 00283 pc.printf("Page fetched successfully - read %d characters \r\n", strlen(webdata)); 00284 pc.printf("Web Data [%s]\r\n", webdata); 00285 00286 MVJSONReader reader(webdata); 00287 // pc.printf("Result: %s \r\n", webdata); 00288 if (reader.root->hasField("sys")) 00289 { 00290 winfo.sunrise = reader.root->getField("sys")->getFieldInt("sunrise"); 00291 winfo.sunset = reader.root->getField("sys")->getFieldInt("sunset"); 00292 winfo.location = reader.root->getFieldString("name"); 00293 winfo.temperature = reader.root->getField("main")->getFieldDouble("temp") - 273.15; 00294 winfo.pressure = reader.root->getField("main")->getFieldDouble("pressure"); 00295 winfo.humidity = reader.root->getField("main")->getFieldDouble("humidity"); 00296 winfo.windspeed = reader.root->getField("wind")->getFieldDouble("speed"); 00297 winfo.clouds = reader.root->getField("clouds")->getFieldDouble("all"); 00298 if (reader.root->getField("weather") != NULL) 00299 if (reader.root->getField("weather")->size() > 0) 00300 { 00301 // we take only first element from list 00302 winfo.weatherid = reader.root->getField("weather")->at(0)->getFieldInt("id"); 00303 winfo.icon = reader.root->getField("weather")->at(0)->getFieldString("icon"); 00304 winfo.description = reader.root->getField("weather")->at(0)->getFieldString("description"); 00305 } 00306 retval = true; 00307 } 00308 }else 00309 retval = false; 00310 00311 return retval; 00312 } 00313 00314 // Update LCD display based on weather info 00315 void update_lcd(bool update_locale) 00316 { 00317 00318 // TFT.cls(); 00319 if (get_current_weather()) 00320 { 00321 // Use large fonts to display temperature 00322 TFT.background(Black); 00323 TFT.foreground(White); 00324 TFT.locate(170, 120); 00325 TFT.set_font((unsigned char *) Neu42x35); 00326 TFT.printf("%.0f C",winfo.temperature); 00327 00328 // At the bottom 00329 TFT.fillrect(0,185,320,216,Blue); 00330 TFT.background(Blue); 00331 TFT.foreground(White); 00332 TFT.set_font((unsigned char*) Arial28x28); 00333 TFT.locate(0,187); 00334 TFT.printf("%.0f%% Humidity", 00335 winfo.current_humidity); 00336 00337 TFT.locate(0, 218); 00338 TFT.set_font((unsigned char *) Arial12x12); 00339 TFT.background(Black); 00340 TFT.foreground(White); 00341 TFT.printf("Dew Point : %0.2fC", winfo.current_dewpoint); 00342 } 00343 00344 if (update_locale) 00345 { 00346 // Fill banner with white 00347 TFT.background(White); 00348 TFT.foreground(Black); 00349 TFT.fillrect(0,0,320,100, White); 00350 00351 // Load the graphic icon 00352 std::string filename = "/sd/icons/" + winfo.icon + ".bmp"; 00353 TFT.BMP_16(0,10, filename.c_str()); 00354 00355 // Fill the header - top most of LCD with info 00356 TFT.locate(100,20); 00357 TFT.set_font((unsigned char *) Arial28x28); 00358 TFT.background(White); // set background to black 00359 TFT.foreground(Black); // set chars to white 00360 00361 TFT.printf("%s", winfo.location.c_str()); 00362 TFT.locate(100,60); 00363 TFT.set_font((unsigned char *) Arial12x12); 00364 capitalize_word_start(winfo.description); 00365 TFT.printf("%s", winfo.description.c_str()); 00366 } 00367 00368 00369 } 00370 00371 static const ShellCommand cmds[] = { 00372 {"ls", cmd_ls}, 00373 {"load", cmd_load}, 00374 {"sensor", cmd_sensor}, 00375 {"roll", cmd_rollimages}, 00376 {NULL, NULL} 00377 }; 00378 00379 static const ShellConfig shell_cfg1 = { 00380 (Serial *) &pc, 00381 (ShellCommand *) cmds 00382 }; 00383 00384 int main() 00385 { 00386 00387 // Set NVIC interrupt priorities 00388 init(); 00389 pc.baud(115200); 00390 i2c.frequency(100000); 00391 init_i2cpanel(); 00392 00393 bool startShell = (shellSwitch.read() == 0); 00394 pc.printf("Starting shell: [%s]\r\n", startShell ? "Yes":"No"); 00395 00396 int numbmps = find_images("/sd", ".bmp"); 00397 pc.printf("Found %d bmps in directory /sd\r\n", numbmps); 00398 // Read the configuration file 00399 pc.printf("Reading /sd/config.ini ...\r\n"); 00400 if (ini_parse("/sd/config.ini", confighandler, &cfg) < 0) { 00401 // Initialize the cfg 00402 strcpy(cfg.webaddress, "http://192.168.1.75/hmap/booksearch.html"); 00403 strcpy(cfg.startupimage, "boot.bmp"); 00404 cfg.imagedelay = 1000; 00405 } 00406 00407 pc.printf("Initializing hardware ...\r\n"); 00408 init_cc3000(); 00409 00410 pc.printf("Starting counter leds ....\r\n"); 00411 osThreadCreate(osThread(counter_thread), NULL); 00412 00413 init_LCD(); 00414 00415 00416 if (startShell) 00417 { 00418 pc.printf("Starting debug shell ...\r\n"); 00419 shellStart(&shell_cfg1); 00420 } 00421 else 00422 { 00423 // pc.printf("Starting image rotator ...\r\n"); 00424 unsigned int count = 0; 00425 bool update_weather = true; 00426 while(true) 00427 { 00428 // If we have an RTC, we can detect new day 00429 if (update_weather && get_weather_info()) 00430 { 00431 winfo.debug(pc); 00432 update_lcd(true); 00433 } 00434 else 00435 update_lcd(false); 00436 00437 wait(5.0); 00438 count++; 00439 if ((count % 10) == 0) 00440 update_weather = true; 00441 else 00442 update_weather = false; 00443 00444 00445 //heapinfo(&pc); 00446 /* 00447 for(std::vector<std::string>::iterator i = images.begin(); 00448 i != images.end(); i++) 00449 { 00450 pc.printf("Loading image %s...\r\n", (*i).c_str()); 00451 TFT.cls(); 00452 int err = TFT.BMP_16(0,0, (*i).c_str()); 00453 if (err != 1) TFT.printf(" - Err: %d", err); 00454 00455 wait(1.0); 00456 heapinfo(&pc); 00457 } 00458 */ 00459 } 00460 } 00461 } 00462
Generated on Tue Jul 12 2022 18:55:01 by
