Edison Carrick / Mbed 2 deprecated Wifi_Alarm_Sunrise_Simulator

Dependencies:   mbed

Fork of huzzah_helloWorld by ECE 4180 Team Who

main.cpp

Committer:
ecarrick
Date:
2016-03-18
Revision:
3:072c63f44572
Parent:
2:f01835b2e4f7
Child:
4:80b814538fe6

File content as of revision 3:072c63f44572:

#include "mbed.h"
#include <string> 
#include <sstream>
#include <stdlib.h>

Serial pc(USBTX, USBRX);
Serial esp(p28, p27); // tx, rx
DigitalOut reset(p26);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
DigitalIn  pb(p10);
PwmOut     light(p21);

Ticker alarmChecker;
bool alarmFired = false;
int alarmHour = 8; // hard configured start alarm time
int alarmMin = 15;
int alarmDur = 15; // alarm will execute at 8:00am and brighten for 15 min
string data;
Timer t;
time_t rtc;
struct tm *tp;
   
 
int  count,ended,timeout;
char buf[2024];
char snd[1024];
char val[2];
 
char ssid[32] = "ssid";     // enter WiFi router ssid inside the quotes
char pwd [32] = "Password"; // enter WiFi router password inside the quotes
 
void SendCMD(),getreply(),ESPhttp(),ESPsetbaudrate(), sendConfig(), ESPreset(), sendNTPFunction(), updateNTP(), getUtime(), startSunrise(float d);

// check the time in seconds, compare to the alarm time
// if the alarm has fired, then don't re-fire once done
// wait until the next day (midnight) to reset the fire status
void alarmCheck(){
        rtc = time(NULL);
        tp = localtime(&rtc);
        led1=1;
        if(!alarmFired){
            printf("hr: %d  min:%d\r\n", tp->tm_hour, tp->tm_min);
            int daystamp = tp->tm_hour * 3600 + tp->tm_min * 60;
            int alarmstamp = alarmHour * 3600 + alarmMin * 60 - (alarmDur * 60);
            pc.printf("%d - %d = %d\r\n", alarmstamp, daystamp, alarmstamp - daystamp);
            if( (alarmstamp - daystamp) <= 0){
                // time to start the wake up sequence
                startSunrise((float)(alarmDur*60));
                alarmFired = true;
            }
        } else{
            if(tp->tm_hour == 0) // wait until midnight
                alarmFired = false;
        }
        wait(1);
        led1=0;
    
}

void flush(){
 while(esp.readable()) {
        char tmp = esp.getc();
        data += tmp;
        pc.putc(tmp);
 }
}
 void dev_recv()
{
    led1 = !led1;
    timeout=2;
    getreply();
    pc.printf("%s\n\n", buf);
    char * location = strstr(buf, "GET /?");
    if(location != NULL){
        //pc.printf("%d\n", location - buf);
        char * hour = strstr(buf, "h=");
        char * min  = strstr(buf, "m=");
        char * dur  = strstr(buf, "d=");
        if(hour != NULL && min != NULL && dur != NULL){
            strncpy(val, hour+2,2);
            alarmHour = atoi(val) %24;
            strncpy(val, min+2,2);
            alarmMin = atoi(val) %60;
            strncpy(val, dur+2,2);
            alarmDur = atoi(val);
            
            pc.printf("New config: hrs %d min %d duration %d", alarmHour, alarmMin, alarmDur);
            sendConfig();
            
        }
    }
}
 
void pc_recv()
{
    led4 = !led4;
    while(pc.readable()) {
        esp.putc(pc.getc());
    }
}
 
 
int main()
{

    pb.mode(PullDown);
    light.period(0.005); //200Hz to eliminate flicker
    reset=0; //hardware reset for 8266
    pc.baud(115200);  // set what you want here depending on your terminal program speed
    pc.printf("\f\n\r-------------ESP8266 Hardware Reset-------------\n\r");
    wait(0.5);
    reset=1;
    timeout=1;
    getreply();
    
    // RESET wifi module and and connect to the wifi
    ESPreset();
    
    // send the NTP function to wifi module
    sendNTPFunction();
    
    rtc = time(NULL);
    tp = localtime(&rtc);

    
    while(tp->tm_year ==0){
        updateNTP();
        wait(3);
        getUtime();
        wait(1);
    }
    
    led3=1;
    
    // test the light to make sure it works
    for(float i=0.0;i<1.0;i+=0.1){
        light=i;
        wait(0.5);
    }
    light = 0;
 
    // set up the HTTP server 
    ESPhttp();
        
        // uncomment to be able to send commands to the wifi module directly through the PC COM port
    //pc.attach(&pc_recv, Serial::RxIrq);
    // set up an interupt to listen for data sent by the wifi module
    // allows the configuration to be updated.
    esp.attach(&dev_recv, Serial::RxIrq);
    
    // print the time to console to verify updated
    rtc = time(NULL);
    pc.printf("%s\r\n", ctime(&rtc));
    led1=0;led2=0;led3=0;led4=0;
    tp = localtime(&rtc);
    printf("hr: %d  min:%d\r\n", tp->tm_hour, tp->tm_min);
    
    // set up an interupt checker to check the alarm status every minute.
    alarmChecker.attach(&alarmCheck, 60);
    while(1) {
        sleep(); // low power sleep to conserve power inbetween checks
    }
 
}

