HTTP Server serving a simple webpage which enables to remotely turn a digital output on/off. Compile, download, run and type 'IP_address/secret/' (don't forget the last '/') into your web browser and hit ENTER.

Dependencies:   UIPEthernet

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. An inexpensive ENC28J60 Ethernet module is used to assure connection between the mbed board and the Ethernet network (Internet). The ENC28J60 Ethernet module is driven by the UIPEthernet library.

Needed parts:

  • mbed board
  • ENC28J60 Ethernet module
  • Wires
  • Web browser (Internet Explorer, Safari, Firefox, Chrome ...) running on Windows, Mac, Linux, iPhone or Android device.
/media/uploads/hudakz/webswitch_enc.jpg/media/uploads/hudakz/webswitch_mobile01.jpg

Notice that DHCP is turned on by default. If you prefer to use static IP address then uncomment line 234

The IP address assigned to the WebSwitch server along with an instruction how to use it is printed in the connected PC's serial terminal window during program start up.

Warning

Please notice that the 3.3V power supply chip (RT8183-B) installed on an STM32F103C8T6 board is not rated to power also the ENC28J60 board.


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

NOTE:

Committer:
hudakz
Date:
Mon Sep 15 11:17:50 2014 +0000
Revision:
0:68a0003c4cb8
Child:
1:3d9c83af7246
rev. 00

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:68a0003c4cb8 1 /* In this example LED1 is switched on/off using a web browser connected to this HTTP server.
hudakz 0:68a0003c4cb8 2 * The example is based on the Tuxgraphics Web Switch <tuxgraphics.org>.
hudakz 0:68a0003c4cb8 3 * This HTTP server is built around the UIPEthernet library for the ENC28J60 chip <https://github.com/ntruchsess/arduino_uip>
hudakz 0:68a0003c4cb8 4 * ported to mbed.
hudakz 0:68a0003c4cb8 5 */
hudakz 0:68a0003c4cb8 6
hudakz 0:68a0003c4cb8 7 #include <mbed.h>
hudakz 0:68a0003c4cb8 8 #include <UIPEthernet.h>
hudakz 0:68a0003c4cb8 9 #include <UIPServer.h>
hudakz 0:68a0003c4cb8 10 #include <UIPClient.h>
hudakz 0:68a0003c4cb8 11 #include <string>
hudakz 0:68a0003c4cb8 12
hudakz 0:68a0003c4cb8 13 using namespace std;
hudakz 0:68a0003c4cb8 14
hudakz 0:68a0003c4cb8 15 // UIPEthernet is the name of a global instance of UIPEthernetClass.
hudakz 0:68a0003c4cb8 16 // Do not change the name! It is used within the UIPEthernet library.
hudakz 0:68a0003c4cb8 17 // Adapt the SPI pin names to your mbed platform/board if not present yet.
hudakz 0:68a0003c4cb8 18 #if defined(TARGET_LPC1768)
hudakz 0:68a0003c4cb8 19 UIPEthernetClass UIPEthernet(p11, p12, p13, p8); // mosi, miso, sck, cs
hudakz 0:68a0003c4cb8 20 #elif defined(TARGET_LPC1114)
hudakz 0:68a0003c4cb8 21 UIPEthernetClass UIPEthernet(dp2, dp1, dp6, dp25); // mosi, miso, sck, cs
hudakz 0:68a0003c4cb8 22 #elif defined(TARGET_LPC11U68)
hudakz 0:68a0003c4cb8 23 UIPEthernetClass UIPEthernet(P0_9, P0_8, P1_29, P0_2); // mosi, miso, sck, cs
hudakz 0:68a0003c4cb8 24 #elif defined (TARGET_NUCLEO_F103RB)
hudakz 0:68a0003c4cb8 25 UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs
hudakz 0:68a0003c4cb8 26 #endif
hudakz 0:68a0003c4cb8 27
hudakz 0:68a0003c4cb8 28
hudakz 0:68a0003c4cb8 29 // MAC number must be unique within the connected network. Modify as appropriate.
hudakz 0:68a0003c4cb8 30 const uint8_t MY_MAC[6] = {0x00,0x01,0x02,0x03,0x04,0x05};
hudakz 0:68a0003c4cb8 31 // IP address must be also unique and compatible with your network. Change as appropriate.
hudakz 0:68a0003c4cb8 32 const IPAddress MY_IP(192,168,1,181);
hudakz 0:68a0003c4cb8 33 const uint16_t MY_PORT = 80; // for HTTP connection
hudakz 0:68a0003c4cb8 34 EthernetServer myServer = EthernetServer(MY_PORT);
hudakz 0:68a0003c4cb8 35 // In this example we are turning on/off LED1.
hudakz 0:68a0003c4cb8 36 // Change the pin name if you would like to switch on/off something else.
hudakz 0:68a0003c4cb8 37 // However, make sure you avoid SPI pin names used already for UIPEthernet.
hudakz 0:68a0003c4cb8 38 DigitalOut sw(LED1);
hudakz 0:68a0003c4cb8 39
hudakz 0:68a0003c4cb8 40 const string PASSWORD = "secret"; // change as you like
hudakz 0:68a0003c4cb8 41 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 0:68a0003c4cb8 42 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 0:68a0003c4cb8 43 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 0:68a0003c4cb8 44 string httpHeader; // HTTP header
hudakz 0:68a0003c4cb8 45 string httpContent; // HTTP content
hudakz 0:68a0003c4cb8 46
hudakz 0:68a0003c4cb8 47
hudakz 0:68a0003c4cb8 48 // analyse the url given
hudakz 0:68a0003c4cb8 49 // return values: -1 invalid password
hudakz 0:68a0003c4cb8 50 // -2 no command given but password valid
hudakz 0:68a0003c4cb8 51 // -3 just refresh page
hudakz 0:68a0003c4cb8 52 // 0 switch off
hudakz 0:68a0003c4cb8 53 // 1 switch on
hudakz 0:68a0003c4cb8 54 //
hudakz 0:68a0003c4cb8 55 // The string passed to this function will look like this:
hudakz 0:68a0003c4cb8 56 // GET /password HTTP/1.....
hudakz 0:68a0003c4cb8 57 // GET /password/ HTTP/1.....
hudakz 0:68a0003c4cb8 58 // GET /password/?sw=1 HTTP/1.....
hudakz 0:68a0003c4cb8 59 // GET /password/?sw=0 HTTP/1.....
hudakz 0:68a0003c4cb8 60
hudakz 0:68a0003c4cb8 61 int8_t analyse_get_url(string& str)
hudakz 0:68a0003c4cb8 62 {
hudakz 0:68a0003c4cb8 63 if(str.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:68a0003c4cb8 64 return(-1);
hudakz 0:68a0003c4cb8 65
hudakz 0:68a0003c4cb8 66 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:68a0003c4cb8 67
hudakz 0:68a0003c4cb8 68 if(str.substr(pos, 1) == " ")
hudakz 0:68a0003c4cb8 69 return(-2);
hudakz 0:68a0003c4cb8 70
hudakz 0:68a0003c4cb8 71 if(str.substr(pos, 1) != "/")
hudakz 0:68a0003c4cb8 72 return(-1);
hudakz 0:68a0003c4cb8 73
hudakz 0:68a0003c4cb8 74 pos++;
hudakz 0:68a0003c4cb8 75
hudakz 0:68a0003c4cb8 76 string cmd(str.substr(pos, 5));
hudakz 0:68a0003c4cb8 77
hudakz 0:68a0003c4cb8 78 if(cmd == "?sw=0")
hudakz 0:68a0003c4cb8 79 return(0);
hudakz 0:68a0003c4cb8 80
hudakz 0:68a0003c4cb8 81 if(cmd == "?sw=1")
hudakz 0:68a0003c4cb8 82 return(1);
hudakz 0:68a0003c4cb8 83
hudakz 0:68a0003c4cb8 84 return(-3);
hudakz 0:68a0003c4cb8 85 }
hudakz 0:68a0003c4cb8 86
hudakz 0:68a0003c4cb8 87 string& moved_perm(uint8_t flag)
hudakz 0:68a0003c4cb8 88 {
hudakz 0:68a0003c4cb8 89 if(flag == 1)
hudakz 0:68a0003c4cb8 90 httpContent = "/" + PASSWORD + "/";
hudakz 0:68a0003c4cb8 91 else
hudakz 0:68a0003c4cb8 92 httpContent = "";
hudakz 0:68a0003c4cb8 93
hudakz 0:68a0003c4cb8 94 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:68a0003c4cb8 95
hudakz 0:68a0003c4cb8 96 return (httpContent);
hudakz 0:68a0003c4cb8 97 }
hudakz 0:68a0003c4cb8 98
hudakz 0:68a0003c4cb8 99 string& page(uint8_t status)
hudakz 0:68a0003c4cb8 100 {
hudakz 0:68a0003c4cb8 101 httpContent = "<h2>Web Switch</h2>\r\n";
hudakz 0:68a0003c4cb8 102
hudakz 0:68a0003c4cb8 103 if(status == 1) {
hudakz 0:68a0003c4cb8 104 httpContent += "<pre>\r\n <font color=#FF0000>ON</font>";
hudakz 0:68a0003c4cb8 105 httpContent += " <a href=\"./?sw=0\">[switch off]</a>\r\n";
hudakz 0:68a0003c4cb8 106 } else {
hudakz 0:68a0003c4cb8 107 httpContent += "<pre>\r\n <font color=#00FF00>OFF</font>";
hudakz 0:68a0003c4cb8 108 httpContent += " <a href=\"./?sw=1\">[switch on]</a>\r\n";
hudakz 0:68a0003c4cb8 109 }
hudakz 0:68a0003c4cb8 110
hudakz 0:68a0003c4cb8 111 httpContent += " <a href=\".\">[refresh status]</a>\r\n";
hudakz 0:68a0003c4cb8 112 httpContent += "</pre>\r\n";
hudakz 0:68a0003c4cb8 113 httpContent += "<hr>\r\n";
hudakz 0:68a0003c4cb8 114 return httpContent;
hudakz 0:68a0003c4cb8 115 }
hudakz 0:68a0003c4cb8 116
hudakz 0:68a0003c4cb8 117 void http_send(EthernetClient& client, string& header, string& content)
hudakz 0:68a0003c4cb8 118 {
hudakz 0:68a0003c4cb8 119 char content_length[5] = {};
hudakz 0:68a0003c4cb8 120
hudakz 0:68a0003c4cb8 121 header += "\r\nContent-Type: text\r\n";
hudakz 0:68a0003c4cb8 122 header += "Content-Length: ";
hudakz 0:68a0003c4cb8 123 sprintf(content_length, "%d", content.length());
hudakz 0:68a0003c4cb8 124 header += string(content_length) + "\r\n";
hudakz 0:68a0003c4cb8 125 header += "Pragma: no-cache\r\n";
hudakz 0:68a0003c4cb8 126 header += "Connection: About to close\r\n";
hudakz 0:68a0003c4cb8 127 header += "\r\n";
hudakz 0:68a0003c4cb8 128 string webpage = header + content;
hudakz 0:68a0003c4cb8 129 client.write((uint8_t*)webpage.c_str(),webpage.length());
hudakz 0:68a0003c4cb8 130 }
hudakz 0:68a0003c4cb8 131
hudakz 0:68a0003c4cb8 132 int main()
hudakz 0:68a0003c4cb8 133 {
hudakz 0:68a0003c4cb8 134 Ethernet.begin(MY_MAC,MY_IP);
hudakz 0:68a0003c4cb8 135 myServer.begin();
hudakz 0:68a0003c4cb8 136 while(1) {
hudakz 0:68a0003c4cb8 137 EthernetClient client = myServer.available();
hudakz 0:68a0003c4cb8 138 if (client) {
hudakz 0:68a0003c4cb8 139 size_t size = client.available();
hudakz 0:68a0003c4cb8 140 if(size > 0) {
hudakz 0:68a0003c4cb8 141 uint8_t* buf = (uint8_t*)malloc(size);
hudakz 0:68a0003c4cb8 142 size = client.read(buf, size);
hudakz 0:68a0003c4cb8 143 string received((char*)buf);
hudakz 0:68a0003c4cb8 144 free(buf);
hudakz 0:68a0003c4cb8 145 if(received.substr(0, 3) != "GET") {
hudakz 0:68a0003c4cb8 146 // head, post or other method
hudakz 0:68a0003c4cb8 147 // for possible status codes see:
hudakz 0:68a0003c4cb8 148 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
hudakz 0:68a0003c4cb8 149 httpHeader = HTTP_OK;
hudakz 0:68a0003c4cb8 150 httpContent = "<h1>200 OK</h1>";
hudakz 0:68a0003c4cb8 151 http_send(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 152 continue;
hudakz 0:68a0003c4cb8 153 }
hudakz 0:68a0003c4cb8 154
hudakz 0:68a0003c4cb8 155 if(received.substr(0, 6) == "GET / ") {
hudakz 0:68a0003c4cb8 156 httpHeader = HTTP_OK;
hudakz 0:68a0003c4cb8 157 httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n";
hudakz 0:68a0003c4cb8 158 http_send(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 159 continue;
hudakz 0:68a0003c4cb8 160 }
hudakz 0:68a0003c4cb8 161
hudakz 0:68a0003c4cb8 162 int cmd = analyse_get_url(received);
hudakz 0:68a0003c4cb8 163
hudakz 0:68a0003c4cb8 164 if(cmd == -2) {
hudakz 0:68a0003c4cb8 165 // redirect to the right base url
hudakz 0:68a0003c4cb8 166 httpHeader = MOVED_PERM;
hudakz 0:68a0003c4cb8 167 http_send(client, httpHeader, moved_perm(1));
hudakz 0:68a0003c4cb8 168 continue;
hudakz 0:68a0003c4cb8 169 }
hudakz 0:68a0003c4cb8 170
hudakz 0:68a0003c4cb8 171 if(cmd == -1) {
hudakz 0:68a0003c4cb8 172 httpHeader = UNAUTHORIZED;
hudakz 0:68a0003c4cb8 173 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:68a0003c4cb8 174 http_send(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 175 continue;
hudakz 0:68a0003c4cb8 176 }
hudakz 0:68a0003c4cb8 177
hudakz 0:68a0003c4cb8 178 if(cmd == 1) {
hudakz 0:68a0003c4cb8 179 sw = 1; // switch on
hudakz 0:68a0003c4cb8 180 }
hudakz 0:68a0003c4cb8 181
hudakz 0:68a0003c4cb8 182 if(cmd == 0) {
hudakz 0:68a0003c4cb8 183 sw = 0; // switch off
hudakz 0:68a0003c4cb8 184 }
hudakz 0:68a0003c4cb8 185
hudakz 0:68a0003c4cb8 186 httpHeader = HTTP_OK;
hudakz 0:68a0003c4cb8 187 http_send(client, httpHeader, page(sw));
hudakz 0:68a0003c4cb8 188 }
hudakz 0:68a0003c4cb8 189 }
hudakz 0:68a0003c4cb8 190 }
hudakz 0:68a0003c4cb8 191 }
hudakz 0:68a0003c4cb8 192