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 Mar 16 09:43:13 2015 +0000
Revision:
5:0ab8292e37da
Parent:
4:d34811deedab
Child:
6:b38a3b476a45
Child:
10:b47c7921346f
Updated

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 5:0ab8292e37da 1 /*
hudakz 5:0ab8292e37da 2 * In this project LED1 on the mbed board is switched on/off using a web browser.
hudakz 5:0ab8292e37da 3 * However, you can easily modify the project to remotely switch on/off any external device.
hudakz 5:0ab8292e37da 4 * The HTTP server is built from an mbed board and an ENC28J60 board.
hudakz 5:0ab8292e37da 5 * ENC28J60 is driven by the UIPEthernet library <https://github.com/ntruchsess/arduino_uip>.
hudakz 4:d34811deedab 6 * The example is based on the Tuxgraphics Web Switch <http://www.tuxgraphics.org/>.
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 5:0ab8292e37da 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 5:0ab8292e37da 19 UIPEthernetClass UIPEthernet(p11, p12, p13, p8); // mosi, miso, sck, cs
hudakz 0:68a0003c4cb8 20 #elif defined(TARGET_LPC1114)
hudakz 5:0ab8292e37da 21 UIPEthernetClass UIPEthernet(dp2, dp1, dp6, dp25); // mosi, miso, sck, cs
hudakz 0:68a0003c4cb8 22 #elif defined(TARGET_LPC11U68)
hudakz 5:0ab8292e37da 23 UIPEthernetClass UIPEthernet(P0_9, P0_8, P1_29, P0_2); // mosi, miso, sck, cs
hudakz 5:0ab8292e37da 24 #elif defined(TARGET_NUCLEO_F103RB)
hudakz 5:0ab8292e37da 25 UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs
hudakz 5:0ab8292e37da 26 #elif defined(TARGET_NUCLEO_F401RE)
hudakz 5:0ab8292e37da 27 UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs
hudakz 5:0ab8292e37da 28 #elif defined(TARGET_NUCLEO_F411RE)
hudakz 5:0ab8292e37da 29 UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs
hudakz 4:d34811deedab 30
hudakz 5:0ab8292e37da 31 // If your board/plaform is not present yet then uncomment
hudakz 5:0ab8292e37da 32 // the following two lines and replace TARGET_YOUR_BOARD as appropriate.
hudakz 4:d34811deedab 33
hudakz 5:0ab8292e37da 34 //#elif defined(TARGET_YOUR_BOARD)
hudakz 5:0ab8292e37da 35 //UIPEthernetClass UIPEthernet(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS); // mosi, miso, sck, cs
hudakz 4:d34811deedab 36
hudakz 0:68a0003c4cb8 37 #endif
hudakz 0:68a0003c4cb8 38
hudakz 4:d34811deedab 39 // Note:
hudakz 4:d34811deedab 40 // If it happends that any of the SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS pins collide with LED1 pin
hudakz 5:0ab8292e37da 41 // then either use different SPI port (if available on the board) and change the pin names
hudakz 5:0ab8292e37da 42 // in the constructor UIPEthernet(...) accordingly or instead of using LED1 pin, select
hudakz 5:0ab8292e37da 43 // a free pin (not used by SPI port) and connect to it an external LED which is connected
hudakz 5:0ab8292e37da 44 // to a 220 Ohm resitor that is connected to the groud.
hudakz 4:d34811deedab 45 // In the second case remember to replace LED1 in sw(LED1) constructor (see below).
hudakz 5:0ab8292e37da 46 // MAC number must be unique within the connected network. Modify as appropriate.
hudakz 5:0ab8292e37da 47 const uint8_t MY_MAC[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 };
hudakz 4:d34811deedab 48
hudakz 0:68a0003c4cb8 49 // IP address must be also unique and compatible with your network. Change as appropriate.
hudakz 5:0ab8292e37da 50 const IPAddress MY_IP(192, 168, 1, 181);
hudakz 5:0ab8292e37da 51 const uint16_t MY_PORT = 80; // for HTTP connection
hudakz 5:0ab8292e37da 52 EthernetServer myServer = EthernetServer(MY_PORT);
hudakz 5:0ab8292e37da 53
hudakz 0:68a0003c4cb8 54 // In this example we are turning on/off LED1.
hudakz 5:0ab8292e37da 55 DigitalOut sw(LED1); // Change LED1 to a pin of your choice.
hudakz 0:68a0003c4cb8 56
hudakz 5:0ab8292e37da 57 // However, make sure that it does not collide with any of the SPI pins
hudakz 5:0ab8292e37da 58 // already used in the UIPEthernet(...) constructor above!
hudakz 5:0ab8292e37da 59 const string PASSWORD = "secret"; // change as you like
hudakz 5:0ab8292e37da 60 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 5:0ab8292e37da 61 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 5:0ab8292e37da 62 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 5:0ab8292e37da 63 string httpHeader; // HTTP header
hudakz 5:0ab8292e37da 64 string httpContent; // HTTP content
hudakz 0:68a0003c4cb8 65
hudakz 0:68a0003c4cb8 66 // analyse the url given
hudakz 0:68a0003c4cb8 67 // return values: -1 invalid password
hudakz 0:68a0003c4cb8 68 // -2 no command given but password valid
hudakz 0:68a0003c4cb8 69 // -3 just refresh page
hudakz 0:68a0003c4cb8 70 // 0 switch off
hudakz 0:68a0003c4cb8 71 // 1 switch on
hudakz 0:68a0003c4cb8 72 //
hudakz 0:68a0003c4cb8 73 // The string passed to this function will look like this:
hudakz 0:68a0003c4cb8 74 // GET /password HTTP/1.....
hudakz 0:68a0003c4cb8 75 // GET /password/ HTTP/1.....
hudakz 0:68a0003c4cb8 76 // GET /password/?sw=1 HTTP/1.....
hudakz 0:68a0003c4cb8 77 // GET /password/?sw=0 HTTP/1.....
hudakz 5:0ab8292e37da 78 int8_t analyse_get_url(string& str) {
hudakz 0:68a0003c4cb8 79 if(str.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:68a0003c4cb8 80 return(-1);
hudakz 0:68a0003c4cb8 81
hudakz 0:68a0003c4cb8 82 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:68a0003c4cb8 83
hudakz 0:68a0003c4cb8 84 if(str.substr(pos, 1) == " ")
hudakz 0:68a0003c4cb8 85 return(-2);
hudakz 0:68a0003c4cb8 86
hudakz 0:68a0003c4cb8 87 if(str.substr(pos, 1) != "/")
hudakz 0:68a0003c4cb8 88 return(-1);
hudakz 0:68a0003c4cb8 89
hudakz 0:68a0003c4cb8 90 pos++;
hudakz 0:68a0003c4cb8 91
hudakz 5:0ab8292e37da 92 string cmd(str.substr(pos, 5));
hudakz 0:68a0003c4cb8 93
hudakz 0:68a0003c4cb8 94 if(cmd == "?sw=0")
hudakz 0:68a0003c4cb8 95 return(0);
hudakz 0:68a0003c4cb8 96
hudakz 0:68a0003c4cb8 97 if(cmd == "?sw=1")
hudakz 0:68a0003c4cb8 98 return(1);
hudakz 0:68a0003c4cb8 99
hudakz 0:68a0003c4cb8 100 return(-3);
hudakz 0:68a0003c4cb8 101 }
hudakz 0:68a0003c4cb8 102
hudakz 5:0ab8292e37da 103 /**
hudakz 5:0ab8292e37da 104 * @brief
hudakz 5:0ab8292e37da 105 * @note
hudakz 5:0ab8292e37da 106 * @param
hudakz 5:0ab8292e37da 107 * @retval
hudakz 5:0ab8292e37da 108 */
hudakz 5:0ab8292e37da 109 string& moved_perm(uint8_t flag) {
hudakz 0:68a0003c4cb8 110 if(flag == 1)
hudakz 5:0ab8292e37da 111 httpContent = "/" + PASSWORD + "/";
hudakz 0:68a0003c4cb8 112 else
hudakz 0:68a0003c4cb8 113 httpContent = "";
hudakz 0:68a0003c4cb8 114
hudakz 0:68a0003c4cb8 115 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:68a0003c4cb8 116
hudakz 5:0ab8292e37da 117 return(httpContent);
hudakz 0:68a0003c4cb8 118 }
hudakz 0:68a0003c4cb8 119
hudakz 5:0ab8292e37da 120 /**
hudakz 5:0ab8292e37da 121 * @brief
hudakz 5:0ab8292e37da 122 * @note
hudakz 5:0ab8292e37da 123 * @param
hudakz 5:0ab8292e37da 124 * @retval
hudakz 5:0ab8292e37da 125 */
hudakz 5:0ab8292e37da 126 string& view(uint8_t status) {
hudakz 0:68a0003c4cb8 127 httpContent = "<h2>Web Switch</h2>\r\n";
hudakz 0:68a0003c4cb8 128
hudakz 0:68a0003c4cb8 129 if(status == 1) {
hudakz 0:68a0003c4cb8 130 httpContent += "<pre>\r\n <font color=#FF0000>ON</font>";
hudakz 0:68a0003c4cb8 131 httpContent += " <a href=\"./?sw=0\">[switch off]</a>\r\n";
hudakz 5:0ab8292e37da 132 }
hudakz 5:0ab8292e37da 133 else {
hudakz 0:68a0003c4cb8 134 httpContent += "<pre>\r\n <font color=#00FF00>OFF</font>";
hudakz 0:68a0003c4cb8 135 httpContent += " <a href=\"./?sw=1\">[switch on]</a>\r\n";
hudakz 0:68a0003c4cb8 136 }
hudakz 0:68a0003c4cb8 137
hudakz 0:68a0003c4cb8 138 httpContent += " <a href=\".\">[refresh status]</a>\r\n";
hudakz 0:68a0003c4cb8 139 httpContent += "</pre>\r\n";
hudakz 0:68a0003c4cb8 140 httpContent += "<hr>\r\n";
hudakz 0:68a0003c4cb8 141 return httpContent;
hudakz 0:68a0003c4cb8 142 }
hudakz 0:68a0003c4cb8 143
hudakz 5:0ab8292e37da 144 /**
hudakz 5:0ab8292e37da 145 * @brief
hudakz 5:0ab8292e37da 146 * @note
hudakz 5:0ab8292e37da 147 * @param
hudakz 5:0ab8292e37da 148 * @retval
hudakz 5:0ab8292e37da 149 */
hudakz 5:0ab8292e37da 150 void http_send(EthernetClient& client, string& header, string& content) {
hudakz 5:0ab8292e37da 151 char content_length[5] = { };
hudakz 0:68a0003c4cb8 152
hudakz 2:76f339a1ba9b 153 header += "\r\nContent-Type: text/html\r\n";
hudakz 0:68a0003c4cb8 154 header += "Content-Length: ";
hudakz 0:68a0003c4cb8 155 sprintf(content_length, "%d", content.length());
hudakz 0:68a0003c4cb8 156 header += string(content_length) + "\r\n";
hudakz 0:68a0003c4cb8 157 header += "Pragma: no-cache\r\n";
hudakz 0:68a0003c4cb8 158 header += "Connection: About to close\r\n";
hudakz 0:68a0003c4cb8 159 header += "\r\n";
hudakz 5:0ab8292e37da 160
hudakz 5:0ab8292e37da 161 string webpage = header + content;
hudakz 5:0ab8292e37da 162 client.write((uint8_t*)webpage.c_str(), webpage.length());
hudakz 0:68a0003c4cb8 163 }
hudakz 0:68a0003c4cb8 164
hudakz 5:0ab8292e37da 165 /**
hudakz 5:0ab8292e37da 166 * @brief
hudakz 5:0ab8292e37da 167 * @note
hudakz 5:0ab8292e37da 168 * @param
hudakz 5:0ab8292e37da 169 * @retval
hudakz 5:0ab8292e37da 170 */
hudakz 5:0ab8292e37da 171 int main(void) {
hudakz 5:0ab8292e37da 172 UIPEthernet.begin(MY_MAC, MY_IP);
hudakz 0:68a0003c4cb8 173 myServer.begin();
hudakz 0:68a0003c4cb8 174 while(1) {
hudakz 5:0ab8292e37da 175 EthernetClient client = myServer.available();
hudakz 5:0ab8292e37da 176 if(client) {
hudakz 5:0ab8292e37da 177 size_t size = client.available();
hudakz 0:68a0003c4cb8 178 if(size > 0) {
hudakz 5:0ab8292e37da 179 uint8_t* buf = (uint8_t*)malloc(size);
hudakz 0:68a0003c4cb8 180 size = client.read(buf, size);
hudakz 5:0ab8292e37da 181 string received((char*)buf);
hudakz 0:68a0003c4cb8 182 free(buf);
hudakz 5:0ab8292e37da 183
hudakz 0:68a0003c4cb8 184 if(received.substr(0, 3) != "GET") {
hudakz 0:68a0003c4cb8 185 httpHeader = HTTP_OK;
hudakz 0:68a0003c4cb8 186 httpContent = "<h1>200 OK</h1>";
hudakz 0:68a0003c4cb8 187 http_send(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 188 continue;
hudakz 0:68a0003c4cb8 189 }
hudakz 0:68a0003c4cb8 190
hudakz 0:68a0003c4cb8 191 if(received.substr(0, 6) == "GET / ") {
hudakz 0:68a0003c4cb8 192 httpHeader = HTTP_OK;
hudakz 0:68a0003c4cb8 193 httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n";
hudakz 0:68a0003c4cb8 194 http_send(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 195 continue;
hudakz 0:68a0003c4cb8 196 }
hudakz 0:68a0003c4cb8 197
hudakz 0:68a0003c4cb8 198 int cmd = analyse_get_url(received);
hudakz 0:68a0003c4cb8 199
hudakz 0:68a0003c4cb8 200 if(cmd == -2) {
hudakz 0:68a0003c4cb8 201 // redirect to the right base url
hudakz 0:68a0003c4cb8 202 httpHeader = MOVED_PERM;
hudakz 0:68a0003c4cb8 203 http_send(client, httpHeader, moved_perm(1));
hudakz 0:68a0003c4cb8 204 continue;
hudakz 0:68a0003c4cb8 205 }
hudakz 0:68a0003c4cb8 206
hudakz 0:68a0003c4cb8 207 if(cmd == -1) {
hudakz 0:68a0003c4cb8 208 httpHeader = UNAUTHORIZED;
hudakz 0:68a0003c4cb8 209 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:68a0003c4cb8 210 http_send(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 211 continue;
hudakz 0:68a0003c4cb8 212 }
hudakz 0:68a0003c4cb8 213
hudakz 0:68a0003c4cb8 214 if(cmd == 1) {
hudakz 5:0ab8292e37da 215 sw = 1; // switch on
hudakz 0:68a0003c4cb8 216 }
hudakz 0:68a0003c4cb8 217
hudakz 0:68a0003c4cb8 218 if(cmd == 0) {
hudakz 5:0ab8292e37da 219 sw = 0; // switch off
hudakz 0:68a0003c4cb8 220 }
hudakz 0:68a0003c4cb8 221
hudakz 0:68a0003c4cb8 222 httpHeader = HTTP_OK;
hudakz 5:0ab8292e37da 223 http_send(client, httpHeader, view(sw));
hudakz 0:68a0003c4cb8 224 }
hudakz 0:68a0003c4cb8 225 }
hudakz 0:68a0003c4cb8 226 }
hudakz 0:68a0003c4cb8 227 }