Final Edit
Dependencies: 4DGL-uLCD-SE LSM9DS1_Library_cal SDFileSystem mbed wave_player
Fork of 4180Lab_4 by
Diff: Webpage.cpp
- Revision:
- 2:c7779da25bdb
- Parent:
- 1:bbd83a3a8372
--- a/Webpage.cpp Wed Nov 02 02:07:34 2016 +0000 +++ b/Webpage.cpp Wed Nov 02 21:46:12 2016 +0000 @@ -1,214 +1,412 @@ #include "Webpage.h" +#include "mbed.h" + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); + +Serial _pc(USBTX, USBRX); +// some test values to show on web page +AnalogIn Ain1(p18); +AnalogIn Ain2(p19); + +char ssid[32] = "GTother"; // enter WiFi router ssid inside the quotes +char pwd [32] = "GeorgeP@1927"; // enter WiFi router password inside the quotes +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]; +// things for sending/receiving data over serial +volatile int tx_in=0; +volatile int tx_out=0; +volatile int rx_in=0; +volatile int rx_out=0; +const int buffer_size = 4095; +char tx_buffer[buffer_size+1]; +char rx_buffer[buffer_size+1]; + +bool playSong = false; + +int DataRX; +int updateFlag; +int count = 0; +int activity = 0; +char cmdbuff[1024]; +char replybuff[4096]; +char webdata[4096]; // This may need to be bigger depending on WEB browser used +char webbuff[4096]; // Currently using 1986 characters, Increase this if more web page data added +char timebuf[30]; +void SendCMD(),getreply(),ReadWebData(),startserver(); +void gettime(),setRTC(),gettemp(),getbattery(); +char rx_line[1024]; +int port =80; // set server port +int SERVtimeout =5; // set server timeout in seconds in case link breaks. +struct tm t; +// manual set RTC values +int minute =00; // 0-59 +int hour =12; // 2-23 +int dayofmonth =26; // 1-31 +int month =8; // 1-12 +int year =15; // last 2 digits + + +Webpage::Webpage(PinName tx, PinName rx) + : esp(tx, rx) {} + +bool Webpage::getPlay() { + return playSong; +} -Webpage::Webpage(PinName tx, PinName rx, PinName rst) - : esp(tx, rx), reset(rst), led1(LED1), led2(LED2), led3(LED3), led4(LED4) { - ssid = "GTother"; // enter Webpage router ssid inside the quotes - pwd = "GeorgeP@1927"; // enter Webpage router password inside the quotes +void Webpage::updateOutput(int activitylvl) { + gettime(); + gettemp(); + getbattery(); + count++; + activity = activitylvl; + // send new values + sprintf(cmdbuff, "count,activity,time,analog1,analog2=%d,%d,\"%s\",\"%s\",\"%s\"\r\n",count, activity, timebuf,Temp,Vcc); + SendCMD(); + getreply(); + updateFlag = 0; +} + +void Webpage::update() { + if(DataRX==1) { + ReadWebData(); + esp.attach(this, &Webpage::Rx_interrupt, Serial::RxIrq); + } + if (updateFlag == 1) { + gettime(); + gettemp(); + getbattery(); + count++; + // send new values + sprintf(cmdbuff, "count,activity,time,analog1,analog2=%d, %d,\"%s\",\"%s\",\"%s\"\r\n",count, activity, timebuf,Temp,Vcc); + SendCMD(); + getreply(); + updateFlag = 0; + } +} + +void Webpage::init() { + _pc.baud(9600); + esp.baud(9600); + led1=1,led2=0,led3=0, led4=0; + // Setup a serial interrupt function to receive data + esp.attach(this, &Webpage::Rx_interrupt, Serial::RxIrq); + // Setup a serial interrupt function to transmit data + esp.attach(this, &Webpage::Tx_interrupt, Serial::TxIrq); + if (time(NULL) < 1420070400) { + setRTC(); + } + startserver(); + DataRX=0; + count=0; +} +void Webpage::ReadWebData() +{ + wait_ms(200); + esp.attach(NULL,Serial::RxIrq); + DataRX=0; + memset(webdata, '\0', sizeof(webdata)); + strcpy(webdata, rx_buffer); + memset(rx_buffer, '\0', sizeof(rx_buffer)); + rx_in = 0; + rx_out = 0; + // check web data for form information + if( strstr(webdata, "check=playv") != NULL ) { + led1=!led1; + playSong = !playSong; + } + // if( strstr(webdata, "check=led2v") != NULL ) { +// led2=!led2; +// } +// if( strstr(webdata, "check=led3v") != NULL ) { +// led3=!led3; +// } +// if( strstr(webdata, "check=led4v") != NULL ) { +// led4=!led4; +// } + if( strstr(webdata, "POST") != NULL ) { // set update flag if POST request + updateFlag=1; + } + if( strstr(webdata, "GET") != NULL && strstr(webdata, "favicon") == NULL ) { // set update flag for GET request but do not want to update for favicon requests + updateFlag=1; + } } -void dev_recv() + +void Webpage::startserver() { - led1 = !led1; - while(esp.readable()) { - pc.putc(esp.getc()); + gettime(); + gettemp(); + getbattery(); + _pc.printf("++++++++++ Resetting ESP ++++++++++\r\n"); + strcpy(cmdbuff,"node.restart()\r\n"); + SendCMD(); + wait(2); + getreply(); + + _pc.printf("\n++++++++++ Starting Server ++++++++++\r\n> "); + + // initial values + sprintf(cmdbuff, "count,activity,time,analog1,analog2=0,0,\"%s\",\"%s\",\"%s\"\r\n",timebuf,Temp,Vcc); + SendCMD(); + getreply(); + wait(0.5); + + //create server + sprintf(cmdbuff, "srv=net.createServer(net.TCP,%d)\r\n",SERVtimeout); + SendCMD(); + getreply(); + wait(0.5); + strcpy(cmdbuff,"srv:listen(80,function(conn)\r\n"); + SendCMD(); + getreply(); + wait(0.3); + strcpy(cmdbuff,"conn:on(\"receive\",function(conn,payload) \r\n"); + SendCMD(); + getreply(); + wait(0.3); + + //print data to mbed + strcpy(cmdbuff,"print(payload)\r\n"); + SendCMD(); + getreply(); + wait(0.2); + + //web page data + strcpy(cmdbuff,"conn:send('<!DOCTYPE html><html><body><h1><center>Naptime!</center></h1>')\r\n"); + SendCMD(); + getreply(); + wait(0.4); + strcpy(cmdbuff,"conn:send('<p><center>~Keep track of baby\\'s activity at night, even play a soothing lullaby~</center></p><hr>')\r\n"); + SendCMD(); + getreply(); + wait(0.2); + //strcpy(cmdbuff,"conn:send('Battery Voltage: '..analog1..' V<br>Analog 2: '..analog2..' V<br><hr>')\r\n"); +// SendCMD(); +// getreply(); +// wait(0.3); + strcpy(cmdbuff,"conn:send('<center>Activity Level: '..activity..'</center>')\r\n"); + SendCMD(); + getreply(); + wait(0.3); + strcpy(cmdbuff,"conn:send('<form method=\"POST\"')\r\n"); + SendCMD(); + getreply(); + wait(0.3); + strcpy(cmdbuff, "conn:send('<p><center><input type=\"checkbox\" name=\"check\" value=\"playv\"> Toggle Music')\r\n"); + SendCMD(); + getreply(); + wait(0.3); + //strcpy(cmdbuff, "conn:send('<p><input type=\"checkbox\" name=\"check\" value=\"led2v\"> flip LED2')\r\n"); +// SendCMD(); +// getreply(); +// wait(0.3); +// strcpy(cmdbuff, "conn:send('<p><input type=\"checkbox\" name=\"check\" value=\"led3v\"> flip LED3')\r\n"); +// SendCMD(); +// getreply(); +// wait(0.3); +// strcpy(cmdbuff, "conn:send('<p><input type=\"checkbox\" name=\"check\" value=\"led4v\"> flip LED4')\r\n"); +// SendCMD(); +// getreply(); +// wait(0.3); + strcpy(cmdbuff,"conn:send('<p><center><input type=\"submit\" value=\"Send\"></form>')\r\n"); + SendCMD(); + getreply(); + wait(0.3); + strcpy(cmdbuff, "conn:send('<p><h2>How to use:</h2>Select the checkbox and hit send to play music')\r\n"); + SendCMD(); + getreply(); + wait(0.5); + strcpy(cmdbuff,"conn:send('<hr><center>Updates: '..count..'</center>')\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff,"conn:send('<center>Last update (based on mbed RTC time): '..time..'</center></body></html>')\r\n"); + SendCMD(); + getreply(); + wait(0.4); + //end web page data + strcpy(cmdbuff, "conn:on(\"sent\",function(conn) conn:close() end)\r\n"); // close current connection + SendCMD(); + getreply(); + wait(0.3); + strcpy(cmdbuff, "end)\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff, "end)\r\n"); + SendCMD(); + getreply(); + wait(0.2); + + strcpy(cmdbuff, "tmr.alarm(0, 1000, 1, function()\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff, "if wifi.sta.getip() == nil then\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff, "print(\"Connecting to AP...\\n\")\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff, "else\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff, "ip, nm, gw=wifi.sta.getip()\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff,"print(\"IP Address: \",ip)\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff,"tmr.stop(0)\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff,"end\r\n"); + SendCMD(); + getreply(); + wait(0.2); + strcpy(cmdbuff,"end)\r\n"); + SendCMD(); + getreply(); + wait(0.2); + + _pc.printf("\n\n++++++++++ Ready ++++++++++\r\n\n"); +} + +void Webpage::SendCMD() +{ + int i; + char temp_char; + bool empty; + i = 0; +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(UART1_IRQn); + empty = (tx_in == tx_out); + while ((i==0) || (cmdbuff[i-1] != '\n')) { +// Wait if buffer full + if (((tx_in + 1) % buffer_size) == tx_out) { +// End Critical Section - need to let interrupt routine empty buffer by sending + NVIC_EnableIRQ(UART1_IRQn); + while (((tx_in + 1) % buffer_size) == tx_out) { + } +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(UART1_IRQn); + } + tx_buffer[tx_in] = cmdbuff[i]; + i++; + tx_in = (tx_in + 1) % buffer_size; } + if (esp.writeable() && (empty)) { + temp_char = tx_buffer[tx_out]; + tx_out = (tx_out + 1) % buffer_size; +// Send first character to start tx interrupts, if stopped + esp.putc(temp_char); + } +// End Critical Section + NVIC_EnableIRQ(UART1_IRQn); + return; +} + +void Webpage::getreply() +{ + read_line(); + sscanf(rx_line,replybuff); +} + +void Webpage::read_line() { + int i; + i = 0; +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(UART1_IRQn); +// Loop reading rx buffer characters until end of line character + while ((i==0) || (rx_line[i-1] != '\r')) { +// Wait if buffer empty + if (rx_in == rx_out) { +// End Critical Section - need to allow rx interrupt to get new characters for buffer + NVIC_EnableIRQ(UART1_IRQn); + while (rx_in == rx_out) { + } +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(UART1_IRQn); + } + rx_line[i] = rx_buffer[rx_out]; + i++; + rx_out = (rx_out + 1) % buffer_size; + } +// End Critical Section + NVIC_EnableIRQ(UART1_IRQn); + rx_line[i-1] = 0; + return; } -void pc_recv() -{ - led4 = !led4; - while(pc.readable()) { - esp.putc(pc.getc()); - } -} -void Webpage::ESPsetbaudrate() { - strcpy(snd, "AT+CIOBAUD=115200\r\n"); // change the numeric value to the required baudrate - SendCMD(); -} -void Webpage::ESPconfig() { - wait(5); - pc.printf("\f---------- Starting ESP Config ----------\r\n\n"); - strcpy(snd,".\r\n.\r\n"); - SendCMD(); - wait(1); - pc.printf("---------- Reset & get Firmware ----------\r\n"); - strcpy(snd,"node.restart()\r\n"); - SendCMD(); - timeout=5; - getreply(); - pc.printf(buf); - - wait(2); - - pc.printf("\n---------- Get Version ----------\r\n"); - strcpy(snd,"print(node.info())\r\n"); - SendCMD(); - timeout=4; - getreply(); - pc.printf(buf); - - wait(3); - - // set CWMODE to 1=Station,2=AP,3=BOTH, default mode 1 (Station) - pc.printf("\n---------- Setting Mode ----------\r\n"); - strcpy(snd, "wifi.setmode(wifi.STATION)\r\n"); - SendCMD(); - timeout=4; - getreply(); - pc.printf(buf); - - wait(2); - - - - pc.printf("\n---------- Listing Access Points ----------\r\n"); - strcpy(snd, "function listap(t)\r\n"); - SendCMD(); - wait(1); - strcpy(snd, "for k,v in pairs(t) do\r\n"); - SendCMD(); - wait(1); - strcpy(snd, "print(k..\" : \"..v)\r\n"); - SendCMD(); - wait(1); - strcpy(snd, "end\r\n"); - SendCMD(); - wait(1); - strcpy(snd, "end\r\n"); - SendCMD(); - wait(1); - strcpy(snd, "wifi.sta.getap(listap)\r\n"); - SendCMD(); - wait(1); - timeout=15; - getreply(); - pc.printf(buf); - - wait(2); - - 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=10; - getreply(); - pc.printf(buf); - - wait(5); - pc.printf("\n---------- Get IP's ----------\r\n"); - strcpy(snd, "print(wifi.sta.getip())\r\n"); - SendCMD(); - timeout=3; - getreply(); - pc.printf(buf); - - wait(1); - - pc.printf("\n---------- Get Connection Status ----------\r\n"); - strcpy(snd, "print(wifi.sta.status())\r\n"); - SendCMD(); - timeout=5; - getreply(); - pc.printf(buf); +// Interupt Routine to read in data from serial port +void Webpage::Rx_interrupt() { + DataRX=1; + //led3=1; +// Loop just in case more than one character is in UART's receive FIFO buffer +// Stop if buffer full + while ((esp.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { + rx_buffer[rx_in] = esp.getc(); +// Uncomment to Echo to USB serial to watch data flow + _pc.putc(rx_buffer[rx_in]); + rx_in = (rx_in + 1) % buffer_size; + } + //led3=0; + return; +} - pc.printf("\n\n\n If you get a valid (non zero) IP, ESP8266 has been set up.\r\n"); - pc.printf(" Run this if you want to reconfig the ESP8266 at any time.\r\n"); - pc.printf(" It saves the SSID and password settings internally\r\n"); - wait(10); - - - pc.printf("\n---------- Setting up http server ----------\r\n"); - 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> Hi James, NodeMcu.</h1>\")\r\n"); - SendCMD(); - wait(1); - - strcpy(snd, "conn:send(\"<h2> test</h2>\")\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(); - wait(1); - timeout=17; - getreply(); - pc.printf(buf); - pc.printf("\r\nDONE"); -} -void Webpage::SendCMD() { - esp.printf("%s", snd); -} -void Webpage::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(); - } - } + +// Interupt Routine to write out data to serial port +void Webpage::Tx_interrupt() { + //led2=1; +// Loop to fill more than one character in UART's transmit FIFO buffer +// Stop if buffer empty + while ((esp.writeable()) && (tx_in != tx_out)) { + esp.putc(tx_buffer[tx_out]); + tx_out = (tx_out + 1) % buffer_size; + } + //led2=0; + return; } -void Webpage::setupPage() { - reset=0; //hardware reset for 8266 - pc.baud(9600); // 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=2; - getreply(); - - esp.baud(9600); // change this to the new ESP8266 baudrate if it is changed at any time. - - //ESPsetbaudrate(); //****************** include this routine to set a different ESP8266 baudrate ****************** - - ESPconfig(); //****************** include Config to set the ESP8266 configuration *********************** - - pc.attach(&pc_recv, Serial::RxIrq); - esp.attach(&dev_recv, Serial::RxIrq); - - // continuosly get AP list and IP +void gettime() +{ + time_t seconds = time(NULL); + strftime(timebuf,50,"%H:%M:%S %a %d %b %y", localtime(&seconds)); } +void setRTC() +{ + t.tm_sec = (0); // 0-59 + t.tm_min = (minute); // 0-59 + t.tm_hour = (hour); // 0-23 + t.tm_mday = (dayofmonth); // 1-31 + t.tm_mon = (month-1); // 0-11 "0" = Jan, -1 added for Mbed RCT clock format + t.tm_year = ((year)+100); // year since 1900, current DCF year + 100 + 1900 = correct year + set_time(mktime(&t)); // set RTC clock +} +// Analog in example +void getbattery() +{ + AdcIn=Ain1.read(); + Ht = (AdcIn*3.3); // set the numeric to the exact MCU analog reference voltage for greater accuracy + sprintf(Vcc,"%2.3f",Ht); +} +// Temperature example +void gettemp() +{ + + AdcIn=Ain2.read(); + Ht = (AdcIn*3.3); // set the numeric to the exact MCU analog reference voltage for greater accuracy + sprintf(Temp,"%2.3f",Ht); +}