Gina Holden / Mbed 2 deprecated IoTAlarmSystem

Dependencies:   PinDetect mbed wave_player FATFileSystem

Fork of ESP8266-WEB-Mbed-LPC1768-Controller by jim hamblen

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // ECE410 Lab 4 Alarm System Holden&Wasserman
00002 /*
00003 The following describes an Mbed IoT Alarm system. A push button is pressed to signify 
00004 an “open door”.  The user accesses a web page that displays the statuses of the Mbed Alarm System. 
00005 The webpage displays the status of the door, as well as the time, and the background indicates the
00006 alarm state. Once the door is opened, the user has a time limit to turn off the alarm or it will sound. 
00007  Once the correct code is keyed in, the alarm will shut off. This status is also displayed on the webpage. 
00008 */
00009 //Webserver code based off: ESP8266-WEB-Mbed-LPC1768-Controller
00010 
00011 //Further work: get rtos working to play a sound on the speaker for the alarm. Add more detailed states that
00012 //allow the user to key in the code before the alarm sounds. Allow user to turn off alarm from webpage.
00013 
00014 #include "mbed.h"
00015 #include "SDFileSystem.h"
00016 #include "wave_player.h"
00017 #define twilight_WAVFILE        "/sd/wavfiles/twilight_zone_x.wav"
00018 #include "PinDetect.h"
00019 #include <mbed.h>
00020 #include <mpr121.h>
00021 #include <string>
00022 
00023 // Standard Mbed LED definitions
00024 DigitalOut  led1(LED1);      
00025 DigitalOut  led2(LED2);   
00026 DigitalOut  led3(LED3);     
00027 DigitalOut  led4(LED4);
00028 
00029 //wifi chip
00030 Serial pc(USBTX, USBRX);
00031 Serial esp(p28, p27); // tx, rx
00032 DigitalOut  reset(p25);
00033 
00034 //timer for alarm countdown
00035 Ticker alarmTimer;
00036 float numSecondsRemaining = 30;
00037 
00038 // interrupt pin for keypad
00039 InterruptIn interrupt(p26);
00040 // Setup the i2c bus on pins 9 and 10 keypad
00041 I2C i2c(p9, p10);
00042 // Setup the Mpr121: touch sensor
00043 // constructor(i2c object, i2c address of the mpr121)
00044 Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);
00045 
00046 //door is triggered by a pushbutton
00047 // no external PullUp resistor needed
00048 // Pushbutton from P12 to GND.
00049 // A pb falling edge (hit) generates an interrupt and activates the interrupt routine
00050 PinDetect doorPB(p12);
00051 //door status variable
00052 enum doorStatus { OPEN, CLOSED };
00053 doorStatus doorStatus = CLOSED;
00054 
00055 //alarm status variable
00056 enum alarmStatus { SOUNDING, OFF };
00057 alarmStatus alarm1Status = OFF;
00058 
00059 //we need to get rtos working for this :( 
00060 PwmOut speaker(p21);
00061 
00062 //timeout timer for getreply()
00063 Timer t1;
00064 //timeout timer for getcheck()
00065 Timer t2;
00066 
00067 //struct used for RTC
00068 struct tm t;
00069 
00070 int bufflen, DataRX, count, getcount, replycount, servreq, timeout;
00071 int bufl, ipdLen, linkID, weberror, webcounter;
00072 char pwd[] = "1234";
00073 char enterpwd[100] = "";
00074 char secondsRemaining[10];
00075 char webcount[8];
00076 char lasthit[30];
00077 char timebuf[30];
00078 char type[16];
00079 char type1[16];
00080 char channel[2];
00081 char cmdbuff[32];
00082 char replybuff[1024];
00083 char webdata[1024]; // This may need to be bigger depending on WEB browser used
00084 char webbuff[4096];     // Currently using 1986 characters, Increase this if more web page data added
00085 
00086 void SendCMD(),getreply(),ReadWebData(),startserver(),sendpage(),SendWEB(),sendcheck();
00087 void gettime(),setRTC();
00088 
00089 void timerExpired() //called every second once door is opened
00090 {
00091     numSecondsRemaining--;
00092     if (numSecondsRemaining == 0) {   //your time to disable the alarm is up. sound alarm!
00093         alarmTimer.detach();
00094         alarm1Status = SOUNDING;
00095     }
00096     sprintf(secondsRemaining, "%2.0f",numSecondsRemaining);
00097 }
00098 
00099 void pb_hit_callback (void) //door
00100 {
00101     pc.printf("pushbutton hit!\r\n");
00102     pc.printf("door is %s \r\n", doorStatus);
00103     if (doorStatus == OPEN)
00104         doorStatus = CLOSED;
00105     else if (doorStatus == CLOSED) {
00106         doorStatus = OPEN;
00107         //start counting every second
00108         alarmTimer.attach(&timerExpired, 1.0); 
00109     }
00110     wait(.1);
00111 }
00112 
00113 
00114 // manual set RTC values
00115 int minute      =00;    // 0-59
00116 int hour        =12;    // 2-23
00117 int dayofmonth  =26;    // 1-31
00118 int month       =8;     // 1-12
00119 int year        =15;    // last 2 digits
00120 
00121 int port        =80;  // set server port
00122 int SERVtimeout =5;    // set server timeout in seconds in case link breaks.
00123 
00124 // Serial Interrupt read ESP data
00125 void callback()
00126 {
00127     while (esp.readable()) {
00128         webbuff[count] = esp.getc();
00129         count++;
00130     }
00131     if(strlen(webbuff)>bufflen) {
00132         DataRX=1;
00133     }
00134 }
00135 
00136 // Key hit/release interrupt routine
00137 void fallInterrupt()
00138 {
00139     int key_code=0;
00140     int i=0;
00141     int value=mpr121.read(0x00);
00142     value +=mpr121.read(0x01)<<8;
00143     // puts key number out to LEDs for demo
00144     for (i=0; i<12; i++) {
00145         if (((value>>i)&0x01)==1) key_code=i+1;
00146     }
00147     if (key_code == 0)
00148     return;
00149     else key_code--;
00150     led4=key_code & 0x01;
00151     led3=(key_code>>1) & 0x01;
00152     led2=(key_code>>2) & 0x01;
00153     led1=(key_code>>3) & 0x01;
00154     char result[10];
00155     //convert float to cstring
00156     sprintf(result,"%d",key_code);
00157     pc.printf("result: %s\r\n", result);
00158     //concatenate to the end
00159     strcat(enterpwd,result);
00160     pc.printf("enterpwd: %s\r\n",enterpwd);
00161     //only compares the first four values entered. future work: make a clear/reset option
00162     if((enterpwd[0]==pwd[0]) && (enterpwd[1]==pwd[1]) && (enterpwd[2]==pwd[2]) && (enterpwd[3]==pwd[3])){
00163         alarm1Status=OFF;
00164         alarmTimer.detach();
00165         pc.printf("correct!\r\n");
00166     }
00167 }
00168 
00169 
00170 int main()
00171 {
00172     //attach interrupt for keypad
00173     interrupt.fall(&fallInterrupt);
00174     interrupt.mode(PullUp);
00175 
00176     doorPB.mode(PullUp);
00177     // Delay for initial pullup to take effect
00178     wait(.01);
00179     // Attach the address of the interrupt handler routine for pushbutton
00180     doorPB.attach_deasserted(&pb_hit_callback);
00181     doorPB.setSampleFrequency();
00182     reset=0;
00183     pc.baud(115200);
00184     pc.printf("\f\n\r------------ ESP8266 Hardware Reset --------------\n\r");
00185     wait(0.5);
00186     reset=1;
00187     timeout=6000;
00188     getcount=500;
00189     getreply();
00190     // ESP8266 baudrate. Maximum on KLxx' is 115200, 230400 works on K20 and K22F
00191     esp.baud(115200);  
00192     if (time(NULL) < 1420070400) {
00193         setRTC();
00194     }
00195     startserver();
00196     while(1) {
00197         if(DataRX==1) {
00198             ReadWebData();
00199             if (servreq == 1 && weberror == 0) {
00200                 sendpage();
00201             }
00202             esp.attach(&callback);
00203             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);
00204             pc.printf("\n\n  HTTP Packet: \n\n%s\n", webdata);
00205             pc.printf("  Web Characters sent : %d\n\n", bufl);
00206             pc.printf("  -------------------------------------\n\n");
00207             strcpy(lasthit, timebuf);
00208             servreq=0;
00209         }
00210     }
00211 }
00212 
00213 
00214 // Static WEB page
00215 void sendpage()
00216 {
00217     gettime();
00218     // WEB page data
00219     strcpy(webbuff, "<!DOCTYPE html>");
00220     strcat(webbuff, "<html><head><title>ESP8266 Mbed LPC1768</title></head>");
00221     if(alarm1Status == SOUNDING) {
00222         strcat(webbuff, "<body style=\"background-color:#FF0000;\" >");
00223     } else if (alarm1Status==OFF) {
00224         strcat(webbuff, "<body style=\" background-color:#32CD32;\" >");
00225     }
00226     strcat(webbuff, "<div style=\"text-align:center; background-color:#F4F4F4; color:#00AEDB;\"><h1>Mbed Alarm System</h1>");
00227     strcat(webbuff, "Hit Count - ");
00228     strcat(webbuff, webcount);
00229     strcat(webbuff, "<br>Last Hit - ");
00230     strcat(webbuff, lasthit);
00231     strcat(webbuff, "</div><br /><hr>");
00232     strcat(webbuff, "<h3>Mbed RTC Time -&nbsp&nbsp");
00233     strcat(webbuff, timebuf);
00234     strcat(webbuff, "</h3>\r\n");
00235     strcat(webbuff, "<p><form method=\"POST\"><strong> Door Status:&nbsp&nbsp<input type=\"text\" size=6 value=\"");
00236     if(doorStatus == CLOSED)
00237         strcat(webbuff, "CLOSED");
00238     else if(doorStatus == OPEN)
00239         strcat(webbuff, "OPEN");
00240     strcat(webbuff, "\"> </sup> <form method=\"POST\"> <strong> &nbsp&nbspSeconds Remaining:&nbsp&nbsp<input type=\"text\" size=4 value=\"");
00241     strcat(webbuff, secondsRemaining);
00242     strcat(webbuff, "\"> </sup>");
00243     strcat(webbuff, "</strong><p><input type=\"submit\" value=\"send-refresh\" style=\"background: #3498db;");
00244     strcat(webbuff, "background-image:-webkit-linear-gradient(top, #3498db, #2980b9);");
00245     strcat(webbuff, "background-image:linear-gradient(to bottom, #3498db, #2980b9);");
00246     strcat(webbuff, "-webkit-border-radius:12;border-radius: 12px;font-family: Arial;color:#ffffff;font-size:20px;padding:");
00247     strcat(webbuff, "10px 20px 10px 20px; border:solid #103c57 3px;text-decoration: none;");
00248     strcat(webbuff, "background: #3cb0fd;");
00249     strcat(webbuff, "background-image:-webkit-linear-gradient(top,#3cb0fd,#1a5f8a);");
00250     strcat(webbuff, "background-image:linear-gradient(to bottom,#3cb0fd,#1a5f8a);");
00251     strcat(webbuff, "text-decoration:none;\"></form></span>");
00252     strcat(webbuff, "<p/><h2>How to use:</h2><ul>");
00253     strcat(webbuff, "<li>Background color reflects alarm state. Green is good red is bad. </li>");
00254     strcat(webbuff, "<li>You can refresh the page with the browser button or send/refresh.</li>");
00255     strcat(webbuff, "<li>Seconds remaining tells you how much time before alarm sounds</li>");
00256     strcat(webbuff, "</ul>");
00257     strcat(webbuff, "</body></html>");
00258 // end of WEB page data
00259     bufl = strlen(webbuff); // get total page buffer length
00260     sprintf(cmdbuff,"AT+CIPSEND=%d,%d\r\n", linkID, bufl); // send IPD link channel and buffer character length.
00261     timeout=200;
00262     getcount=7;
00263     SendCMD();
00264     getreply();
00265     SendWEB();  // send web page
00266     memset(webbuff, '\0', sizeof(webbuff));
00267     sendcheck();
00268 }
00269 
00270 //  wait for ESP "SEND OK" reply, then close IP to load web page
00271 void sendcheck()
00272 {
00273     weberror=1;
00274     timeout=500;
00275     getcount=24;
00276     t2.reset();
00277     t2.start();
00278     while(weberror==1 && t2.read() <5) {
00279         getreply();
00280         if (strstr(replybuff, "SEND OK") != NULL) {
00281             weberror=0;   // wait for valid SEND OK
00282         }
00283     }
00284     if(weberror==1) { // restart connection
00285         strcpy(cmdbuff, "AT+CIPMUX=1\r\n");
00286         timeout=500;
00287         getcount=10;
00288         SendCMD();
00289         getreply();
00290         pc.printf(replybuff);
00291         sprintf(cmdbuff,"AT+CIPSERVER=1,%d\r\n", port);
00292         timeout=500;
00293         getcount=10;
00294         SendCMD();
00295         getreply();
00296         pc.printf(replybuff);
00297     } else {
00298         sprintf(cmdbuff, "AT+CIPCLOSE=%s\r\n",channel); // close current connection
00299         SendCMD();
00300         getreply();
00301         pc.printf(replybuff);
00302     }
00303     t2.reset();
00304 }
00305 
00306 // Reads and processes GET and POST web data
00307 void ReadWebData()
00308 {
00309     wait_ms(200);
00310     esp.attach(NULL);
00311     count=0;
00312     DataRX=0;
00313     weberror=0;
00314     memset(webdata, '\0', sizeof(webdata));
00315     int x = strcspn (webbuff,"+");
00316     if(x) {
00317         strcpy(webdata, webbuff + x);
00318         weberror=0;
00319         int numMatched = sscanf(webdata,"+IPD,%d,%d:%s", &linkID, &ipdLen, type);
00320         sprintf(channel, "%d",linkID);
00321         if (strstr(webdata, "GET") != NULL) {
00322             servreq=1;
00323         }
00324         if (strstr(webdata, "POST") != NULL) {
00325             servreq=1;
00326         }
00327         webcounter++;
00328         sprintf(webcount, "%d",webcounter);
00329     } else {
00330         memset(webbuff, '\0', sizeof(webbuff));
00331         esp.attach(&callback);
00332         weberror=1;
00333     }
00334 }
00335 // Starts and restarts webserver if errors detected.
00336 void startserver()
00337 {
00338     gettime();
00339     pc.printf("\n\n RTC time   %s\r\n\n",timebuf);
00340     pc.printf("++++++++++ Resetting ESP ++++++++++\r\n");
00341     strcpy(cmdbuff,"AT+RST\r\n");
00342     timeout=8000;
00343     getcount=1000;
00344     SendCMD();
00345     getreply();
00346     pc.printf(replybuff);
00347     pc.printf("%d",count);
00348     if (strstr(replybuff, "OK") != NULL) {
00349         pc.printf("\n++++++++++ Starting Server ++++++++++\r\n");
00350         strcpy(cmdbuff, "AT+CIPMUX=1\r\n");  // set multiple connections.
00351         timeout=500;
00352         getcount=20;
00353         SendCMD();
00354         getreply();
00355         pc.printf(replybuff);
00356         sprintf(cmdbuff,"AT+CIPSERVER=1,%d\r\n", port);
00357         timeout=500;
00358         getcount=20;
00359         SendCMD();
00360         getreply();
00361         pc.printf(replybuff);
00362         wait(1);
00363         sprintf(cmdbuff,"AT+CIPSTO=%d\r\n",SERVtimeout);
00364         timeout=500;
00365         getcount=50;
00366         SendCMD();
00367         getreply();
00368         pc.printf(replybuff);
00369         wait(5);
00370         pc.printf("\n Getting Server IP \r\n");
00371         strcpy(cmdbuff, "AT+CIFSR\r\n");
00372         timeout=2500;
00373         getcount=200;
00374         while(weberror==0) {
00375             SendCMD();
00376             getreply();
00377             if (strstr(replybuff, "0.0.0.0") == NULL) {
00378                 weberror=1;   // wait for valid IP
00379             }
00380         }
00381         pc.printf("\n Enter WEB address (IP) found below in your browser \r\n\n");
00382         pc.printf("\n The MAC address is also shown below,if it is needed \r\n\n");
00383         replybuff[strlen(replybuff)-1] = '\0';
00384         //char* IP = replybuff + 5;
00385         sprintf(webdata,"%s", replybuff);
00386         pc.printf(webdata);
00387         //  led2=1;
00388         bufflen=200;
00389         count=0;
00390         pc.printf("\n\n++++++++++ Ready ++++++++++\r\n\n");
00391         esp.attach(&callback);
00392     } else {
00393         pc.printf("\n++++++++++ ESP8266 error, check power/connections ++++++++++\r\n");
00394         while(1) {}
00395     }
00396     t2.reset();
00397     t2.start();
00398 }
00399 
00400 // ESP Command data send
00401 void SendCMD()
00402 {
00403     esp.printf("%s", cmdbuff);
00404 }
00405 
00406 // Large WEB buffer data send
00407 void SendWEB()
00408 {
00409     int i=0;
00410     if(esp.writeable()) {
00411         while(webbuff[i]!='\0') {
00412             esp.putc(webbuff[i]);
00413             i++;
00414         }
00415     }
00416 }
00417 
00418 // Get Command and ESP status replies
00419 void getreply()
00420 {
00421     memset(replybuff, '\0', sizeof(replybuff));
00422     t1.reset();
00423     t1.start();
00424     replycount=0;
00425     while(t1.read_ms()< timeout && replycount < getcount) {
00426         if(esp.readable()) {
00427             replybuff[replycount] = esp.getc();
00428             replycount++;
00429         }
00430     }
00431     t1.stop();
00432 }
00433 
00434 // Get RTC time
00435 void gettime()
00436 {
00437     time_t seconds = time(NULL);
00438     strftime(timebuf,50,"%H:%M:%S %a %d %b %y", localtime(&seconds));
00439 }
00440 
00441 void setRTC()
00442 {
00443     t.tm_sec = (0);             // 0-59
00444     t.tm_min = (minute);        // 0-59
00445     t.tm_hour = (hour);         // 0-23
00446     t.tm_mday = (dayofmonth);   // 1-31
00447     t.tm_mon = (month-1);       // 0-11  "0" = Jan, -1 added for Mbed RCT clock format
00448     t.tm_year = ((year)+100);   // year since 1900,  current DCF year + 100 + 1900 = correct year
00449     set_time(mktime(&t));       // set RTC clock
00450 }