// brighten the light over the duration period length
// keep the light on for 2 minutes, then shut it off
void startSunrise(float d){
    for(float i=0.0; i < 1.0; i += (1.0/d)){
        light = i;   
        pc.printf("%f\n", i);
        wait(1);
    }
    light = 1.0;
    
    wait(120);
    light = 0;
 
}
 
// Sets new ESP8266 baurate, change the esp.baud(xxxxx) to match your new setting once this has been executed
// This is an important configuration change. By setting the last argument to zero, it stops the module from echoing 
// commands back, allowing us to send commands and read only the value
void ESPsetbaudrate()
{
    strcpy(snd, "uart.setup(0, 9600, 8, 0, 1, 0)\r\n");   // change the numeric value to the required baudrate
    SendCMD();
    timeout=2;
    getreply();
    pc.printf(buf);
}

void ESPreset(){
    pc.printf("---------- Reset & get Firmware ----------\r\n");
    strcpy(snd,"node.restart()\r\n");
    SendCMD();
    timeout=2;
    getreply();
    pc.printf(buf);
    
    ESPsetbaudrate();
    
    
    pc.printf("\n---------- Connecting to AP ----------\r\n");
    //pc.printf("ssid = %s   pwd = %s\r\n",ssid,pwd);
    strcpy(snd, "wifi.sta.config(\"");
    strcat(snd, ssid);
    strcat(snd, "\",\"");
    strcat(snd, pwd);
    strcat(snd, "\")\r\n");
    SendCMD();
    timeout=3;
    getreply();
    pc.printf(buf);
 
    wait(5);
 
    pc.printf("\n---------- Get IP's ----------\r\n");
    strcpy(snd, "print(wifi.sta.getip())\r\n");
    SendCMD();
    timeout=2;
    getreply();
    pc.printf(buf);
 
    wait(1);
 
    pc.printf("\n---------- Get Connection Status ----------\r\n");
    strcpy(snd, "print(wifi.sta.status())\r\n");
    pc.printf("%s", snd);
    SendCMD();
    timeout=2;
    getreply();
    pc.printf(buf);
    
    
}
 
void ESPhttp()
{
     
          pc.printf("\n---------- Setting up http server ----------\r\n");
          
          sendConfig();
          
        strcpy(snd, "srv=net.createServer(net.TCP)\r\n");
        SendCMD();
        wait(1);
        strcpy(snd, "srv:listen(80,function(conn)\r\n");
        SendCMD();
        wait(1);
        strcpy(snd, "conn:on(\"receive\",function(conn,payload)\r\n");
        SendCMD();
        wait(1);
 
        strcpy(snd, "print(payload)\r\n");
        SendCMD();
        wait(1);
        
        
        strcpy(snd, "conn:send(\"<!DOCTYPE html>\")\r\n");
        SendCMD();
      wait(1);
        
        strcpy(snd, "conn:send(\"<html>\")\r\n");
        SendCMD();
      wait(1);
        
        strcpy(snd, "conn:send(\"<h1>Configure Sunrise Alarm</h1><br><br><form method='get'>Wake up at: <input name=h value='\")\r\n");
        SendCMD();
        wait(1);
        
        strcpy(snd, "conn:send(hour)\r\n");
        SendCMD();
        wait(1);
        
        strcpy(snd, "conn:send(\"'> Hours and <input name=m value='\")\r\n");
        SendCMD();
        wait(1);
        
        strcpy(snd, "conn:send(min)\r\n");
        SendCMD();
        wait(1);
        
        strcpy(snd, "conn:send(\"'> minutes <br> <br> Start sunrise <input name=d value='\")\r\n");
        SendCMD();
        wait(1);
        
        strcpy(snd, "conn:send(dur)\r\n");
        SendCMD();
        wait(1);
        
        strcpy(snd, "conn:send(\"'> minutes before <input type=submit value='submit'></form>\")\r\n");
        SendCMD();
        wait(1);
        
        strcpy(snd, "conn:send(\"</html>\")\r\n");
    SendCMD();
    wait(1);
        
        strcpy(snd, "end)\r\n");
    SendCMD();
    wait(1);
        
        strcpy(snd, "conn:on(\"sent\",function(conn) conn:close() end)\r\n");
    SendCMD();
    wait(1);
        strcpy(snd, "end)\r\n");
    SendCMD();
    
    flush();

    pc.printf("\r\nDONE\r\n");
}
 
