Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: UIPEthernet_GSOE
Diff: main.cpp
- Revision:
- 10:b47c7921346f
- Parent:
- 5:0ab8292e37da
- Child:
- 11:6c0b20227ca2
--- a/main.cpp Mon Mar 16 09:43:13 2015 +0000
+++ b/main.cpp Tue Aug 27 15:03:19 2019 +0000
@@ -1,100 +1,69 @@
-/*
- * In this project LED1 on the mbed board is switched on/off using a web browser.
- * However, you can easily modify the project to remotely switch on/off any external device.
- * The HTTP server is built from an mbed board and an ENC28J60 board.
- * ENC28J60 is driven by the UIPEthernet library <https://github.com/ntruchsess/arduino_uip>.
- * The example is based on the Tuxgraphics Web Switch <http://www.tuxgraphics.org/>.
- */
-#include <mbed.h>
-#include <UIPEthernet.h>
-#include <UIPServer.h>
-#include <UIPClient.h>
+#include "mbed.h"
#include <string>
-
-using namespace std;
+#include "UipEthernet.h"
+#include "TcpServer.h"
+#include "TcpClient.h"
-// UIPEthernet is the name of a global instance of UIPEthernetClass.
-// Do not change the name! It is used within the UIPEthernet library.
-#if defined(TARGET_LPC1768)
-UIPEthernetClass UIPEthernet(p11, p12, p13, p8); // mosi, miso, sck, cs
-#elif defined(TARGET_LPC1114)
-UIPEthernetClass UIPEthernet(dp2, dp1, dp6, dp25); // mosi, miso, sck, cs
-#elif defined(TARGET_LPC11U68)
-UIPEthernetClass UIPEthernet(P0_9, P0_8, P1_29, P0_2); // mosi, miso, sck, cs
-#elif defined(TARGET_NUCLEO_F103RB)
-UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs
-#elif defined(TARGET_NUCLEO_F401RE)
-UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs
-#elif defined(TARGET_NUCLEO_F411RE)
-UIPEthernetClass UIPEthernet(PB_5, PB_4, PB_3, PB_6); // mosi, miso, sck, cs
+using namespace std;
-// If your board/plaform is not present yet then uncomment
-// the following two lines and replace TARGET_YOUR_BOARD as appropriate.
-
-//#elif defined(TARGET_YOUR_BOARD)
-//UIPEthernetClass UIPEthernet(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS); // mosi, miso, sck, cs
-
-#endif
+// To be used when static IP is needed
+#define IP "192.168.1.35"
+#define GATEWAY "192.168.1.1"
+#define NETMASK "255.255.255.0"
+#define PORT 80
-// Note:
-// If it happends that any of the SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS pins collide with LED1 pin
-// then either use different SPI port (if available on the board) and change the pin names
-// in the constructor UIPEthernet(...) accordingly 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 220 Ohm resitor that is connected to the groud.
-// In the second case remember to replace LED1 in sw(LED1) constructor (see below).
-// MAC number must be unique within the connected network. Modify as appropriate.
-const uint8_t MY_MAC[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 };
-
-// IP address must be also unique and compatible with your network. Change as appropriate.
-const IPAddress MY_IP(192, 168, 1, 181);
-const uint16_t MY_PORT = 80; // for HTTP connection
-EthernetServer myServer = EthernetServer(MY_PORT);
-
-// In this example we are turning on/off LED1.
-DigitalOut sw(LED1); // Change LED1 to a pin of your choice.
+// The ENC28J60 chip doesn't have a built-in MAC address.
+// It's up to us to provide one which is unique within the connected network.
+// So modify the one below accordingly.
+const uint8_t MAC[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
+UipEthernet net(MAC, D11, D12, D13, D10); // mosi, miso, sck, cs
+TcpServer server; // TCP server running on this mbed device
+TcpClient* client; // TCP client communicating with a HTTP Browser running on a PC or Mobile device
+const int OFF = 0;
+const int ON = 1;
+DigitalOut output(D3); // A digital output to be switched on/off
+float roomTemp = 21.8; // A dummy temperature sensor output
+const string PASSWORD = "secret"; // Change as you like
+string httpHeader; // HTTP header
+string httpContent; // HTTP content
-// However, make sure that it does not collide with any of the SPI pins
-// already used in the UIPEthernet(...) constructor above!
-const string PASSWORD = "secret"; // change as you like
-const string HTTP_OK = "HTTP/1.0 200 OK";
-const string MOVED_PERM = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
-const string UNAUTHORIZED = "HTTP/1.0 401 Unauthorized";
-string httpHeader; // HTTP header
-string httpContent; // HTTP content
+/**
+ * @brief Analyses the received URL
+ * @note The string passed to this function will look like this:
+ * GET /HTTP/1.....
+ * GET /password HTTP/1.....
+ * GET /password/ HTTP/1.....
+ * GET /password/?sw=1 HTTP/1.....
+ * GET /password/?sw=0 HTTP/1.....
+ * @param url URL string
+ * @retval -3 just refresh page
+ * -2 no command given but password valid
+ * -1 invalid password
+ * 0 switch off
+ * 1 switch on
+ */
+int8_t analyseURL(string& url)
+{
+ if (url.length() < 5 + PASSWORD.size() + 1)
+ return(-1);
-// analyse the url given
-// return values: -1 invalid password
-// -2 no command given but password valid
-// -3 just refresh page
-// 0 switch off
-// 1 switch on
-//
-// The string passed to this function will look like this:
-// GET /password HTTP/1.....
-// GET /password/ HTTP/1.....
-// GET /password/?sw=1 HTTP/1.....
-// GET /password/?sw=0 HTTP/1.....
-int8_t analyse_get_url(string& str) {
- if(str.substr(5, PASSWORD.size()) != PASSWORD)
+ if (url.substr(5, PASSWORD.size()) != PASSWORD)
return(-1);
uint8_t pos = 5 + PASSWORD.size();
- if(str.substr(pos, 1) == " ")
- return(-2);
-
- if(str.substr(pos, 1) != "/")
+ if (url.substr(pos, 1) != "/")
return(-1);
- pos++;
+ if (url.substr(pos++, 1) == " ")
+ return(-2);
- string cmd(str.substr(pos, 5));
+ string cmd(url.substr(pos, 5));
- if(cmd == "?sw=0")
+ if (cmd == "?sw=0")
return(0);
- if(cmd == "?sw=1")
+ if (cmd == "?sw=1")
return(1);
return(-3);
@@ -106,8 +75,9 @@
* @param
* @retval
*/
-string& moved_perm(uint8_t flag) {
- if(flag == 1)
+string& movedPermanently(uint8_t flag)
+{
+ if (flag == 1)
httpContent = "/" + PASSWORD + "/";
else
httpContent = "";
@@ -123,43 +93,92 @@
* @param
* @retval
*/
-string& view(uint8_t status) {
- httpContent = "<h2>Web Switch</h2>\r\n";
+string& showWebPage(int status)
+{
+ char roomTempStr[5];
+
+ //roomTemp = ds1820.read();
+ sprintf(roomTempStr, "%3.1f", roomTemp);
- if(status == 1) {
- httpContent += "<pre>\r\n <font color=#FF0000>ON</font>";
- httpContent += " <a href=\"./?sw=0\">[switch off]</a>\r\n";
+ /*$off*/
+ httpContent =
+ "<head>"
+ "<meta charset=\"utf-8\">"
+ "<meta name=\"viewport\" content=\" initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=0;\"/>"
+ "<title>Smart Home</title>"
+ "<link href='http://fonts.googleapis.com/css?family=Droid+Sans&v1' rel='stylesheet' type='text/css'>"
+ "<style>"
+ ".switch {"
+ "position: relative;"
+ "display: inline-block;"
+ "width: 60px;"
+ "height: 34px;"
+ "}"
+ ".switch input {display:none;}"
+ ".slider {"
+ "position: absolute;"
+ "cursor: pointer;"
+ "top: 0;"
+ "left: 0;"
+ "right: 0;"
+ "bottom: 0;"
+ "border-radius: 34px;"
+ "background-color: #ccc;"
+ "-webkit-transition: .4s;"
+ "transition: .4s;"
+ "}"
+ ".slider:before {"
+ "position: absolute;"
+ "content: \"\";"
+ "height: 26px;"
+ "width: 26px;"
+ "left: 4px;"
+ "bottom: 4px;"
+ "border-radius: 50%;"
+ "background-color: white;"
+ "-webkit-transition: .4s;"
+ "transition: .4s;"
+ "}"
+ "input:checked + .slider {"
+ "background-color: #8ce196;"
+ "}"
+ "input:focus + .slider {"
+ "box-shadow: 0 0 1px #8ce196;"
+ "}"
+ "input:checked + .slider:before {"
+ "-webkit-transform: translateX(26px);"
+ "-ms-transform: translateX(26px);"
+ "transform: translateX(26px);"
+ "}"
+ "</style>"
+ "</head>"
+
+ "<body>"
+ "<h2><a href=\".\" title=\"Click to refresh the page\">Smart Home</a></h2>"
+ "<pre>Temperature:\t" + string(roomTempStr) + "°C</pre>"
+ "<pre>Heating:\t";
+
+ if(status == ON) {
+ httpContent +=
+ "<a href=\"./?sw=0\" class=\"switch\"> "
+ "<input type=\"checkbox\" checked>";
}
else {
- httpContent += "<pre>\r\n <font color=#00FF00>OFF</font>";
- httpContent += " <a href=\"./?sw=1\">[switch on]</a>\r\n";
+ httpContent +=
+ "<a href=\"./?sw=1\" class=\"switch\"> "
+ "<input type=\"checkbox\">";
}
- httpContent += " <a href=\".\">[refresh status]</a>\r\n";
- httpContent += "</pre>\r\n";
- httpContent += "<hr>\r\n";
- return httpContent;
-}
+ httpContent +=
+ "<div class=\"slider\"></div>"
+ "</a>"
+ "</pre>"
+ "<hr>"
+ "<pre>2017 ARMmbed</pre>"
+ "</body>";
-/**
- * @brief
- * @note
- * @param
- * @retval
- */
-void http_send(EthernetClient& client, string& header, string& content) {
- char content_length[5] = { };
-
- header += "\r\nContent-Type: text/html\r\n";
- header += "Content-Length: ";
- sprintf(content_length, "%d", content.length());
- header += string(content_length) + "\r\n";
- header += "Pragma: no-cache\r\n";
- header += "Connection: About to close\r\n";
- header += "\r\n";
-
- string webpage = header + content;
- client.write((uint8_t*)webpage.c_str(), webpage.length());
+ return httpContent;
+ /*$on*/
}
/**
@@ -168,60 +187,124 @@
* @param
* @retval
*/
-int main(void) {
- UIPEthernet.begin(MY_MAC, MY_IP);
- myServer.begin();
- while(1) {
- EthernetClient client = myServer.available();
- if(client) {
- size_t size = client.available();
- if(size > 0) {
+void sendHTTP(TcpClient& client, string& header, string& content)
+{
+ /*$off*/
+ char content_length[5] = { };
+
+ header +=
+ "\r\nContent-Type: text/html\r\n"
+ "Content-Length: ";
+ sprintf(content_length, "%d", content.length());
+ header +=
+ string(content_length) + "\r\n"
+ "Pragma: no-cache\r\n"
+ "Connection: About to close\r\n\r\n";
+
+ string webpage = header + content;
+ client.write((uint8_t*)webpage.c_str(), webpage.length());
+ /*$on*/
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int main(void)
+{
+ printf("Starting ...\r\n");
+
+ // IP address must be unique and compatible with your network.
+ //net->set_network(IP, NETMASK, GATEWAY); // include this for using static IP address
+ net.connect();
+
+ // Show the network address
+ const char* ip = net.get_ip_address();
+ const char* netmask = net.get_netmask();
+ const char* gateway = net.get_gateway();
+
+ printf("IP address: %s\r\n", ip ? ip : "None");
+ printf("Netmask: %s\r\n", netmask ? netmask : "None");
+ printf("Gateway: %s\r\n\r\n", gateway ? gateway : "None");
+ printf("------------------------------------------------------\r\n");
+ printf("Usage: Type %s/%s/ into your web browser and hit ENTER\r\n\r\n", net.get_ip_address(), PASSWORD.c_str());
+ printf("------------------------------------------------------\r\n");
+
+ /* Open the server on ethernet stack */
+ server.open(&net);
+
+ /* Bind the HTTP port (TCP 80) to the server */
+ server.bind(PORT);
+
+ /* Can handle 5 simultaneous connections */
+ server.listen(5);
+
+ while (1) {
+ client = server.accept();
+
+ if (client) {
+ size_t size = client->available();
+
+ if (size > 0) {
uint8_t* buf = (uint8_t*)malloc(size);
- size = client.read(buf, size);
+ size = client->read(buf, size);
+
string received((char*)buf);
free(buf);
-
- if(received.substr(0, 3) != "GET") {
- httpHeader = HTTP_OK;
+
+ if (received.substr(0, 3) != "GET") {
+ httpHeader = "HTTP/1.0 200 OK";
httpContent = "<h1>200 OK</h1>";
- http_send(client, httpHeader, httpContent);
- continue;
- }
-
- if(received.substr(0, 6) == "GET / ") {
- httpHeader = HTTP_OK;
- httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n";
- http_send(client, httpHeader, httpContent);
+ sendHTTP(*client, httpHeader, httpContent);
+ client->close();
continue;
}
- int cmd = analyse_get_url(received);
-
- if(cmd == -2) {
- // redirect to the right base url
- httpHeader = MOVED_PERM;
- http_send(client, httpHeader, moved_perm(1));
+ if (received.substr(0, 6) == "GET / ") {
+ httpHeader = "HTTP/1.0 200 OK";
+ httpContent = "<p>Usage: http://host_or_ip/password</p>\r\n";
+ sendHTTP(*client, httpHeader, httpContent);
+ client->close();
continue;
}
- if(cmd == -1) {
- httpHeader = UNAUTHORIZED;
- httpContent = "<h1>401 Unauthorized</h1>";
- http_send(client, httpHeader, httpContent);
- continue;
- }
+ int cmd = analyseURL(received);
+
+ switch (cmd) {
+ case -3:
+ // update webpage
+ httpHeader = "HTTP/1.0 200 OK";
+ sendHTTP(*client, httpHeader, showWebPage(output));
+ break;
+
+ case -2:
+ // redirect to the right base url
+ httpHeader = "HTTP/1.0 301 Moved Permanently\r\nLocation: ";
+ sendHTTP(*client, httpHeader, movedPermanently(1));
+ break;
- if(cmd == 1) {
- sw = 1; // switch on
- }
+ case -1:
+ httpHeader = "HTTP/1.0 401 Unauthorized";
+ httpContent = "<h1>401 Unauthorized</h1>";
+ sendHTTP(*client, httpHeader, httpContent);
+ break;
- if(cmd == 0) {
- sw = 0; // switch off
- }
+ case 0:
+ output = OFF; // output off
+ httpHeader = "HTTP/1.0 200 OK";
+ sendHTTP(*client, httpHeader, showWebPage(output));
+ break;
- httpHeader = HTTP_OK;
- http_send(client, httpHeader, view(sw));
+ case 1:
+ output = ON; // output on
+ httpHeader = "HTTP/1.0 200 OK";
+ sendHTTP(*client, httpHeader, showWebPage(output));
+ break;
+ }
}
+ client->close();
}
}
}