Demo code for a Wi-Fi controlled wall outlet that monitors light intensity, temperature, and motion and can control which plugs are supplied with power based off of user preference.

Dependencies:   BH1750 DHT11_Lib mbed

Fork of ECE4180_Lab4_ESP8266_IoT_Outlets by Deron Mai

Revision:
2:d4c6bc0f2dc4
Parent:
1:71ed1afbf344
Child:
3:f7febfa77784
--- a/main.cpp	Sun Feb 15 12:05:58 2015 +0000
+++ b/main.cpp	Thu Feb 19 23:47:54 2015 +0000
@@ -6,53 +6,58 @@
 Serial pc(USBTX, USBRX);
 Serial esp(PTE0, PTE1); // tx, rx
 
+DS18B20 thermom(A0, DS18B20::RES_12_BIT);
+
 // Standard Mbed LED definitions
 DigitalOut  led1(LED_RED);      // (PTB18)
 DigitalOut  led2(LED_GREEN);    // (PTB19)
 DigitalOut  led3(LED_BLUE);     // (PTD1)
 
 // Digital Out and In pins, can be configured to any suitable pin depending on Platform
-DigitalOut  Out1(PTC7);
-DigitalOut  Out2(PTC0);
-DigitalOut  Out3(PTC3);
+DigitalOut  Out1(D7);
+DigitalOut  Out2(D8);
+DigitalOut  Out3(D4);
 
-DigitalIn  In1(PTC12);
-DigitalIn  In2(PTC13);
-DigitalIn  In3(PTC16);
+DigitalIn  In1(A2);
+DigitalIn  In2(A3);
+DigitalIn  In3(A4);
 
-AnalogIn   BATin(PTC1);
-
-DS18B20 thermom(PTB0, DS18B20::RES_12_BIT);
+PwmOut speaker(D5);
+AnalogIn   BATin(A1);
 
 Timer t1;
 Timer t2;
 
 struct tm t;
 
-int buflen, DataRX, count, ended, servreq, timeout;
-int bufl, ipdLen, linkID, weberror;
+int buflen, DataRX, count, getcount, ended, servreq, timeout;
+int bufl, ipdLen, linkID, weberror, webcounter;
 float temperature, AdcIn, Ht; 
 float R1=100000, R2=10000; // resistor values to give a 10:1 reduction of measured AnalogIn voltage
 char Vcc[10];
 char Temp[10];
 char temp[10];
+char webcount[8];
+char lasthit[60];
 char timebuf[30];
 char type[16];
 char type1[16];
 char channel[2];
 char snd[256];
 char webdata[1024]; // This may need to be bigger depending on WEB browser used
-char buf[2048];     // Currently using 1407 characters, Increase this if more web page data added
+char buf[4096];     // Currently using 1407 characters, Increase this if more web page data added
 
 void SendCMD(),getreply(),ReadWebData(),startserver(),sendpage(),SendWEB(),sendcheck();
-void gettime(),gettemp(),getbattery(),setRTC();
+void gettime(),gettemp(),getbattery(),setRTC(),beep();
 
 // manual set RTC values
-int minute      =58;    // 0-59
-int hour        =11;    // 2-23
-int dayofmonth  =15;    // 1-31
+int minute      =13;    // 0-59
+int hour        =15;    // 2-23
+int dayofmonth  =19;    // 1-31
 int month       =2;     // 1-12
 int year        =15;    // last 2 digits
