A tiny webserver alowing to remotely turn on or turn off a digital output on an STM32F407VET6 board. For more details see https://os.mbed.com/users/hudakz/code/STM32F407VET6_Hello/

Dependencies:   EthernetInterface mbed-rtos 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/off by using a web browser.

/media/uploads/hudakz/webswitch_desktop.png/media/uploads/hudakz/webswitch_mobile01.jpg

Notice that DHCP is turned on by default. The IP address assigned to the WebSwitch server along with an instruction how to use it is printed to the connected PC's serial terminal window during program start up.

For more details on how to connect an Ethernet interface to a STM32F407VET6 board see https://os.mbed.com/users/hudakz/code/STM32F407VET6_Hello/.

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

Committer:
hudakz
Date:
Tue Apr 03 08:58:14 2018 +0000
Revision:
1:a583ba376cc7
Parent:
0:7764029ff97d
Updated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:7764029ff97d 1 // Blinky demo for the STM32F407VET6 boards.
hudakz 0:7764029ff97d 2 // See http://wiki.stm32duino.com/index.php?title=STM32F407.
hudakz 0:7764029ff97d 3 //
hudakz 0:7764029ff97d 4 // Use "Seed Arch Max" as target platform for the online compiler.
hudakz 0:7764029ff97d 5
hudakz 0:7764029ff97d 6 #include "mbed.h"
hudakz 0:7764029ff97d 7 #include "EthernetInterface.h"
hudakz 0:7764029ff97d 8 #include <stdio.h>
hudakz 0:7764029ff97d 9 #include <string>
hudakz 0:7764029ff97d 10
hudakz 0:7764029ff97d 11 using namespace std;
hudakz 0:7764029ff97d 12
hudakz 0:7764029ff97d 13 #define PORT 80
hudakz 0:7764029ff97d 14
hudakz 0:7764029ff97d 15 EthernetInterface ethernet;
hudakz 0:7764029ff97d 16
hudakz 0:7764029ff97d 17 TCPSocketServer server;
hudakz 0:7764029ff97d 18 bool serverIsListening = false;
hudakz 0:7764029ff97d 19
hudakz 0:7764029ff97d 20 TCPSocketConnection client;
hudakz 0:7764029ff97d 21 bool clientIsConnected = false;
hudakz 0:7764029ff97d 22
hudakz 1:a583ba376cc7 23 const int OFF = 1;
hudakz 1:a583ba376cc7 24 const int ON = 0;
hudakz 0:7764029ff97d 25
hudakz 0:7764029ff97d 26 DigitalOut sw(PA_6);
hudakz 0:7764029ff97d 27 float roomTemp = 21.8; // A temperature sensor output
hudakz 0:7764029ff97d 28
hudakz 0:7764029ff97d 29 const string PASSWORD = "secret"; // change as you like
hudakz 0:7764029ff97d 30 const string HTTP_OK = "HTTP/1.0 200 OK";
hudakz 0:7764029ff97d 31 const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
hudakz 0:7764029ff97d 32 const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
hudakz 0:7764029ff97d 33 string httpHeader; // HTTP header
hudakz 0:7764029ff97d 34 string httpContent; // HTTP content
hudakz 0:7764029ff97d 35
hudakz 0:7764029ff97d 36 /**
hudakz 0:7764029ff97d 37 * @brief Defines a custom MAC address
hudakz 0:7764029ff97d 38 * @note Uncomment the code below to define a unique MAC address.
hudakz 0:7764029ff97d 39 * Modify the mac array items as needed.
hudakz 0:7764029ff97d 40 * @param
hudakz 0:7764029ff97d 41 * @retval
hudakz 0:7764029ff97d 42 */
hudakz 0:7764029ff97d 43 extern "C" void mbed_mac_address(char* mac) {
hudakz 0:7764029ff97d 44 mac[0] = 0x00;
hudakz 0:7764029ff97d 45 mac[1] = 0x01;
hudakz 0:7764029ff97d 46 mac[2] = 0x02;
hudakz 0:7764029ff97d 47 mac[3] = 0x03;
hudakz 0:7764029ff97d 48 mac[4] = 0x04;
hudakz 0:7764029ff97d 49 mac[5] = 0x05;
hudakz 0:7764029ff97d 50 };
hudakz 0:7764029ff97d 51
hudakz 0:7764029ff97d 52 /**
hudakz 0:7764029ff97d 53 * @brief Analyses the received URL
hudakz 0:7764029ff97d 54 * @note The string passed to this function will look like this:
hudakz 0:7764029ff97d 55 * GET /password HTTP/1.....
hudakz 0:7764029ff97d 56 * GET /password/ HTTP/1.....
hudakz 0:7764029ff97d 57 * GET /password/?sw=1 HTTP/1.....
hudakz 0:7764029ff97d 58 * GET /password/?sw=0 HTTP/1.....
hudakz 0:7764029ff97d 59 * @param url URL string
hudakz 0:7764029ff97d 60 * @retval -1 invalid password
hudakz 0:7764029ff97d 61 * -2 no command given but password valid
hudakz 0:7764029ff97d 62 * -3 just refresh page
hudakz 0:7764029ff97d 63 * 0 switch off
hudakz 0:7764029ff97d 64 * 1 switch on
hudakz 0:7764029ff97d 65 */
hudakz 0:7764029ff97d 66 int8_t analyseURL(string& url) {
hudakz 0:7764029ff97d 67 if(url.substr(5, PASSWORD.size()) != PASSWORD)
hudakz 0:7764029ff97d 68 return(-1);
hudakz 0:7764029ff97d 69
hudakz 0:7764029ff97d 70 uint8_t pos = 5 + PASSWORD.size();
hudakz 0:7764029ff97d 71
hudakz 0:7764029ff97d 72 if(url.substr(pos, 1) == " ")
hudakz 0:7764029ff97d 73 return(-2);
hudakz 0:7764029ff97d 74
hudakz 0:7764029ff97d 75 if(url.substr(pos++, 1) != "/")
hudakz 0:7764029ff97d 76 return(-1);
hudakz 0:7764029ff97d 77
hudakz 0:7764029ff97d 78 string cmd(url.substr(pos, 5));
hudakz 0:7764029ff97d 79
hudakz 0:7764029ff97d 80 if(cmd == "?sw=0")
hudakz 0:7764029ff97d 81 return(OFF);
hudakz 0:7764029ff97d 82
hudakz 0:7764029ff97d 83 if(cmd == "?sw=1")
hudakz 0:7764029ff97d 84 return(ON);
hudakz 0:7764029ff97d 85
hudakz 0:7764029ff97d 86 return(-3);
hudakz 0:7764029ff97d 87 }
hudakz 0:7764029ff97d 88
hudakz 0:7764029ff97d 89 /**
hudakz 0:7764029ff97d 90 * @brief
hudakz 0:7764029ff97d 91 * @note
hudakz 0:7764029ff97d 92 * @param
hudakz 0:7764029ff97d 93 * @retval
hudakz 0:7764029ff97d 94 */
hudakz 0:7764029ff97d 95 string& movedPermanently(uint8_t flag) {
hudakz 0:7764029ff97d 96 if(flag == 1)
hudakz 0:7764029ff97d 97 httpContent = "/" + PASSWORD + "/";
hudakz 0:7764029ff97d 98 else
hudakz 0:7764029ff97d 99 httpContent = "";
hudakz 0:7764029ff97d 100
hudakz 0:7764029ff97d 101 httpContent += "<h1>301 Moved Permanently</h1>\r\n";
hudakz 0:7764029ff97d 102
hudakz 0:7764029ff97d 103 return(httpContent);
hudakz 0:7764029ff97d 104 }
hudakz 0:7764029ff97d 105
hudakz 0:7764029ff97d 106 /**
hudakz 0:7764029ff97d 107 * @brief
hudakz 0:7764029ff97d 108 * @note
hudakz 0:7764029ff97d 109 * @param
hudakz 0:7764029ff97d 110 * @retval
hudakz 0:7764029ff97d 111 */
hudakz 0:7764029ff97d 112 string& showWebPage(uint8_t status) {
hudakz 0:7764029ff97d 113 char roomTempStr[5];
hudakz 0:7764029ff97d 114
hudakz 0:7764029ff97d 115 //roomTemp = ds1820.read();
hudakz 0:7764029ff97d 116 sprintf(roomTempStr, "%3.1f", roomTemp);
hudakz 0:7764029ff97d 117
hudakz 0:7764029ff97d 118 httpContent = "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>";
hudakz 0:7764029ff97d 119 httpContent += "<pre>Temperature:\t" + string(roomTempStr) + "&deg;C\r\n</pre>";
hudakz 0:7764029ff97d 120
hudakz 0:7764029ff97d 121 if(status == ON) {
hudakz 0:7764029ff97d 122 httpContent += "<pre>\r\nHeating:\t<font color=#FF0000>On </font>";
hudakz 0:7764029ff97d 123 httpContent += " <a href=\"./?sw=0\"><button>Turn off</button></a>\r\n";
hudakz 0:7764029ff97d 124 }
hudakz 0:7764029ff97d 125 else {
hudakz 0:7764029ff97d 126 httpContent += "<pre>\r\nHeating:\t<font color=#999999>Off</font>";
hudakz 0:7764029ff97d 127 httpContent += " <a href=\"./?sw=1\"><button>Turn on</button></a>\r\n";
hudakz 0:7764029ff97d 128 }
hudakz 0:7764029ff97d 129
hudakz 0:7764029ff97d 130 httpContent += "</pre>\r\n";
hudakz 0:7764029ff97d 131 httpContent += "<hr>\r\n";
hudakz 0:7764029ff97d 132 httpContent += "<pre>2017 armMBED</pre>";
hudakz 0:7764029ff97d 133 return httpContent;
hudakz 0:7764029ff97d 134 }
hudakz 0:7764029ff97d 135
hudakz 0:7764029ff97d 136 /**
hudakz 0:7764029ff97d 137 * @brief
hudakz 0:7764029ff97d 138 * @note
hudakz 0:7764029ff97d 139 * @param
hudakz 0:7764029ff97d 140 * @retval
hudakz 0:7764029ff97d 141 */
hudakz 0:7764029ff97d 142 void sendHTTP(TCPSocketConnection& client, string& header, string& content) {
hudakz 0:7764029ff97d 143 char contentLength[5] = { };
hudakz 0:7764029ff97d 144
hudakz 0:7764029ff97d 145 header += "\r\nContent-Type: text/html\r\n";
hudakz 0:7764029ff97d 146 header += "Content-Length: ";
hudakz 0:7764029ff97d 147 sprintf(contentLength, "%d", content.length());
hudakz 0:7764029ff97d 148 header += string(contentLength) + "\r\n";
hudakz 0:7764029ff97d 149 header += "Pragma: no-cache\r\n";
hudakz 0:7764029ff97d 150 header += "Connection: About to close\r\n";
hudakz 0:7764029ff97d 151 header += "\r\n";
hudakz 0:7764029ff97d 152
hudakz 0:7764029ff97d 153 string webpage = header + content;
hudakz 0:7764029ff97d 154 client.send((char*)webpage.c_str(), webpage.length());
hudakz 0:7764029ff97d 155 clientIsConnected = false;
hudakz 0:7764029ff97d 156 printf("HTTP sent.\n\r");
hudakz 0:7764029ff97d 157 }
hudakz 0:7764029ff97d 158
hudakz 0:7764029ff97d 159 /**
hudakz 0:7764029ff97d 160 * @brief
hudakz 0:7764029ff97d 161 * @note
hudakz 0:7764029ff97d 162 * @param
hudakz 0:7764029ff97d 163 * @retval
hudakz 0:7764029ff97d 164 */
hudakz 0:7764029ff97d 165 int main(void) {
hudakz 1:a583ba376cc7 166 sw = OFF;
hudakz 0:7764029ff97d 167 //setup ethernet interface
hudakz 0:7764029ff97d 168 ethernet.init(); //Use DHCP
hudakz 0:7764029ff97d 169 //ethernet.init("192.168.1.181", "255.255.255.0", "192.168.1.1"); // Use static IP
hudakz 0:7764029ff97d 170 ethernet.connect();
hudakz 0:7764029ff97d 171 printf("USAGE: Type '%s/%s/' into your web browser and hit ENTER\r\n", ethernet.getIPAddress(), PASSWORD.c_str());
hudakz 0:7764029ff97d 172 printf("NOTE: Don't forget to type the last '/'.\r\n\r\n");
hudakz 0:7764029ff97d 173
hudakz 0:7764029ff97d 174 //setup tcp socket
hudakz 0:7764029ff97d 175 if(server.bind(PORT) < 0) {
hudakz 0:7764029ff97d 176 printf("HTTP server bind failed.\n\r");
hudakz 0:7764029ff97d 177 return -1;
hudakz 0:7764029ff97d 178 }
hudakz 0:7764029ff97d 179 else {
hudakz 0:7764029ff97d 180 printf("HTTP server bind succeeded.\n\r");
hudakz 0:7764029ff97d 181 serverIsListening = true;
hudakz 0:7764029ff97d 182 }
hudakz 0:7764029ff97d 183
hudakz 0:7764029ff97d 184 if(server.listen(1) < 0) {
hudakz 0:7764029ff97d 185 printf("HTTP server listen failed.\n\r");
hudakz 0:7764029ff97d 186 return -1;
hudakz 0:7764029ff97d 187 }
hudakz 0:7764029ff97d 188 else {
hudakz 0:7764029ff97d 189 printf("HTTP server is listening...\n\r");
hudakz 0:7764029ff97d 190 }
hudakz 0:7764029ff97d 191
hudakz 0:7764029ff97d 192 //listening for http GET request
hudakz 0:7764029ff97d 193 while(serverIsListening) {
hudakz 0:7764029ff97d 194
hudakz 0:7764029ff97d 195 if(server.accept(client) < 0) {
hudakz 0:7764029ff97d 196 printf("Failed to accept connection.\n\r");
hudakz 0:7764029ff97d 197 }
hudakz 0:7764029ff97d 198 else {
hudakz 0:7764029ff97d 199 printf("\r\n=========================================\r\n");
hudakz 0:7764029ff97d 200 printf("Connection accepted!\n\rIP: %s\n\r", client.get_address());
hudakz 0:7764029ff97d 201 clientIsConnected = true;
hudakz 0:7764029ff97d 202
hudakz 0:7764029ff97d 203 while(clientIsConnected) {
hudakz 0:7764029ff97d 204 char buffer[1024] = { };
hudakz 0:7764029ff97d 205 switch(client.receive(buffer, 1023)) {
hudakz 0:7764029ff97d 206 case 0:
hudakz 0:7764029ff97d 207 printf("Recieved buffer is empty.\n\r");
hudakz 0:7764029ff97d 208 clientIsConnected = false;
hudakz 0:7764029ff97d 209 break;
hudakz 0:7764029ff97d 210
hudakz 0:7764029ff97d 211 case -1:
hudakz 0:7764029ff97d 212 printf("Failed to read data from client.\n\r");
hudakz 0:7764029ff97d 213 clientIsConnected = false;
hudakz 0:7764029ff97d 214 break;
hudakz 0:7764029ff97d 215
hudakz 0:7764029ff97d 216 default:
hudakz 0:7764029ff97d 217 printf("Recieved Data: %d\n\r\n\r%.*s\n\r", strlen(buffer), strlen(buffer), buffer);
hudakz 0:7764029ff97d 218
hudakz 0:7764029ff97d 219 string received(buffer);
hudakz 0:7764029ff97d 220 if(received.substr(0, 3) != "GET") {
hudakz 0:7764029ff97d 221 httpHeader = HTTP_OK;
hudakz 0:7764029ff97d 222 httpContent = "<h1>200 OK</h1>";
hudakz 0:7764029ff97d 223 sendHTTP(client, httpHeader, httpContent);
hudakz 0:7764029ff97d 224 continue;
hudakz 0:7764029ff97d 225 }
hudakz 0:7764029ff97d 226
hudakz 0:7764029ff97d 227 if(received.substr(0, 6) == "GET / ") {
hudakz 0:7764029ff97d 228 httpHeader = HTTP_OK;
hudakz 0:7764029ff97d 229 httpContent = "<p>USAGE: Type 'http://ip_address/password/' into your web browser and hit ENTER</p>\r\n";
hudakz 0:7764029ff97d 230 sendHTTP(client, httpHeader, httpContent);
hudakz 0:7764029ff97d 231 continue;
hudakz 0:7764029ff97d 232 }
hudakz 0:7764029ff97d 233
hudakz 0:7764029ff97d 234 int cmd = analyseURL(received);
hudakz 0:7764029ff97d 235
hudakz 0:7764029ff97d 236 if(cmd == -2) {
hudakz 0:7764029ff97d 237
hudakz 0:7764029ff97d 238 // redirect to the correct base URL
hudakz 0:7764029ff97d 239 httpHeader = MOVED_PERM;
hudakz 0:7764029ff97d 240 sendHTTP(client, httpHeader, movedPermanently(1));
hudakz 0:7764029ff97d 241 continue;
hudakz 0:7764029ff97d 242 }
hudakz 0:7764029ff97d 243
hudakz 0:7764029ff97d 244 if(cmd == -1) {
hudakz 0:7764029ff97d 245 httpHeader = UNAUTHORIZED;
hudakz 0:7764029ff97d 246 httpContent = "<h1>401 Unauthorized</h1>";
hudakz 0:7764029ff97d 247 sendHTTP(client, httpHeader, httpContent);
hudakz 0:7764029ff97d 248 continue;
hudakz 0:7764029ff97d 249 }
hudakz 0:7764029ff97d 250
hudakz 0:7764029ff97d 251 if(cmd == ON) {
hudakz 0:7764029ff97d 252 sw = ON; // turn the switch on
hudakz 0:7764029ff97d 253 }
hudakz 0:7764029ff97d 254
hudakz 0:7764029ff97d 255 if(cmd == OFF) {
hudakz 0:7764029ff97d 256 sw = OFF; // turn the switch off
hudakz 0:7764029ff97d 257 }
hudakz 0:7764029ff97d 258
hudakz 0:7764029ff97d 259 httpHeader = HTTP_OK;
hudakz 0:7764029ff97d 260 sendHTTP(client, httpHeader, showWebPage(sw));
hudakz 0:7764029ff97d 261 break;
hudakz 0:7764029ff97d 262 }
hudakz 0:7764029ff97d 263 }
hudakz 0:7764029ff97d 264
hudakz 0:7764029ff97d 265 printf("Closing connection.\n\r");
hudakz 0:7764029ff97d 266 printf("HTTP server is listening...\n\r");
hudakz 0:7764029ff97d 267 client.close();
hudakz 0:7764029ff97d 268 }
hudakz 0:7764029ff97d 269 }
hudakz 0:7764029ff97d 270 }