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.
/media/uploads/hudakz/webswitch_wiz.jpg/media/uploads/hudakz/webswitch_mobile01.jpg

The project was inspired by the Tuxgraphics Web Switch. Thank you Guido!

NOTE:

Revision:
0:5c8e08cf3b33
Child:
1:343d3c7e13b8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Mar 15 22:47:37 2015 +0000
@@ -0,0 +1,290 @@
+/* In this example LED1 on the mbed board is switched on/off using a web browser.
+ * 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/>.
+ */
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include <string>
+
+using namespace     std;
+
+Serial              serial(USBTX, USBRX);
+
+// Do not change the name! It is used within the UIPEthernet library.
+#if defined(TARGET_LPC1768)
+SPI                 spi(p11, p12, p13);     // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, p8, p14);     // SPI, CS, RESET
+#elif defined(TARGET_FRDM_KL25Z)
+SPI                 spi(PTD2, PTD3, PTD1);  // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, PTD0, PTD5);  // SPI, CS, RESET
+#elif defined(TARGET_FRDM_KL46Z)
+SPI                 spi(PTD2, PTD3, PTD1);  // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, PTD0, PTD5);  // SPI, CS, RESET
+#elif defined(TARGET_LPC11U24)
+SPI                 spi(P16, P15, P13);     // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, P17, P18);    // SPI, CS, RESET
+#elif defined(TARGET_NUCLEO_F030R8)
+SPI                 spi(PB_5, PB_4, PB_3);  // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, PB_10, PA_8); // SPI, CS, RESET
+#elif defined(TARGET_NUCLEO_F072RB)
+SPI                 spi(PB_5, PB_4, PB_3);  // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, PB_10, PA_8); // SPI, CS, RESET
+#elif defined(TARGET_NUCLEO_F103RB)
+SPI                 spi(PB_5, PB_4, PB_3);  // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, PB_10, PA_8); // SPI, CS, RESET
+#elif defined(TARGET_NUCLEO_F401RE)
+SPI                 spi(PB_5, PB_4, PB_3);  // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, PB_10, PA_8); // SPI, CS, RESET
+#elif defined(TARGET_NUCLEO_F411RE)
+SPI                 spi(PB_5, PB_4, PB_3);  // MOSI, MISO, SCK
+EthernetInterface   eth(&spi, PB_10, PA_8); // SPI, CS, RESET
+
+// If your board/plaform is not present yet then uncomment
+// the following three lines and replace modify as appropriate.
+
+//#elif defined(TARGET_YOUR_BOARD)
+//SPI                 spi(SPI_MOSI, SPI_MISO, SPI_SCK);   // MOSI, MISO, SCK
+//EthernetInterface   eth(&spi, SPI_CS, RESET);           // SPI, 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.
+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
+                                // already used in the UIPEthernet(...) constructor above!
+
+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 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);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+string& moved_perm(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& view(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 http_send(TCPSocketConnection& 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.send (const_cast<char*>(webpage.c_str ()), webpage.length ());
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int main(void) {
+    int     ret = eth.init(MY_IP, MY_NETMASK, MY_GATEWAY);
+
+    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>";
+                    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;
+                }
+
+                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(cmd == -1) {
+                    httpHeader = UNAUTHORIZED;
+                    httpContent = "<h1>401 Unauthorized</h1>";
+                    http_send(client, httpHeader, httpContent);
+                    continue;
+                }
+
+                if(cmd == 1) {
+                    sw = 1; // switch on
+                }
+
+                if(cmd == 0) {
+                    sw = 0; // switch off
+                }
+
+                httpHeader = HTTP_OK;
+                http_send(client, httpHeader, view(sw));
+            }
+
+            client.close();
+
+            serial.printf("Connection closed.\n\rTCP server is listening...\n\r");
+        }
+    }
+}