WEB server handles an ESP8266 module to control a LED
Fork of WebSwitch_ENC28J60 by
Diff: main.cpp
- Revision:
- 5:9b4fd5f07e10
- Parent:
- 4:d34811deedab
--- a/main.cpp Wed Feb 04 19:27:26 2015 +0000 +++ b/main.cpp Wed Jan 06 14:47:02 2016 +0000 @@ -1,207 +1,349 @@ -/* In this example LED1 is switched on/off using a web browser connected to this HTTP server. - * The example is based on the Tuxgraphics Web Switch <http://www.tuxgraphics.org/>. - * This HTTP server is built around the the ENC28J60 chip - * driven by the UIPEthernet library <https://github.com/ntruchsess/arduino_uip> - * ported to mbed. - */ +#include <mbed.h> -#include <mbed.h> -#include <UIPEthernet.h> -#include <UIPServer.h> -#include <UIPClient.h> -#include <string> - -using namespace std; +// WEB Server to control one LED +// ----------------------------- -// UIPEthernet is the name of a global instance of UIPEthernetClass. -// Do not change the name! It is used within the UIPEthernet library. -#if defined(TARGET_LPC1768) -UIPEthernetClass UIPEthernet(p11, p12, p13, p8); // mosi, miso, sck, cs -#elif defined(TARGET_LPC1114) -UIPEthernetClass UIPEthernet(dp2, dp1, dp6, dp25); // mosi, miso, sck, cs -#elif defined(TARGET_LPC11U68) -UIPEthernetClass UIPEthernet(P0_9, P0_8, P1_29, P0_2); // mosi, miso, sck, cs -#elif defined (TARGET_NUCLEO_F103RB) -UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs -#elif defined (TARGET_NUCLEO_F401RE) -UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs -#elif defined (TARGET_NUCLEO_F411RE) -UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs +Serial pc(USBTX, USBRX); +Serial esp(PA_9, PA_10); // tx, rx +DigitalOut sw(PA_5); // Change LED to a pin of your choice. However, make sure that it does not collide with any serial pins already used + +Timer t; -// If your board/plaform is not present yet then uncomment the following two lines and replace TARGET_YOUR_BOARD as appropriate. - -//#elif defined (TARGET_YOUR_BOARD) -//UIPEthernetClass UIPEthernet(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS); // mosi, miso, sck, cs - -#endif - -// Note: -// If it happends that any of the SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS pins collide with LED1 pin -// then either use different SPI port (if available on the board) and change the pin names in the constructor UIPEthernet(...) accordingly -// or instead of using LED1 pin, select a free pin (not used by SPI port) and connect to it an external LED which is connected to a resitor that is connected to the groud. -// In the second case remember to replace LED1 in sw(LED1) constructor (see below). - +int count,ended,timeout; +char buf[1024]; +char snd[255]; -// MAC number must be unique within the connected network. Modify as appropriate. -const uint8_t MY_MAC[6] = {0x00,0x01,0x02,0x03,0x04,0x06}; -// IP address must be also unique and compatible with your network. Change as appropriate. -const IPAddress MY_IP(192,168,1,181); -const uint16_t MY_PORT = 80; // for HTTP connection -EthernetServer myServer = EthernetServer(MY_PORT); -// In this example we are turning on/off LED1. -DigitalOut sw(LED1); // Change LED1 to a pin of your choice. However, make sure that it does not collide with any of the SPI pins already used in the UIPEthernet(...) constructor above! +const char* PASSWORD = "secret"; // change as you like +const char ssid[32] = "ESP8266"; // enter router ssid inside the quotes +const char pwd [32] = "ok"; // enter router password inside the quotes +char http[1024]; // HTTP content +uint8_t port = 80; +int id = 1; -const string PASSWORD = "secret"; // change as you like -const string HTTP_OK = "HTTP/1.0 200 OK"; -const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: "; -const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized"; -string httpHeader; // HTTP header -string httpContent; // HTTP content +void SendCMD(char*),SendData(char*),GetReplyLine(int,char*,int),GetReply(int,char*,int),ESPconfig_Server(),ESPconfig_Client(),ESPsetbaudrate(),page(int); +int checksw(char*); -// analyse the url given -// return values: -1 invalid password -// -2 no command given but password valid -// -3 just refresh page -// 0 switch off -// 1 switch on -// -// The string passed to this function will look like this: -// GET /password HTTP/1..... -// GET /password/ HTTP/1..... -// GET /password/?sw=1 HTTP/1..... -// GET /password/?sw=0 HTTP/1..... - -int8_t analyse_get_url(string& str) -{ - if(str.substr(5, PASSWORD.size()) != PASSWORD) - return(-1); - - uint8_t pos = 5 + PASSWORD.size(); - - if(str.substr(pos, 1) == " ") - return(-2); - - if(str.substr(pos, 1) != "/") - return(-1); - - pos++; - - string cmd(str.substr(pos, 5)); - - if(cmd == "?sw=0") - return(0); - - if(cmd == "?sw=1") - return(1); - - return(-3); -} +// USAGE: +// IP/password +// IP/password/?sw=1 +// IP/password/?sw=0 -string& moved_perm(uint8_t flag) -{ - if(flag == 1) - httpContent = "/" + PASSWORD + "/"; - else - httpContent = ""; - - httpContent += "<h1>301 Moved Permanently</h1>\r\n"; - - return (httpContent); -} - -string& page(uint8_t status) -{ - httpContent = "<h2>Web Switch</h2>\r\n"; - - if(status == 1) { - httpContent += "<pre>\r\n <font color=#FF0000>ON</font>"; - httpContent += " <a href=\"./?sw=0\">[switch off]</a>\r\n"; - } else { - httpContent += "<pre>\r\n <font color=#00FF00>OFF</font>"; - httpContent += " <a href=\"./?sw=1\">[switch on]</a>\r\n"; - } - - httpContent += " <a href=\".\">[refresh status]</a>\r\n"; - httpContent += "</pre>\r\n"; - httpContent += "<hr>\r\n"; - return httpContent; -} - -void http_send(EthernetClient& client, string& header, string& content) -{ - char content_length[5] = {}; - - header += "\r\nContent-Type: text/html\r\n"; - header += "Content-Length: "; - sprintf(content_length, "%d", content.length()); - header += string(content_length) + "\r\n"; - header += "Pragma: no-cache\r\n"; - header += "Connection: About to close\r\n"; - header += "\r\n"; - string webpage = header + content; - client.write((uint8_t*)webpage.c_str(),webpage.length()); -} int main() { - UIPEthernet.begin(MY_MAC,MY_IP); - myServer.begin(); + + // Setup + esp.baud(115200); // esp speed + pc.baud(9600); // change this to the new ESP8266 baudrate if it is changed at any time. + + + //ESPconfig_Client(); + ESPconfig_Server(); + + for (int i=0; i<8; i++) + { + sw=!sw; + wait(0.3); + } + + + // Loop while(1) { - EthernetClient client = myServer.available(); - if (client) { - size_t size = client.available(); - if(size > 0) { - uint8_t* buf = (uint8_t*)malloc(size); - size = client.read(buf, size); - string received((char*)buf); - free(buf); - if(received.substr(0, 3) != "GET") { - // head, post or other method - // for possible status codes see: - // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html - httpHeader = HTTP_OK; - httpContent = "<h1>200 OK</h1>"; - http_send(client, httpHeader, httpContent); - continue; - } - - if(received.substr(0, 6) == "GET / ") { - httpHeader = HTTP_OK; - httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n"; - http_send(client, httpHeader, httpContent); - continue; + timeout=2; + if(esp.readable()){ + GetReply(500,buf,sizeof(buf)); + char* rqstPnt = strstr(buf, "+IPD"); + if(rqstPnt != NULL) + { + sscanf(rqstPnt, "+IPD,%d", &id); + + page(checksw(buf)); + + // Command TCP/IP Data Tx + sprintf(snd,"AT+CIPSEND=%d,%d\r\n", id, strlen(http)); + SendCMD(snd); + GetReply(500,buf,sizeof(buf)); + + SendData(http); + + bool weberror = true; + int cnt = 0; + while(weberror && cnt < 100){ + GetReply(500,buf,sizeof(buf)); + if(strstr(buf, "SEND OK") != NULL) + weberror = false; + + cnt++; } - - int cmd = analyse_get_url(received); - - if(cmd == -2) { - // redirect to the right base url - httpHeader = MOVED_PERM; - http_send(client, httpHeader, moved_perm(1)); - continue; + + if(weberror) + { + strcpy(snd,"AT+CIPMUX=1\r\n"); + SendCMD(snd); + GetReply(500,buf,sizeof(buf)); + + sprintf(snd,"AT+CIPSERVER=1,%d\r\n", port); + SendCMD(snd); + GetReply(2000,buf,sizeof(buf)); } - - if(cmd == -1) { - httpHeader = UNAUTHORIZED; - httpContent = "<h1>401 Unauthorized</h1>"; - http_send(client, httpHeader, httpContent); - continue; + else + { + sprintf(snd,"AT+CIPCLOSE=%d\r\n", id); // Notice id is an int formatted to string + SendCMD(snd); + GetReply(500,buf,sizeof(buf)); } - - if(cmd == 1) { - sw = 1; // switch on - } - - if(cmd == 0) { - sw = 0; // switch off - } - - httpHeader = HTTP_OK; - http_send(client, httpHeader, page(sw)); } } } } +void page(int status) +{ + char content_length[5]; + char info[255]; + + strcpy(info,"<h2>Web Switch</h2>\r\n"); + + if(status < 0) + { + strcat(info,"<p>Usage: http://host_or_ip/password</p>\r\n"); + } + else if (status == 1) + { + strcat(info,"<pre>\r\n <font color=#FF0000>ON</font>"); + strcat(info," <a href=\"./?sw=0\">[switch off]</a>\r\n"); + } + else + { + strcat(info,"<pre>\r\n <font color=#00FF00>OFF</font>"); + strcat(info," <a href=\"./?sw=1\">[switch on]</a>\r\n"); + } + + strcat(info," <a href=\".\">[refresh status]</a>\r\n"); + strcat(info,"</pre>\r\n"); + strcat(info,"<br>\r\n"); + + strcpy(http,"HTTP/1.0 200 OK"); + strcat(http,"\r\nContent-Type: text/html\r\n"); + strcat(http,"Content-Length: "); + sprintf(content_length, "%d", strlen(buf)); + strcat(http,content_length); + strcat(http,"\r\nPragma: no-cache\r\n"); + strcat(http,"Connection: About to close\r\n\r\n"); + strcat(http,info); +} + + +int checksw(char *buf) +{ + int ret = 0; + + if(strstr(buf,PASSWORD)== NULL) + return -1; + + char* rqstPnt = strstr(buf, "?sw="); + if(rqstPnt == NULL) + ret = 0; + else + sscanf(rqstPnt,"?sw=%d", &ret); + + if(ret == 1) + sw = 1; // switch on + else + sw = 0; // switch off + + return ret; +} + + +void ESPconfig_Server() +{ + + pc.printf("------- Starting ESP Config -------\r\n\n"); + pc.printf("------- Reset & get Firmware ------\r\n"); + strcpy(snd,"AT+RST\r\n"); + SendCMD(snd); + GetReply(6000,buf,sizeof(buf)); + + + pc.printf("\n---------- Get Version ----------\r\n"); + strcpy(snd,"AT+GMR\r\n"); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + pc.printf(buf); + GetReply(1000,buf,sizeof(buf)); + + // set CWMODE to 1=Station,2=AP,3=BOTH, default mode 1 (Station) + pc.printf("\n---------- Setting Mode ----------\r\n"); + strcpy(snd, "AT+CWMODE=2\r\n"); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + pc.printf(buf); + + // set CIPMUX to 0=Single,1=Multi + pc.printf("\n---- Setting Connection Mode -----\r\n"); + strcpy(snd, "AT+CIPMUX=1\r\n"); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + + + + pc.printf("\n------------ AP ------------\r\n"); + pc.printf("ssid = %s pwd = %s\r\n",ssid,pwd); + strcpy(snd, "AT+CWSAP=\""); + strcat(snd, ssid); + strcat(snd, "\",\""); + strcat(snd, pwd); + strcat(snd, "\",4,0\r\n"); + SendCMD(snd); + GetReply(8000,buf,sizeof(buf)); + pc.printf(buf); + + pc.printf("\n------- Set Server Port ------\r\n"); + sprintf(snd, "AT+CIPSERVER=1,%d\r\n", port); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + + + pc.printf("\n----- Set Server Timeout -----\r\n"); + sprintf(snd,"AT+CIPSTO=%d\r\n", 5); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + + + pc.printf("\n---------- Get IP's ----------\r\n"); + strcpy(snd, "AT+CWSAP?\r\n"); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + pc.printf(buf); + + strcpy(snd, "AT+CIFSR\r\n"); + SendCMD(snd); + GetReply(2000,buf,sizeof(buf)); + pc.printf(buf); + pc.printf("\n------- Connection Up --------\r\n"); + +} + +void ESPconfig_Client() +{ + + pc.printf("---------- Starting ESP Config -----------\r\n\n"); + pc.printf("---------- Reset & get Firmware ----------\r\n"); + strcpy(snd,"AT+RST\r\n"); + SendCMD(snd); + GetReply(6000,buf,sizeof(buf)); + + + pc.printf("\n---------- Get Version ----------\r\n"); + strcpy(snd,"AT+GMR\r\n"); + SendCMD(snd); + GetReply(3000,buf,sizeof(buf)); + pc.printf(buf); + + // set CWMODE to 1=Station,2=AP,3=BOTH, default mode 1 (Station) + pc.printf("\n---------- Setting Mode ----------\r\n"); + strcpy(snd, "AT+CWMODE=1\r\n"); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + + + // set CIPMUX to 0=Single,1=Multi + pc.printf("\n-------- Setting Connection Mode ---------\r\n"); + strcpy(snd, "AT+CIPMUX=1\r\n"); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + + + pc.printf("\n---------- Listing Acces Points ----------\r\n"); + strcpy(snd, "AT+CWLAP\r\n"); + SendCMD(snd); + GetReply(3000,buf,sizeof(buf)); + pc.printf(buf); + + pc.printf("\n---------- Connecting to AP ----------\r\n"); + pc.printf("ssid = %s pwd = %s\r\n",ssid,pwd); + strcpy(snd, "AT+CWJAP=\""); + strcat(snd, ssid); + strcat(snd, "\",\""); + strcat(snd, pwd); + strcat(snd, "\"\r\n"); + SendCMD(snd); + GetReply(8000,buf,sizeof(buf)); + pc.printf(buf); + + pc.printf("\n------ Set Server Port -------\r\n"); + sprintf(snd, "AT+CIPSERVER=1,%d\r\n", port); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + + + pc.printf("\n----- Set Server Timeout -----\r\n"); + sprintf(snd,"AT+CIPSTO=%d\r\n", 5); + SendCMD(snd); + GetReply(1000,buf,sizeof(buf)); + + + pc.printf("\n---------- Get IP's ----------\r\n"); + int weberror = true; + while(weberror) { // wait for valid IP + strcpy(snd, "AT+CIFSR\r\n"); + SendCMD(snd); + GetReply(2000,buf,sizeof(buf)); + pc.printf(buf); + if(strstr(buf, "0.0.0.0") == NULL) { + weberror=false; + } + } + + pc.printf("\n------- Connection Up --------\r\n"); + +} + +void SendCMD(char *cmd) +{ + esp.printf("%s", cmd); +} + +void SendData(char *dat) +{ + esp.printf("%s", dat); +} + +void GetReply(int timeout, char *buf, int size) +{ + char c; + ended=0; + count=0; + t.start(); + memset(buf, '\0', size); + while(!ended) { + if(esp.readable()) { + c = esp.getc(); + + buf[count] = c; + count++; + + if (c == '\r' || c == '\n') // OK will end + { + if (count > 2 && buf[count-3]== 'O' && buf[count-2] == 'K') + { + buf[count-1] = '\r'; + buf[count] = '\n'; + count = size; + } + } + } + + if(t.read_ms() > timeout || count >= size) // Timeout or full + { + ended = 1; + t.stop(); + t.reset(); + } + } + //pc.printf(buf); +} +