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:
Wed Feb 04 19:27:26 2015 +0000
Revision:
4:d34811deedab
Parent:
3:0133517ba02d
Child:
5:0ab8292e37da
Rev 02

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