void SendCMD()
{
    pc.printf("%s", snd);
    esp.printf("%s", snd);
}
 
void getreply()
{
    memset(buf, '\0', sizeof(buf));
    t.start();
    ended=0;
    count=0;
    while(!ended) {
        if(esp.readable()) {
            buf[count] = esp.getc();
            count++;
        }
        if(t.read() > timeout) {
            ended = 1;
            t.stop();
            t.reset();
        }
    }
}
 
void sendConfig()
{
    stringstream strs;
    stringstream strs1;
    stringstream strs2;
    
    strcpy(snd, "hour=");
    SendCMD();
    strs << alarmHour;
    string temp_str = strs.str();
    char const* pchar = temp_str.c_str();
    strcpy(snd, pchar);
    SendCMD();
    strcpy(snd, "\r\n");
    SendCMD();
    wait(1);
    
    
    strcpy(snd, "min=");
    SendCMD();
    strs1 << alarmMin;
    temp_str = strs1.str();
    pchar = temp_str.c_str();
    strcpy(snd, pchar);
    SendCMD();
    strcpy(snd, "\r\n");
    SendCMD();
    wait(1);
    
    
    
    strcpy(snd, "dur=");
    SendCMD();
    strs2 << alarmDur;
    temp_str = strs2.str();
    pchar = temp_str.c_str();
    strcpy(snd, pchar);
    SendCMD();
    strcpy(snd, "\r\n");
    SendCMD();
    wait(1);
}

void sendNTPFunction()
{
    wait(5);
         
    pc.printf("\n---------- Setting up NTp Client on Wifi Module ----------\r\n");
   
    strcpy(snd, "timezone = -4\r\n");
        SendCMD();
        wait(2);
    strcpy(snd, "request=string.char(227,0,6,236,0,0,0,0,0,0,0,0,49,78,49,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)\r\n");
        SendCMD();
        wait(4);
    
    strcpy(snd, "time = 0\r\n");
        SendCMD();
        wait(1);
    strcpy(snd, "sk=net.createConnection(net.UDP, 0)\r\n");
        SendCMD();
        wait(1);
  
    strcpy(snd, "sk:on(\"receive\", function(sck, payload)\r\n");
        SendCMD();
        wait(1);
    strcpy(snd, "print(\"YAY!\")\r\n");
        SendCMD();
        wait(1);
    strcpy(snd, "local highw,loww,ntpstamp\r\n");
        SendCMD();
        wait(1);
    strcpy(snd, "highw = payload:byte(41) * 256 + payload:byte(42)\r\n");
        SendCMD();
        wait(1);
    strcpy(snd, "loww = payload:byte(43) * 256 + payload:byte(44)\r\n");
        SendCMD();
        wait(1);
    strcpy(snd, "ntpstamp=( highw * 65536 + loww ) + ( timezone* 3600)\r\n");
        SendCMD();
        wait(1);
    strcpy(snd, "time = ntpstamp - 1104494400 - 1104494400\r\n");
        SendCMD();
        wait(1);
    strcpy(snd, "print(time)\r\n");
        SendCMD();
        wait(1);
 
    strcpy(snd, "sck:close()\r\n");
        SendCMD();
        wait(1);
 
    strcpy(snd, "end )\r\n");
        SendCMD();
        wait(1);
 
    flush();       
    wait(15);
    //updateNTP();  
}
// this function executes the connection to the NTP server
// saving the time stamp into a local variable on the wifi module to be read
void updateNTP(){
    flush();
    strcpy(snd, "sk:connect(123,\"104.232.3.3\")\r\n");
        SendCMD();
        wait(3);
    strcpy(snd, "sk:send(request)\r\n");
        SendCMD();
        wait(4);
    timeout=3;
    getreply();
    pc.printf(buf);
    //getUtime();
}
// This function calls the wifi module to output the time stamp and save it to the local clock
// This should be executed right after updateNTP to reduce the delay in getting the clock value 
// and setting the clock
void getUtime(){
    flush();
    strcpy(snd, "print(time)\r\n");
        SendCMD();
        wait(1);
    timeout=5;
    getreply();
    pc.printf(buf);
    int utime = atoi(buf);
    if(utime != NULL)
        set_time(utime);
    time_t seconds = time(NULL);
    pc.printf("Time as a basic string = %s", ctime(&seconds));
}