The code from https://github.com/vpcola/Nucleo
Diff: main.cpp
- Revision:
- 0:5464d5e415e5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Oct 08 11:00:24 2014 +0000 @@ -0,0 +1,462 @@ +#include "mbed.h" +#include "cmsis_os.h" +#include "DHT.h" +#include "SDFileSystem.h" +#include "cc3000.h" +#include "SPI_TFT_ILI9341.h" +#include "Arial12x12.h" +#include "Arial24x23.h" +#include "Arial28x28.h" +//#include "Arial34x40.h" +//#include "Arial48x51.h" +//#include "Arial35x38.h" +#include "font_big.h" +#include "Shell.h" +#include "ini.h" +#include "Utility.h" +#include "HttpClient.h" +#include "JsonParser.h" + + +#include <vector> +#include <string> +#include <cstring> + +#include "TCPSocketConnection.h" +#include "TCPSocketServer.h" + +using namespace mbed_cc3000; + +typedef struct +{ + char startupimage[30]; + char webaddress[256]; + float imagedelay; +} configuration; + +typedef struct +{ + // Values read from DHT11 + double current_temperature; + double current_humidity; + double current_dewpoint; + // Values read from openweathermap.com + int weatherid; + int sunrise; + int sunset; + double temperature; + double humidity; + double pressure; + double windspeed; + double clouds; + std::string icon; + std::string location; + std::string description; + + void debug(Stream & strm) + { + strm.printf("Weather id : [%d]\r\n", weatherid); + strm.printf("Current temperature: [%0.2f C]\r\n", current_temperature); + strm.printf("Current humidity: [%0.2f%%]\r\n", current_humidity); + strm.printf("Dew Point : [%0.2f C]\r\n", current_dewpoint); + strm.printf("Temperature: [%0.2f C]\r\n", temperature); + strm.printf("Humidity : [%0.2f%%]\r\n", humidity); + strm.printf("Pressure : [%0.2fhpa]\r\n", pressure); + strm.printf("Wind Speed : [%%0.2f]\r\n", windspeed); + strm.printf("Cloud Coverage: [%0.2f]\r\n", clouds); + strm.printf("Location : [%s]\r\n", location.c_str()); + strm.printf("Description: [%s]\r\n", description.c_str()); + strm.printf("Icon id : [%s]\r\n", icon.c_str()); + } +} weather_info; + +/* Define ALL Hardware used here and their pin configuration */ +Serial pc(USBTX, USBRX); // tx, rx +DHT dht(D9, DHT11); +//DigitalOut conLed(D6); // PB_10 +DigitalIn shellSwitch(D6); // PB_0 (normally pulled high) +I2C i2c(I2C_SDA, I2C_SCL); // SDA, SCL +SDFileSystem sdcard(PB_15, PB_14, PB_13, PB_1, "sd"); // mosi, miso, sclk, cs, name +// the TFT is connected to SPI pin 5-7 +SPI_TFT_ILI9341 TFT(PC_12, PC_11, PC_10, PC_0, PC_2, PC_3,"TFT"); // mosi, miso, sclk, cs, reset, dc +DigitalOut lcdOn(PC_1); +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 + + +/** Globals **/ +std::vector<std::string> images; +char webdata[1024]; +configuration cfg; +weather_info winfo; +HeaderInfo info; + + +static int confighandler(void* user, const char* section, const char* name, + const char* value) +{ + configuration* pconfig = (configuration*)user; + + #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 + if (MATCH("rotator", "imagedelay")) { + pconfig->imagedelay = atof(value); + } else if (MATCH("weather", "webaddress")) { + strncpy(pconfig->webaddress, value, sizeof(pconfig->webaddress)); + } else if (MATCH("boot", "startupimage")) { + strncpy(pconfig->startupimage, value, sizeof(pconfig->startupimage)); + } else { + return 0; /* unknown section/name, error */ + } + return 1; +} + +/** + * \brief Setup interrupt priorities for Nucleo board + * \param none + * \return none + */ +void init() +{ + // First and last IRQ defined in stm32f401xe.h + int irqnum; + for(irqnum = SysTick_IRQn ; irqnum < SPI4_IRQn + 1 ; irqnum++) + NVIC_SetPriority((IRQn_Type)irqnum, 0x04); + + NVIC_SetPriority(SPI1_IRQn, 0x0); + NVIC_SetPriority(FPU_IRQn, 0x1); + NVIC_SetPriority(SPI2_IRQn, 0x2); + NVIC_SetPriority(SPI3_IRQn, 0x02); + NVIC_SetPriority(SysTick_IRQn, 0x3); +} + +/** + * \brief Initialize CC3000 + * \param none + * \return void + **/ +void init_cc3000() +{ + printf("Loading wifi startup settings ...\r\n"); + + printf("Initializing cc3000 wifi ...\r\n"); + wifi.init(); + printf("Connecting to AP ...\r\n"); + if (wifi.connect() == -1) { + printf("Failed to connect. Please verify connection details and try again. \r\n"); + } else { + printf("IP address: %s \r\n", wifi.getIPAddress()); + printf("Gateway address: %s \r\n", wifi.getGateway()); + set_ctrl_panel(1, 1); + } +} + +/** + * \brief Initialize LCD + * \param none + * \return void + **/ +void init_LCD() +{ + printf("Initializing LCD Screen ...\r\n"); + + lcdOn = 1; + + TFT.claim(stdout); + TFT.set_orientation(1); + TFT.background(Black); // set background to black + TFT.foreground(White); // set chars to white + TFT.cls(); // clear the screen + + + TFT.set_font((unsigned char*) Arial12x12); + TFT.locate(0,0); + +} +/** + * \brief Initialize switch/led panel on I2C bus + * \param none + * \return void + **/ +void init_i2cpanel() +{ + char cmd[2]; + // Setup direction reg for panel address 1 + cmd[0] = 0x00; // Last bit is input + cmd[1] = 0x00; + // Write to the command register + i2c.write(I2C_CTR_PANEL_ADDR, cmd, 2); + + // Setup direction reg for panel address 2 + cmd[0] = 0x01; + cmd[1] = 0x00; + + i2c.write(I2C_CTR_PANEL_ADDR, cmd, 2); + +} + +/** + * \brief Counter thread to test rtos + * \param arg arguments to the thread + * \return none + **/ +void counter_thread(void const *args) +{ + uint8_t count; + + while (true) + { + set_ctrl_panel(0, count); + + count++; + + osDelay(1000); + } +} +osThreadDef(counter_thread, osPriorityNormal, DEFAULT_STACK_SIZE); + + +int find_images(const char * root, const char * ext) +{ + DIR * dp; + struct dirent * dirp; + FILINFO fileInfo; + + dp = opendir(root); + while((dirp = readdir(dp)) != NULL) + { + if (sdcard.stat(dirp->d_name, &fileInfo) == 0) + { + if (!(fileInfo.fattrib & AM_DIR )) + { + std::string filename = dirp->d_name; + std::size_t found = filename.find(ext); + if (found!=std::string::npos) + { + std::string fullpathname = root; + fullpathname += "/"; + fullpathname += filename; + images.push_back(fullpathname); + } + } + } + } + closedir(dp); + + return images.size(); +} + +bool get_current_weather() +{ + // First fetch current weather conditions from sensor + pc.printf("Getting current conditions...\r\n"); + if(dht.readData() == ERROR_NONE) + { + float temperature = dht.ReadTemperature(CELCIUS); + float humidity = dht.ReadHumidity(); + float dewpoint = dht.CalcdewPoint(temperature, humidity); + + winfo.current_temperature = temperature; + winfo.current_humidity = humidity; + winfo.current_dewpoint = dewpoint; + + pc.printf("Temperature : %.2f\r\n", temperature); + pc.printf("Humidity : %.2f\r\n", humidity); + pc.printf("Dew Point : %.2f\r\n", dewpoint); + + return true; + } else + return false; +} + +bool get_weather_info() +{ + bool retval = false; + HttpClient client("test.com"); + + memset(webdata, 0, sizeof(webdata)); + + // Fetch page from openweather + pc.printf("\r\nTrying to fetch page [%s]... \r\n", cfg.webaddress); + int ret = client.get(cfg.webaddress, webdata, sizeof(webdata), info); + if (ret > 0) + { + using namespace JSON; + pc.printf("Page fetched successfully - read %d characters \r\n", strlen(webdata)); + pc.printf("Web Data [%s]\r\n", webdata); + + MVJSONReader reader(webdata); + // pc.printf("Result: %s \r\n", webdata); + if (reader.root->hasField("sys")) + { + winfo.sunrise = reader.root->getField("sys")->getFieldInt("sunrise"); + winfo.sunset = reader.root->getField("sys")->getFieldInt("sunset"); + winfo.location = reader.root->getFieldString("name"); + winfo.temperature = reader.root->getField("main")->getFieldDouble("temp") - 273.15; + winfo.pressure = reader.root->getField("main")->getFieldDouble("pressure"); + winfo.humidity = reader.root->getField("main")->getFieldDouble("humidity"); + winfo.windspeed = reader.root->getField("wind")->getFieldDouble("speed"); + winfo.clouds = reader.root->getField("clouds")->getFieldDouble("all"); + if (reader.root->getField("weather") != NULL) + if (reader.root->getField("weather")->size() > 0) + { + // we take only first element from list + winfo.weatherid = reader.root->getField("weather")->at(0)->getFieldInt("id"); + winfo.icon = reader.root->getField("weather")->at(0)->getFieldString("icon"); + winfo.description = reader.root->getField("weather")->at(0)->getFieldString("description"); + } + retval = true; + } + }else + retval = false; + + return retval; +} + +// Update LCD display based on weather info +void update_lcd(bool update_locale) +{ + + // TFT.cls(); + if (get_current_weather()) + { + // Use large fonts to display temperature + TFT.background(Black); + TFT.foreground(White); + TFT.locate(170, 120); + TFT.set_font((unsigned char *) Neu42x35); + TFT.printf("%.0f C",winfo.temperature); + + // At the bottom + TFT.fillrect(0,185,320,216,Blue); + TFT.background(Blue); + TFT.foreground(White); + TFT.set_font((unsigned char*) Arial28x28); + TFT.locate(0,187); + TFT.printf("%.0f%% Humidity", + winfo.current_humidity); + + TFT.locate(0, 218); + TFT.set_font((unsigned char *) Arial12x12); + TFT.background(Black); + TFT.foreground(White); + TFT.printf("Dew Point : %0.2fC", winfo.current_dewpoint); + } + + if (update_locale) + { + // Fill banner with white + TFT.background(White); + TFT.foreground(Black); + TFT.fillrect(0,0,320,100, White); + + // Load the graphic icon + std::string filename = "/sd/icons/" + winfo.icon + ".bmp"; + TFT.BMP_16(0,10, filename.c_str()); + + // Fill the header - top most of LCD with info + TFT.locate(100,20); + TFT.set_font((unsigned char *) Arial28x28); + TFT.background(White); // set background to black + TFT.foreground(Black); // set chars to white + + TFT.printf("%s", winfo.location.c_str()); + TFT.locate(100,60); + TFT.set_font((unsigned char *) Arial12x12); + capitalize_word_start(winfo.description); + TFT.printf("%s", winfo.description.c_str()); + } + + +} + +static const ShellCommand cmds[] = { + {"ls", cmd_ls}, + {"load", cmd_load}, + {"sensor", cmd_sensor}, + {"roll", cmd_rollimages}, + {NULL, NULL} +}; + +static const ShellConfig shell_cfg1 = { + (Serial *) &pc, + (ShellCommand *) cmds +}; + +int main() +{ + + // Set NVIC interrupt priorities + init(); + pc.baud(115200); + i2c.frequency(100000); + init_i2cpanel(); + + bool startShell = (shellSwitch.read() == 0); + pc.printf("Starting shell: [%s]\r\n", startShell ? "Yes":"No"); + + int numbmps = find_images("/sd", ".bmp"); + pc.printf("Found %d bmps in directory /sd\r\n", numbmps); + // Read the configuration file + pc.printf("Reading /sd/config.ini ...\r\n"); + if (ini_parse("/sd/config.ini", confighandler, &cfg) < 0) { + // Initialize the cfg + strcpy(cfg.webaddress, "http://192.168.1.75/hmap/booksearch.html"); + strcpy(cfg.startupimage, "boot.bmp"); + cfg.imagedelay = 1000; + } + + pc.printf("Initializing hardware ...\r\n"); + init_cc3000(); + + pc.printf("Starting counter leds ....\r\n"); + osThreadCreate(osThread(counter_thread), NULL); + + init_LCD(); + + + if (startShell) + { + pc.printf("Starting debug shell ...\r\n"); + shellStart(&shell_cfg1); + } + else + { +// pc.printf("Starting image rotator ...\r\n"); + unsigned int count = 0; + bool update_weather = true; + while(true) + { + // If we have an RTC, we can detect new day + if (update_weather && get_weather_info()) + { + winfo.debug(pc); + update_lcd(true); + } + else + update_lcd(false); + + wait(5.0); + count++; + if ((count % 10) == 0) + update_weather = true; + else + update_weather = false; + + + //heapinfo(&pc); +/* + for(std::vector<std::string>::iterator i = images.begin(); + i != images.end(); i++) + { + pc.printf("Loading image %s...\r\n", (*i).c_str()); + TFT.cls(); + int err = TFT.BMP_16(0,0, (*i).c_str()); + if (err != 1) TFT.printf(" - Err: %d", err); + + wait(1.0); + heapinfo(&pc); + } +*/ + } + } +} +