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.
Dependencies: mbed MbedJSONValue mbed-rtos 4DGL-uLCD-SE ESP8266NodeMCUInterface
main.cpp
- Committer:
- alexhrao
- Date:
- 2019-03-31
- Revision:
- 3:7bf41989ff8f
- Parent:
- 2:f7d19812bdc5
- Child:
- 4:55f0c303f56a
File content as of revision 3:7bf41989ff8f:
#include "mbed.h"
#include "uLCD_4DGL.h"
#include "ESP8266Interface.h"
#include "TCPSocketConnection.h"
#include "rtos.h"
#include "MbedJSONValue.h"
#include <string>
#define BUF_SIZE 4096
// We need this for being able to reset the MBED (similar to watch dogs)
extern "C" void mbed_reset();
// LCD Screen
uLCD_4DGL uLCD(p9, p10, p11);
Mutex lcd_lock;
// File System
LocalFileSystem fs("local");
// Bluetooth
RawSerial pc(USBTX, USBRX);
RawSerial dev(p28,p27);
Thread dev_thread;
// Error LED
DigitalOut err_led(LED1);
// WiFi
ESP8266Interface wifi(p13, p14, p15, 9600, 10000);
// Time
Thread time_thread;
// Weather
Thread weather_thread;
char weather_api_key[256];
// Location
char ip_api_key[256];
double latitude = 0;
double longitude = 0;
void time_updater() {
// We're not an interrupt, so take as much time as we need. Infinite loop
// but wait 1 second between each loop
struct tm* ltm;
time_t now;
now = time(NULL);
ltm = localtime(&now);
// Buffer for time string. Max length is 23:59 + \0
int max_time_len = 6;
char ftime[max_time_len];
int min = -1;
while (true) {
// if the minute has changed, update.
now = time(NULL);
ltm = localtime(&now);
if(ltm->tm_min != min) {
// Get the new time
strftime(ftime, max_time_len, "%H:%M", ltm);
// Update time! Lock the lcd mutex
lcd_lock.lock();
uLCD.text_width(2);
uLCD.text_height(2);
uLCD.text_string(ftime, 0, 2, FONT_8X8, GREEN);
// Done updating - unlock!
lcd_lock.unlock();
min = ltm->tm_min;
}
// Wait 1 second
Thread::wait(1.0f);
}
}
void weather_updater() {
// We can take as long as we want
return;
while (true) {
// get the weather
// first get the current weather
// Weather data is _long_
char forecast_buf[2];
TCPSocketConnection sck;
// http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6
sck.connect("api.openweathermap.org", 80);
char cmd[1024];
sprintf(cmd,
"GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
latitude, longitude, weather_api_key);
sck.send_all(cmd, strlen(cmd));
wait(10);
int buf_len = wifi.recv(forecast_buf, 16384 - 1, 0);
forecast_buf[buf_len] = '\0';
// Get current weather
char current_buf[8192];
sprintf(cmd,
"GET /data/2.5/forecast?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
latitude, longitude, weather_api_key);
sck.send_all(cmd, strlen(cmd));
wait(10);
buf_len = wifi.recv(current_buf, 8192 - 1, 0);
current_buf[buf_len] = '\0';
// we'll always want to update the LCD - don't worry about the previous
// weather
int curr_temp = 0;
int high_temp = 0;
int low_temp = 0;
char buf[12];
sprintf(buf, "%d %d/%d", curr_temp, high_temp, low_temp);
// lock
lcd_lock.lock();
uLCD.text_width(2);
uLCD.text_height(2);
// include null!
uLCD.text_string(buf, 0, 5, FONT_7X8, WHITE);
// done! unlock
lcd_lock.unlock();
}
}
void dev_recv() {
// Continually check if we have stuff...
char buf[1024];
int ind = 0;
while (true) {
while (true) {
// get stuff. If we encounter \r or \n, that's a complete command!
char tmp = dev.getc();
if (tmp == '\n' || tmp == '\r') {
break;
}
buf[ind++] = tmp;
Thread::wait(0.01);
}
buf[ind] = '\0';
// read command and respond
if (strcmp(buf, "reset") == 0) {
dev.printf("Are you sure? y/[n]\n");
}
buf[0] = '\0';
ind = 0;
//if (strcmp(buf, "reset") != 0) {
Thread::wait(0.01);
}
}
int main() {
// Set up bluetooth
dev.baud(9600);
pc.baud(9600);
// Tell user we're initializing...
lcd_lock.lock();
uLCD.cls();
uLCD.text_height(2);
uLCD.text_string("PLEASE WAIT", 0, 2, FONT_7X8, WHITE);
lcd_lock.unlock();
// Need to get wifi settings. If we don't have local file, then ask!
FILE* fid = NULL;//fopen("/local/settings.txt", "r");
char ssid[256];
char pass[256];
char api_key[256];
if (true) {
} else if (fid != NULL) {
// Read WiFi Settings
char settings_buf[1024];
// Guaranteed to be 256, 256, 512 AT MOST + two new lines
//
fgets(settings_buf, 1024, fid);
// find \n
int settings_ind = 0;
int counter = 0;
while (settings_buf[counter] != '\n') {
ssid[settings_ind++] = settings_buf[counter++];
}
ssid[settings_ind] = '\0';
settings_ind = 0;
counter++;
while (settings_buf[counter] != '\n') {
pass[settings_ind++] = settings_buf[counter++];
}
pass[settings_ind] = '\0';
settings_ind = 0;
counter++;
while (settings_buf[counter] != '\n') {
api_key[settings_ind++] = settings_buf[counter++];
}
api_key[settings_ind] = '\0';
fclose(fid);
} else {
lcd_lock.lock();
uLCD.cls();
uLCD.text_height(2);
uLCD.text_width(2);
uLCD.text_string("SEE", 0, 2, FONT_7X8, RED);
uLCD.text_string("DEVICE", 0, 5, FONT_7X8, RED);
lcd_lock.unlock();
// Ask!
dev.printf("Please provide the name of a WiFi Network\n");
// Wait for them to respond
while (!dev.readable()) {
wait(0.001);
}
int ind = 0;
// Read response
while (ind < 255) {
char tmp = dev.getc();
if (tmp == '\n' || tmp == '\r') {
break;
}
ssid[ind++] = tmp;
wait(0.01);
}
ssid[ind] = '\0';
// flush device
while (dev.readable()) {
dev.getc();
wait(0.01);
}
// Get the password
dev.printf("Please provide the password\n");
while (!dev.readable()) {
wait(0.001);
}
ind = 0;
while (ind < 255) {
char tmp = dev.getc();
if (tmp == '\n' || tmp == '\r') {
break;
}
pass[ind++] = tmp;
wait(0.01);
}
pass[ind] = '\0';
// Get the API key
dev.printf("Please provide the API key\n");
while (!dev.readable()) {
wait(0.001);
}
ind = 0;
while (ind < 255) {
char tmp = dev.getc();
if (tmp == '\n' || tmp == '\r') {
break;
}
api_key[ind++] = tmp;
wait(0.01);
}
api_key[ind] = '\0';
// Because this is a simple proof of concept, we store the password in
// plaintext. It should be noted, however, that you **should never do
// this in "real life"**
//fid = fopen("/local/settings.txt", "w");
//fprintf(fid, "%s\n%s\n%s\n", ssid, pass, api_key);
//fclose(fid);
}
char* tmp = "af9319bf6435ddd9bb640f763ff64d34";
for (int i = 0; i < strlen(tmp); i++) {
api_key[i] = tmp[i];
}
bool res = wifi.init();
//dev.printf("Reset: %d\n", res);
// Set up the WiFi Access Point
dev.printf("Connecting to WiFi %s with Password %s\n", ssid, pass);
res = wifi.connect("Alex's iPhone", "mbedlookhere");
if (!res) {
dev.printf("Connection Failed... Resetting Device\n");
err_led = 1;
mbed_reset();
}
dev.printf("Connected with IP Address: %s\n", wifi.getIPAddress());
// Get the time & location
dev.printf("Getting the current location...\n");
TCPSocketConnection tcp;
tcp.connect("api.ipstack.com", 80);
char tcp_cmd[256];
sprintf(tcp_cmd,
"GET /check?access_key=af9319bf6435ddd9bb640f763ff64d34 HTTP/1.1\r\nHost: api.ipstack.com\r\n\r\n");
tcp.send_all(tcp_cmd, strlen(tcp_cmd));
wait(10);
char buffer[BUF_SIZE];
int read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
buffer[read_len] = '\0';
MbedJSONValue parser;
parse(parser, buffer);
// for now, just print...
latitude = parser["latitude"].get<double>();
longitude = parser["longitude"].get<double>();
/*
TCPSocketConnection weather_sck;
//http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=6971e1ebfcc60f29c8dcc617c532b1b6
//http://api.openweathermap.org/data/2.5/forecast?lat=33.7485&lon=-84.3871&appid=6971e1ebfcc60f29c8dcc617c532b1b6
weather_sck.connect("api.openweathermap.org", 80);
sprintf(tcp_cmd,
"GET /data/2.5/weather?lat=%0.4f&lon=%0.4f&APPID=%s\r\nHost: api.openweathermap.org\r\n\r\n",
lat, lng, "6971e1ebfcc60f29c8dcc617c532b1b6");
sprintf(weather_api_key,
"%s", "6971e1ebfcc60f29c8dcc617c532b1b6");
weather_sck.send_all(tcp_cmd, strlen(tcp_cmd));
wait(15);
int read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
buffer[read_len] = '\0';
dev.printf(buffer);
*/
// dev.printf("Connection: %d\n", con_res);
//sprintf
//int con_res = weather_sck.connect("api.weather.gov", 443);
// dev.printf("Connection: %d\n", con_res);
//sprintf(tcp_cmd,
// "GET /points/%0.4f,%0.4f HTTP/1.1\r\nHost: api.weather.gov\r\n\r\n",
// lat, lng);
//weather_sck.send_all(tcp_cmd, strlen(tcp_cmd));
//wait(5);
//wait(10);
//int read_len = wifi.recv(buffer, BUF_SIZE - 1, 0);
//buffer[read_len] = '\0';
//dev.printf(buffer);
set_time(1256729737);
// Clear the LCD Screen first
lcd_lock.lock();
uLCD.cls();
lcd_lock.unlock();
// Now that we know what time it is, set up our Time Thread
time_thread.start(time_updater);
// Make the request to get the forecast link
// Now, make a single request to nws and get the forecast link - we can
// store this link for later!
// Start up weather service!
//weather_thread.start(weather_updater);
//weather_ticker.attach(&weather_tick, 900000.0f);
// Listen on bluetooth.
dev_thread.start(dev_recv);
dev.printf("Hello, World!\n");
time_t prev_time = time(NULL);
while(true) {
time_t curr_time = time(NULL);
// if it's been an hour (divide by 3600 >= 60), pause and get weather:
if (((int)(curr_time - prev_time) / 3600) >= 60) {
//weather_updater();
prev_time = curr_time;
}
err_led = !err_led;
//dev.printf("Connection Status: %d\n", wifi.is_connected());
wait(0.5);
}
}