
HTTP Server serving a simple webpage which enables to remotely turn LED1 on/off. Compile, download, run and type 'IP_address/secret/' (don't forget the last '/') into your web browser and hit ENTER.
Dependencies: W5500Interface mbed
Turn LED1, or other digital output, on/off using a web browser.
In this example we create a HTTP server that will serve a simple Web page to remotely turn LED1, or other digital output on the mbed board, on/off by using a web browser. A WIZ550io module or W5500 Network-Shielld is used to assure connection between the mbed module and the Ethernet network (Internet).
Needed parts:
- mbed board
- WIZ550io module or W5500 Network-Shield
- Wires
- Web browser (Internet Explorer, Safari, Firefox, Chrome ...) running on Windows, Mac, Linux, iPhone or Android device.
![]() | ![]() |
The project was inspired by the Tuxgraphics Web Switch. Thank you Guido!
NOTE:
- For a Web Switch using an ENC28J60 Ethernet module see WebSwitch_ENC28J60
- For a Web Switch using mbed's built in Ethernet PHY see WebSwitch_mbed-dev or WebSwitch_mbed-os
main.cpp
- Committer:
- hudakz
- Date:
- 2016-02-08
- Revision:
- 5:458d9d7b5c1b
- Parent:
- 4:31010e482971
- Child:
- 6:3d74cb156c5c
File content as of revision 5:458d9d7b5c1b:
/* * In this example LED1 on the mbed board is turned on/off using a web browser. * However, you can easily modify the project to remotely switch on/off any external device. * The HTTP server is built from an mbed board and a WIZ550io board. * The example is based on the Tuxgraphics Web Switch <http://www.tuxgraphics.org/>. * For more details see <https://developer.mbed.org/users/hudakz/code/WebSwitch_WIZ550io/wiki/Homepage> * Thanks to Jozsef Voros it works now also with the W5500 modules without a built-in MAC * See below how to enable that. */ #include "mbed.h" #include "EthernetInterface.h" #include <string> using namespace std; Serial serial(USBTX, USBRX); #if defined(TARGET_LPC1768) EthernetInterface eth(p11, p12, p13, p8, p14); // MOSI, MISO, SCK, CS, RESET #elif defined(TARGET_LPC11U24) EthernetInterface eth(P16, P15, P13, P17, P18); // MOSI, MISO, SCK, CS, RESET #elif defined(TARGET_NUCLEO_F103RB) || defined(TARGET_NUCLEO_L152RE) || defined(TARGET_NUCLEO_F030R8) \ || defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F302R8) || defined(TARGET_NUCLEO_L053R8) \ || defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F334R8) || defined(TARGET_NUCLEO_F072RB) \ || defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F070RB) \ || defined(TARGET_KL25Z ) || defined(TARGET_KL46Z) || defined(TARGET_K64F) || defined(TARGET_KL05Z) \ || defined(TARGET_K20D50M) || defined(TARGET_K22F) \ || defined(TARGET_NRF51822) \ || defined(TARGET_RZ_A1H) EthernetInterface eth(D4, D5, D3, D6, D7); // MOSI, MISO, SCK, CS, RESET // If your board/plaform is not present yet then uncomment // the following two lines and replace modify as appropriate. //#elif defined(TARGET_YOUR_BOARD) //EthernetInterface eth(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, RESET); // MOSI, MISO, SCK, CS, RESET #endif // Note: // If it happends that any of the SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS or RESET pins collide with LED1 pin // then either use different SPI port (if available on the board) and change the pin names // in the constructor spi(...) 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 220 Ohm resitor that is connected to the groud. // In the second case remember to replace LED1 in sw(LED1) constructor (see below). // IP address must be also unique and compatible with your network. Change as appropriate. // If instead of WIZ550io you'd like to use a W5500 module without a built-in MAC please uncommend the following line //#define W5500 1 #if defined(W5500) // The MAC number must be unique within the connected network. Modify as appropriate. uint8_t MY_MAC[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; #endif const char MY_IP[] = "192.168.1.181"; const char MY_NETMASK[] = "255.255.255.0"; const char MY_GATEWAY[] = "192.168.1.1"; int MY_PORT = 80; TCPSocketServer server; TCPSocketConnection client; bool serverIsListening = false; 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 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 // 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 analyseGetURL(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); } /** * @brief * @note * @param * @retval */ string& movedPermanently(uint8_t flag) { if(flag == 1) httpContent = "/" + PASSWORD + "/"; else httpContent = ""; httpContent += "<h1>301 Moved Permanently</h1>\r\n"; return(httpContent); } /** * @brief * @note * @param * @retval */ string& httpPage(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; } /** * @brief * @note * @param * @retval */ void sendHTTP(TCPSocketConnection& client, string& header, string& content) { char contentLeght[5] = {}; header += "\r\nContent-Type: text/html\r\n"; header += "Content-Length: "; sprintf(contentLeght, "%d", content.length()); header += string(contentLeght) + "\r\n"; header += "Pragma: no-cache\r\n"; header += "Connection: About to close\r\n"; header += "\r\n"; string webpage = header + content; client.send(const_cast<char*>(webpage.c_str()), webpage.length()); } /** * @brief * @note * @param * @retval */ void closeClient(void) { client.close(); serial.printf("Connection closed.\n\rTCP server is listening...\n\r"); } /** * @brief * @note * @param * @retval */ int main(void) { #if defined(W5500) int ret = eth.init(MY_MAC, MY_IP, MY_NETMASK, MY_GATEWAY); #else int ret = eth.init(MY_IP, MY_NETMASK, MY_GATEWAY); #endif if(!ret) { serial.printf("Initialized, MY_MAC: %s\n", eth.getMACAddress()); serial.printf ( "Connected, MY_IP: %s, MY_NETMASK: %s, MY_GATEWAY: %s\n", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway() ); } else { serial.printf("Error eth.init() - ret = %d\n", ret); return -1; } //setup tcp socket if(server.bind(MY_PORT) < 0) { serial.printf("TCP server bind failed.\n\r"); return -1; } else { serial.printf("TCP server bind succeeded.\n\r"); serverIsListening = true; } if(server.listen(1) < 0) { serial.printf("TCP server listen failed.\n\r"); return -1; } else { serial.printf("TCP server is listening...\n\r"); } while(serverIsListening) { if(server.accept(client) >= 0) { char buf[1024] = { }; size_t size = 0; serial.printf("Client connected!\n\rIP: %s\n\r", client.get_address()); switch(client.receive(buf, 1023)) { case 0: serial.printf("Recieved buffer is empty.\n\r"); break; case -1: serial.printf("Failed to read data from client.\n\r"); break; default: size = strlen(buf); string received((char*)buf); if(received.substr(0, 3) != "GET") { httpHeader = HTTP_OK; httpContent = "<h1>200 OK</h1>"; sendHTTP(client, httpHeader, httpContent); closeClient(); continue; } if(received.substr(0, 6) == "GET / ") { httpHeader = HTTP_OK; httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n"; sendHTTP(client, httpHeader, httpContent); closeClient(); continue; } int cmd = analyseGetURL(received); if(cmd == -2) { // redirect to the right base url httpHeader = MOVED_PERM; sendHTTP(client, httpHeader, movedPermanently(1)); closeClient(); continue; } if(cmd == -1) { httpHeader = UNAUTHORIZED; httpContent = "<h1>401 Unauthorized</h1>"; sendHTTP(client, httpHeader, httpContent); closeClient(); continue; } if(cmd == 1) { sw = 1; // switch on } if(cmd == 0) { sw = 0; // switch off } httpHeader = HTTP_OK; sendHTTP(client, httpHeader, httpPage(sw)); } closeClient(); } } }