+
+int port        =90;  // set server port
  
 // Serial Interrupt read ESP data
 void callback() {    
@@ -65,38 +70,46 @@
     pc.baud(115200);
     esp.baud(115200);   // ESP8266 baudrate.
     if (time(NULL) < 1420070400) {setRTC();}    
-    
+    beep();
     startserver();
       
     while(1){        
         
         if(DataRX==1){
             ReadWebData();
+            beep();
             if (servreq == 1 && weberror == 0){sendpage();}    
             pc.printf(" IPD Data:\r\n\n Link ID = %d,\r\n IPD Header Length = %d \r\n IPD Type = %s\r\n", linkID, ipdLen, type);        
             pc.printf("\n\n  HTTP Packet: \n\n%s\n", webdata); 
             pc.printf("  Web Characters sent : %d\n\n", bufl);
             pc.printf("  -------------------------------------\n\n");
             esp.attach(&callback);
+            strcpy(lasthit, timebuf);
             servreq=0;               
-        }                               
+        }
+        if(t2.read()>900){startserver();} // restart server every 15 minutes after no activity in case of ESP lock out.                               
     }
 }    
 // Static WEB page    
 void sendpage()
 {          
-    gettemp();getbattery();gettime();
-// WEB page data    
+    gettemp();getbattery();gettime();   
     memset(buf, '\0', sizeof(buf));
-    strcpy(buf, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n");
-    strcat(buf, "<html><head><title>ESP8266 Mbed</title></head>\r\n");
-    strcat(buf, "<body>\r\n");
-    strcat(buf, "<h1>ESP8266 Mbed Web Controller</h1>\r\n");                        
-    strcat(buf, "<br /><hr>\r\n");
+    
+// WEB page data     
+    strcpy(buf, "<!DOCTYPE html>");
+    strcat(buf, "<html><head><title>ESP8266 Mbed</title></head>");
+    strcat(buf, "<body>");    
+    strcat(buf, "<div style=\"text-align:center; background-color:#F4F4F4; color:#00AEDB;\"><h1>ESP8266 Mbed Web Controller</h1>");   
+    strcat(buf, "Hit Count - ");
+    strcat(buf, webcount);
+    strcat(buf, "<br>Last Hit - ");
+    strcat(buf, lasthit);                     
+    strcat(buf, "</div><br /><hr>");
     strcat(buf, "<h3>Mbed RTC Time -  ");             
     strcat(buf, timebuf);
     strcat(buf, "</h3>\r\n");
-    strcat(buf, "<p><form method=\"POST\"><strong> Temperature:  <input type=\"text\" size=4 value=\"");
+    strcat(buf, "<p><form method=\"POST\"><strong> Temperature:  <input type=\"text\" size=6 value=\"");
     strcat(buf, Temp);
     strcat(buf, "\"> <sup>O</sup>C <form method=\"POST\"> <strong> Battery:  <input type=\"text\" size=4 value=\"");
     strcat(buf, Vcc);
@@ -122,20 +135,29 @@
     if(In2==0){strcat(buf, "<br><input type=\"radio\" name=\"In2\" value=\"0\" >  Digital In 2");}
         else{strcat(buf, "<br><input type=\"radio\" name=\"In2\" value=\"1\" checked>  Digital In 2");}           
     if(In3==0){strcat(buf, "<br><input type=\"radio\" name=\"In3\" value=\"0\" >  Digital In 3");}
-        else{strcat(buf, "<br><input type=\"radio\" name=\"In3\" value=\"1\" checked>  Digital In 3");}           
-    strcat(buf, "</strong><p><input type=\"submit\"></form></span>");
-    strcat(buf, "</body>\r\n</html>\r\n");   
+        else{strcat(buf, "<br><input type=\"radio\" name=\"In3\" value=\"1\" checked>  Digital In 3");}                  
+    strcat(buf, "</strong><p><input type=\"submit\" value=\"send-refresh\" style=\"background: #3498db;");    
+    strcat(buf, "background-image:-webkit-linear-gradient(top, #3498db, #2980b9);");    
+    strcat(buf, "background-image:linear-gradient(to bottom, #3498db, #2980b9);");
+    strcat(buf, "-webkit-border-radius:12;border-radius: 12px;font-family: Arial;color:#ffffff;font-size:20px;padding:");
+    strcat(buf, "10px 20px 10px 20px; border:solid #103c57 3px;text-decoration: none;"); 
+    strcat(buf, "background: #3cb0fd;");
+    strcat(buf, "background-image:-webkit-linear-gradient(top,#3cb0fd,#1a5f8a);"); 
+    strcat(buf, "background-image:linear-gradient(to bottom,#3cb0fd,#1a5f8a);");
+    strcat(buf, "text-decoration:none;\"></form></span>");
     strcat(buf, "<p/><h2>How to use:</h2><ul>");
     strcat(buf, "<li>Select the Radio buttons to control the digital out pins.</li>");
-    strcat(buf, "<li>Click 'Submit Query' to send.</li>");      
-    strcat(buf, "<li>Use the 'Submit Query' button to refresh the page.</li>"); 
+    strcat(buf, "<li>Click 'Send-Refresh' to send.</li>");      
+    strcat(buf, "<li>Use the 'Send-Refresh' button to refresh the data.</li>"); 
     strcat(buf, "</ul>");
+    strcat(buf, "</body></html>");    
 // end of WEB page data       
     bufl = strlen(buf); // get total page buffer length            
     sprintf(snd,"AT+CIPSEND=%s,%d\r\n", channel, bufl); // send IPD link channel and buffer character length.
     SendCMD();                                   
     wait_ms(100);                        
     SendWEB();  // send web page
+    memset(buf, '\0', sizeof(buf));
     sendcheck();              
 }
 
@@ -148,7 +170,7 @@
         getreply();
         if (strstr(buf, "SEND OK") != NULL) {weberror=0;}  // wait for valid SEND OK
         }
