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:
Tue Feb 05 14:15:05 2019 +0000
Revision:
9:6f63abd61de8
Parent:
8:3bd85b731cca
Updated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 7:f5e11393836d 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 7:f5e11393836d 8
hudakz 7:f5e11393836d 9 //#define TARGET_STM32F103C8T6 1 // uncomment this line when using STM32F103C8T6 boards!
hudakz 6:b38a3b476a45 10
hudakz 6:b38a3b476a45 11 #if defined(TARGET_STM32F103C8T6)
hudakz 7:f5e11393836d 12 #define LED_PIN PC_13
hudakz 7:f5e11393836d 13 const int OFF = 1;
hudakz 7:f5e11393836d 14 const int ON = 0;
hudakz 6:b38a3b476a45 15 #else
hudakz 7:f5e11393836d 16 #define LED_PIN LED1
hudakz 7:f5e11393836d 17 const int OFF = 0;
hudakz 7:f5e11393836d 18 const int ON = 1;
hudakz 6:b38a3b476a45 19 #endif
hudakz 6:b38a3b476a45 20
hudakz 6:b38a3b476a45 21 #include "mbed.h"
hudakz 6:b38a3b476a45 22 #include "UIPEthernet.h"
hudakz 6:b38a3b476a45 23 #include "UIPServer.h"
hudakz 6:b38a3b476a45 24 #include "UIPClient.h"
hudakz 6:b38a3b476a45 25 #include "string"
hudakz 0:68a0003c4cb8 26
hudakz 5:0ab8292e37da 27 using namespace std;
hudakz 0:68a0003c4cb8 28
hudakz 9:6f63abd61de8 29 Serial pc(PA_2, PA_3);
hudakz 6:b38a3b476a45 30
hudakz 9:6f63abd61de8 31 //#define DHCP 1 // if you'd like to use static IP address comment out this line
hudakz 6:b38a3b476a45 32
hudakz 8:3bd85b731cca 33 // uIPEthernet is the name of a global instance of UIPEthernet.
hudakz 0:68a0003c4cb8 34 // Do not change the name! It is used within the UIPEthernet library.
hudakz 9:6f63abd61de8 35 UIPEthernet uIPEthernet(PB_5, PB_4, PB_3, PA_10); // mosi, miso, sck, cs
hudakz 0:68a0003c4cb8 36
hudakz 4:d34811deedab 37 // Note:
hudakz 4:d34811deedab 38 // If it happends that any of the SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS pins collide with LED1 pin
hudakz 5:0ab8292e37da 39 // then either use different SPI port (if available on the board) and change the pin names
hudakz 8:3bd85b731cca 40 // in the constructor uIPEthernet(...) accordingly or instead of using LED1 pin, select
hudakz 5:0ab8292e37da 41 // a free pin (not used by SPI port) and connect to it an external LED which is connected
hudakz 5:0ab8292e37da 42 // to a 220 Ohm resitor that is connected to the groud.
hudakz 4:d34811deedab 43 // In the second case remember to replace LED1 in sw(LED1) constructor (see below).
hudakz 5:0ab8292e37da 44 // MAC number must be unique within the connected network. Modify as appropriate.
hudakz 5:0ab8292e37da 45 const uint8_t MY_MAC[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 };
hudakz 5:0ab8292e37da 46 const uint16_t MY_PORT = 80; // for HTTP connection
hudakz 5:0ab8292e37da 47 EthernetServer myServer = EthernetServer(MY_PORT);
hudakz 5:0ab8292e37da 48
hudakz 0:68a0003c4cb8 49 // In this example we are turning on/off LED1.
hudakz 7:f5e11393836d 50 DigitalOut sw(LED_PIN); // Change LED_PIN to a pin of your choice.
hudakz 7:f5e11393836d 51 //DigitalOut sw(D9); // Change LED_PIN to a pin of your choice.
hudakz 7:f5e11393836d 52 float roomTemp = 21.8; // A temperature sensor output
hudakz 0:68a0003c4cb8 53
hudakz 5:0ab8292e37da 54 // However, make sure that it does not collide with any of the SPI pins
hudakz 8:3bd85b731cca 55 // already used in the uIPEthernet(...) constructor above!
hudakz 5:0ab8292e37da 56 const string PASSWORD = "secret"; // change as you like
hudakz 5:0ab8292e37da 57 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 5:0ab8292e37da 58 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 5:0ab8292e37da 59 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 5:0ab8292e37da 60 string httpHeader; // HTTP header
hudakz 5:0ab8292e37da 61 string httpContent; // HTTP content
hudakz 0:68a0003c4cb8 62
hudakz 7:f5e11393836d 63 /**
hudakz 7:f5e11393836d 64 * @brief Analyses the received URL
hudakz 7:f5e11393836d 65 * @note The string passed to this function will look like this:
hudakz 7:f5e11393836d 66 * GET /password HTTP/1.....
hudakz 7:f5e11393836d 67 * GET /password/ HTTP/1.....
hudakz 7:f5e11393836d 68 * GET /password/?sw=1 HTTP/1.....
hudakz 7:f5e11393836d 69 * GET /password/?sw=0 HTTP/1.....
hudakz 7:f5e11393836d 70 * @param url URL string
hudakz 7:f5e11393836d 71 * @retval -1 invalid password
hudakz 7:f5e11393836d 72 * -2 no command given but password valid
hudakz 7:f5e11393836d 73 * -3 just refresh page
hudakz 7:f5e11393836d 74 * 0 switch off
hudakz 7:f5e11393836d 75 * 1 switch on
hudakz 7:f5e11393836d 76 */
hudakz 7:f5e11393836d 77 int8_t analyseURL(string& url) {
hudakz 7:f5e11393836d 78 if(url.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:68a0003c4cb8 79 return(-1);
hudakz 0:68a0003c4cb8 80
hudakz 0:68a0003c4cb8 81 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:68a0003c4cb8 82
hudakz 7:f5e11393836d 83 if(url.substr(pos, 1) == " ")
hudakz 0:68a0003c4cb8 84 return(-2);
hudakz 0:68a0003c4cb8 85
hudakz 7:f5e11393836d 86 if(url.substr(pos++, 1) != "/")
hudakz 0:68a0003c4cb8 87 return(-1);
hudakz 0:68a0003c4cb8 88
hudakz 7:f5e11393836d 89 string cmd(url.substr(pos, 5));
hudakz 0:68a0003c4cb8 90
hudakz 0:68a0003c4cb8 91 if(cmd == "?sw=0")
hudakz 6:b38a3b476a45 92 return(OFF);
hudakz 0:68a0003c4cb8 93
hudakz 0:68a0003c4cb8 94 if(cmd == "?sw=1")
hudakz 6:b38a3b476a45 95 return(ON);
hudakz 0:68a0003c4cb8 96
hudakz 0:68a0003c4cb8 97 return(-3);
hudakz 0:68a0003c4cb8 98 }
hudakz 0:68a0003c4cb8 99
hudakz 5:0ab8292e37da 100 /**
hudakz 5:0ab8292e37da 101 * @brief
hudakz 5:0ab8292e37da 102 * @note
hudakz 5:0ab8292e37da 103 * @param
hudakz 5:0ab8292e37da 104 * @retval
hudakz 5:0ab8292e37da 105 */
hudakz 7:f5e11393836d 106 string& movedPermanently(uint8_t flag)
hudakz 7:f5e11393836d 107 {
hudakz 0:68a0003c4cb8 108 if(flag == 1)
hudakz 5:0ab8292e37da 109 httpContent = "/" + PASSWORD + "/";
hudakz 0:68a0003c4cb8 110 else
hudakz 0:68a0003c4cb8 111 httpContent = "";
hudakz 0:68a0003c4cb8 112
hudakz 0:68a0003c4cb8 113 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:68a0003c4cb8 114
hudakz 5:0ab8292e37da 115 return(httpContent);
hudakz 0:68a0003c4cb8 116 }
hudakz 0:68a0003c4cb8 117
hudakz 5:0ab8292e37da 118 /**
hudakz 5:0ab8292e37da 119 * @brief
hudakz 5:0ab8292e37da 120 * @note
hudakz 5:0ab8292e37da 121 * @param
hudakz 5:0ab8292e37da 122 * @retval
hudakz 5:0ab8292e37da 123 */
hudakz 6:b38a3b476a45 124 string& showWebPage(uint8_t status) {
hudakz 7:f5e11393836d 125 char roomTempStr[5];
hudakz 7:f5e11393836d 126
hudakz 7:f5e11393836d 127 //roomTemp = ds1820.read();
hudakz 7:f5e11393836d 128 sprintf(roomTempStr, "%3.1f", roomTemp);
hudakz 7:f5e11393836d 129
hudakz 8:3bd85b731cca 130 httpContent = "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>";
hudakz 7:f5e11393836d 131 httpContent += "<pre>Temperature:\t" + string(roomTempStr) + "&deg;C\r\n</pre>";
hudakz 0:68a0003c4cb8 132
hudakz 6:b38a3b476a45 133 if(status == ON) {
hudakz 7:f5e11393836d 134 httpContent += "<pre>\r\nHeating:\t<font color=#FF0000>On </font>";
hudakz 7:f5e11393836d 135 httpContent += " <a href=\"./?sw=0\"><button>Turn off</button></a>\r\n";
hudakz 5:0ab8292e37da 136 }
hudakz 5:0ab8292e37da 137 else {
hudakz 7:f5e11393836d 138 httpContent += "<pre>\r\nHeating:\t<font color=#999999>Off</font>";
hudakz 7:f5e11393836d 139 httpContent += " <a href=\"./?sw=1\"><button>Turn on</button></a>\r\n";
hudakz 0:68a0003c4cb8 140 }
hudakz 0:68a0003c4cb8 141
hudakz 0:68a0003c4cb8 142 httpContent += "</pre>\r\n";
hudakz 0:68a0003c4cb8 143 httpContent += "<hr>\r\n";
hudakz 7:f5e11393836d 144 httpContent += "<pre>2017 ARMmbed</pre>";
hudakz 0:68a0003c4cb8 145 return httpContent;
hudakz 0:68a0003c4cb8 146 }
hudakz 0:68a0003c4cb8 147
hudakz 5:0ab8292e37da 148 /**
hudakz 5:0ab8292e37da 149 * @brief
hudakz 5:0ab8292e37da 150 * @note
hudakz 5:0ab8292e37da 151 * @param
hudakz 5:0ab8292e37da 152 * @retval
hudakz 5:0ab8292e37da 153 */
hudakz 7:f5e11393836d 154 void sendHTTP(EthernetClient& client, string& header, string& content)
hudakz 7:f5e11393836d 155 {
hudakz 5:0ab8292e37da 156 char content_length[5] = { };
hudakz 0:68a0003c4cb8 157
hudakz 2:76f339a1ba9b 158 header += "\r\nContent-Type: text/html\r\n";
hudakz 0:68a0003c4cb8 159 header += "Content-Length: ";
hudakz 0:68a0003c4cb8 160 sprintf(content_length, "%d", content.length());
hudakz 0:68a0003c4cb8 161 header += string(content_length) + "\r\n";
hudakz 0:68a0003c4cb8 162 header += "Pragma: no-cache\r\n";
hudakz 0:68a0003c4cb8 163 header += "Connection: About to close\r\n";
hudakz 0:68a0003c4cb8 164 header += "\r\n";
hudakz 5:0ab8292e37da 165
hudakz 5:0ab8292e37da 166 string webpage = header + content;
hudakz 5:0ab8292e37da 167 client.write((uint8_t*)webpage.c_str(), webpage.length());
hudakz 0:68a0003c4cb8 168 }
hudakz 0:68a0003c4cb8 169
hudakz 5:0ab8292e37da 170 /**
hudakz 5:0ab8292e37da 171 * @brief
hudakz 5:0ab8292e37da 172 * @note
hudakz 5:0ab8292e37da 173 * @param
hudakz 5:0ab8292e37da 174 * @retval
hudakz 5:0ab8292e37da 175 */
hudakz 7:f5e11393836d 176 int main(void)
hudakz 7:f5e11393836d 177 {
hudakz 7:f5e11393836d 178 #if defined(TARGET_STM32F103C8T6)
hudakz 7:f5e11393836d 179 confSysClock(); //Configure system clock (72MHz HSE clock, 48MHz USB clock)
hudakz 7:f5e11393836d 180 #endif
hudakz 6:b38a3b476a45 181 #if defined(DHCP)
hudakz 6:b38a3b476a45 182 pc.printf("Searching for DHCP server..\r\n");
hudakz 8:3bd85b731cca 183 if(uIPEthernet.begin(MY_MAC) != 1) {
hudakz 6:b38a3b476a45 184 pc.printf("No DHCP server found.\r\n");
hudakz 6:b38a3b476a45 185 pc.printf("Exiting application.\r\n");
hudakz 6:b38a3b476a45 186 return 0;
hudakz 6:b38a3b476a45 187 }
hudakz 6:b38a3b476a45 188 pc.printf("DHCP server found.\r\n");
hudakz 6:b38a3b476a45 189 #else
hudakz 6:b38a3b476a45 190 // IP address must be unique and compatible with your network.
hudakz 6:b38a3b476a45 191 const IPAddress MY_IP(192, 168, 1, 181); // Change as appropriate.
hudakz 8:3bd85b731cca 192 uIPEthernet.begin(MY_MAC, MY_IP);
hudakz 6:b38a3b476a45 193 #endif
hudakz 8:3bd85b731cca 194 IPAddress localIP = uIPEthernet.localIP();
hudakz 9:6f63abd61de8 195 pc.printf("Type %s/secret/ into your web browser and hit ENTER\r\n", localIP.toString());
hudakz 8:3bd85b731cca 196 myServer.begin();
hudakz 0:68a0003c4cb8 197 while(1) {
hudakz 5:0ab8292e37da 198 EthernetClient client = myServer.available();
hudakz 5:0ab8292e37da 199 if(client) {
hudakz 5:0ab8292e37da 200 size_t size = client.available();
hudakz 0:68a0003c4cb8 201 if(size > 0) {
hudakz 5:0ab8292e37da 202 uint8_t* buf = (uint8_t*)malloc(size);
hudakz 0:68a0003c4cb8 203 size = client.read(buf, size);
hudakz 5:0ab8292e37da 204 string received((char*)buf);
hudakz 0:68a0003c4cb8 205 free(buf);
hudakz 7:f5e11393836d 206
hudakz 0:68a0003c4cb8 207 if(received.substr(0, 3) != "GET") {
hudakz 0:68a0003c4cb8 208 httpHeader = HTTP_OK;
hudakz 0:68a0003c4cb8 209 httpContent = "<h1>200 OK</h1>";
hudakz 6:b38a3b476a45 210 sendHTTP(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 211 continue;
hudakz 0:68a0003c4cb8 212 }
hudakz 0:68a0003c4cb8 213
hudakz 0:68a0003c4cb8 214 if(received.substr(0, 6) == "GET / ") {
hudakz 0:68a0003c4cb8 215 httpHeader = HTTP_OK;
hudakz 0:68a0003c4cb8 216 httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n";
hudakz 6:b38a3b476a45 217 sendHTTP(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 218 continue;
hudakz 0:68a0003c4cb8 219 }
hudakz 0:68a0003c4cb8 220
hudakz 6:b38a3b476a45 221 int cmd = analyseURL(received);
hudakz 0:68a0003c4cb8 222
hudakz 0:68a0003c4cb8 223 if(cmd == -2) {
hudakz 0:68a0003c4cb8 224 // redirect to the right base url
hudakz 0:68a0003c4cb8 225 httpHeader = MOVED_PERM;
hudakz 6:b38a3b476a45 226 sendHTTP(client, httpHeader, movedPermanently(1));
hudakz 0:68a0003c4cb8 227 continue;
hudakz 0:68a0003c4cb8 228 }
hudakz 0:68a0003c4cb8 229
hudakz 0:68a0003c4cb8 230 if(cmd == -1) {
hudakz 0:68a0003c4cb8 231 httpHeader = UNAUTHORIZED;
hudakz 0:68a0003c4cb8 232 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 6:b38a3b476a45 233 sendHTTP(client, httpHeader, httpContent);
hudakz 0:68a0003c4cb8 234 continue;
hudakz 0:68a0003c4cb8 235 }
hudakz 0:68a0003c4cb8 236
hudakz 6:b38a3b476a45 237 if(cmd == ON) {
hudakz 6:b38a3b476a45 238 sw = ON; // turn the switch on
hudakz 0:68a0003c4cb8 239 }
hudakz 0:68a0003c4cb8 240
hudakz 6:b38a3b476a45 241 if(cmd == OFF) {
hudakz 6:b38a3b476a45 242 sw = OFF; // turn the switch off
hudakz 0:68a0003c4cb8 243 }
hudakz 0:68a0003c4cb8 244
hudakz 0:68a0003c4cb8 245 httpHeader = HTTP_OK;
hudakz 6:b38a3b476a45 246 sendHTTP(client, httpHeader, showWebPage(sw));
hudakz 0:68a0003c4cb8 247 }
hudakz 0:68a0003c4cb8 248 }
hudakz 0:68a0003c4cb8 249 }
hudakz 0:68a0003c4cb8 250 }