-    t2.stop();
+    t2.reset();
     if(weberror==1){
         pc.printf("\n\n\n ++++++++++ WEB Connect Error, restarting ...   ++++++++++\n\n");
         NVIC_SystemReset();}     
@@ -178,8 +200,10 @@
         sprintf(channel, "%d",linkID);        
         if (strstr(webdata, "GET") != NULL) {servreq=1;}
         if (strstr(webdata, "POST") != NULL) {servreq=1;}
+        webcounter++;
+        sprintf(webcount, "%d",webcounter);
         }
-            else {strcpy(webdata, buf);weberror=1;}
+            else {strcpy(webdata, buf);weberror=1;}         
     led3=1;
 }
 // Starts and restarts webserver if errors detected.
@@ -192,19 +216,22 @@
     pc.printf("++++++++++ Resetting ESP ++++++++++\r\n");  
     strcpy(snd,"AT+RST\r\n");
     SendCMD();
-    timeout=2000;
+    timeout=2000;getcount=336;
     getreply();
     if (strstr(buf, "ready") != NULL) {
         pc.printf("\n++++++++++ Starting Server ++++++++++\r\n");
         strcpy(snd, "AT+CIPMUX=1\r\n");  // set multiple connections. 
         SendCMD();
-        wait_ms(50);  
-        strcpy(snd, "AT+CIPSERVER=1,80\r\n"); // set to port 80, you can change this to what you want.
+        timeout=500;getcount=10;
+        getreply();
+        strcpy(snd, "AT+CIPSERVER=1,90\r\n");
+        //sprintf(snd,"AT+CIPSERVER=1,%d\r\n", port);
         SendCMD();
-        wait_ms(200); 
+        timeout=500;getcount=10;
+        getreply();
         pc.printf("\n Getting Server IP \r\n"); 
         strcpy(snd, "AT+CIFSR\r\n");
-        timeout=500;
+        timeout=1000;getcount=50;
         while(weberror==0){
             SendCMD();getreply();
             if (strstr(buf, "0.0.0.0") == NULL) {weberror=1;}  // wait for valid IP
@@ -212,7 +239,7 @@
         pc.printf("\n Enter WEB address in your browser \r\n\n");
         buf[strlen(buf) - 8] = '\0';                
         char* IP = buf + 5; 
-        sprintf(snd,"   http://%s:80", IP);
+        sprintf(snd,"   http://%s:%d", IP, port);
         pc.printf(snd); 
         while (esp.readable()){esp.getc();}    
         buflen=200;count=0;
@@ -224,7 +251,8 @@
         else{
             pc.printf("\n++++++++++ ESP8266 error, check power/connections ++++++++++\r\n");
             while(1){}
-            }  
+            }
+        t2.reset();t2.start();beep();      
 }    
 // ESP Command data send
 void SendCMD()
@@ -243,27 +271,25 @@
 void getreply()
 {    
     memset(buf, '\0', sizeof(buf));
-    t1.start();
+    t1.reset(); t1.start();
     ended=0;count=0;
-    while(!ended) {
+    while(t1.read_ms()< timeout && count < getcount) {
         if(esp.readable()) {
             buf[count] = esp.getc();count++;
             }
-        if(t1.read_ms() > timeout) {
-                ended = 1;t1.stop();t1.reset();
-            }
-        }   
+        }
+    t1.stop();      
 }
 // Analog in example
 void getbattery()
 {
     AdcIn=BATin.read(); 
-    Ht = (AdcIn*3.328*(R1+R2)/R2); // set the numeric to the exact MCU analog reference voltage for greater accuracy
+    Ht = (AdcIn*3.328f*(R1+R2)/R2); // set the numeric to the exact MCU analog reference voltage for greater accuracy
     sprintf(Vcc,"%2.3f",Ht);    
 }
 // Temperature example
 void gettemp()
-{
+{   
     temperature=thermom.GetTemperature();   // comment this out if no sensor connected
     //temperature = 21.357;                 // include for dummy value
     sprintf(Temp,"%3.3f",temperature);             
@@ -275,6 +301,14 @@
     strftime(timebuf,50,"%H:%M:%S %a %d %b %y", localtime(&seconds));               
 }
 
+void beep()
+{   
+    speaker.period(1.0/2000); // 2000hz period
+    speaker = 0.5; //50% duty cycle - max volume
+    wait_ms(60);
+    speaker=0.0; // turn off audio
+}
+
 void setRTC()
 {
             t.tm_sec = (0);             // 0-59