# Advanced Wi-Fi Usage This wiki introduces some of the advanced library usage of the Wi-Fi such as **HTTPClient, DNSServer and WebServer** Libraries. With these libraries implemented, you are able to develop your IoT projects with simple APIs. Please make sure you have followed the [**Network Overview**](https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview/) to update the **latest firmware and dependent libraries**.
!!!Note Make sure that **the RTL8720 firmware version is >= v2.0.2** ## HTTPClient Usage HTTPClient is used to make **HTTP GET, POST and PUT** requests to a web server very easy. Here are some examples for you to get started! ### HTTP GET Example This is an example of using HTTPClient for a simple HTTP connection and prints response back to the Serial Monitor.
- Change the `yourNetwork` and `yourPassword` to your WiFi **ssid** and **password**. - Upload the code to Wio Terminal. ```cpp #include #include const char* ssid = "yourNetwork"; const char* password = "yourPassword"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { //Check for the connection delay(500); Serial.println("Connecting.."); } Serial.print("Connected to the WiFi network with IP: "); Serial.println(WiFi.localIP()); } void loop() { // wait for WiFi connection if((WiFi.status() == WL_CONNECTED)) { HTTPClient http; Serial.print("[HTTP] begin...\n"); // configure traged server and url http.begin("http://www.example.com/index.html"); //HTTP Serial.print("[HTTP] GET...\n"); // start connection and send HTTP header int httpCode = http.GET(); // httpCode will be negative on error if(httpCode > 0) { // HTTP header has been send and Server response header has been handled Serial.printf("[HTTP] GET... code: %d\n", httpCode); // file found at server if(httpCode == HTTP_CODE_OK) { String payload = http.getString(); Serial.println(payload); } } else { Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } http.end(); } delay(5000); } ``` ### HTTPs GET Example This is the **HTTPs connection** using HTTPClient library. You may refer this to send HTTPs GET request to websites that you want to visit! !!!Note You can find out website's root CA following [**this**](https://wiki.seeedstudio.com/Wio-Terminal-Wi-Fi/#obtaining-websites-root-ca).
- Change the `yourNetwork` and `yourPassword` to your WiFi **ssid** and **password**. - Upload the code to Wio Terminal. ```cpp #include #include #include const char* ssid = "yourNetwork"; const char* password = "yourPassword"; const char* test_root_ca = \ "-----BEGIN CERTIFICATE-----\n" "MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMSAw\n" "HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs\n" "U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEy\n" "MTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3Qg\n" "U2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwggEiMA0GCSqGSIb3DQEBAQUA\n" "A4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnv\n" "UA0Qk28FgICfKqC9EksC4T2fWBYk/jCfC3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRr\n" "mBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++Ac\n" "xGNhr59qM/9il71I2dN8FGfcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmK\n" "FsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7X\n" "rJfoucBZEqFJJSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNV\n" "HQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1Ud\n" "EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8G\n" "A1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEBBCkwJzAl\n" "BggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzAp\n" "MCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYDVR0g\n" "BDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9y\n" "ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAGoA+Nnn78y6pRjd9XlQWNa7H\n" "TgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoN\n" "FvhsO9tvBCOIazpswWC9aJ9xju4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrz\n" "mqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wW\n" "IRdAvKLWZu/axBVbzYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZ\n" "USpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg==\n" "-----END CERTIFICATE-----\n"; WiFiClientSecure client; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { //Check for the connection delay(500); Serial.println("Connecting.."); } Serial.print("Connected to the WiFi network with IP: "); Serial.println(WiFi.localIP()); client.setCACert(test_root_ca); } void loop() { if(&client) { { // Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is HTTPClient https; Serial.print("[HTTPS] begin...\n"); if (https.begin(client, "https://www.google.com/index.html")) { // HTTPS Serial.print("[HTTPS] GET...\n"); // start connection and send HTTP header int httpCode = https.GET(); // httpCode will be negative on error if (httpCode > 0) { // HTTP header has been send and Server response header has been handled Serial.printf("[HTTPS] GET... code: %d\n", httpCode); // file found at server if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { String payload = https.getString(); Serial.println(payload); } } else { Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str()); } https.end(); } else { Serial.printf("[HTTPS] Unable to connect\n"); } // End extra scoping block } } else { Serial.println("Unable to create client"); } Serial.println(); Serial.println("Waiting 10s before the next round..."); delay(10000); } ``` ### HTTP POST Example This is an example of sending **HTTP POST request** using the HTTPClient from Wio Terminal to a Web Server. For this demonstration, we are using python to set up a simple web server on our PC that can receive and response to HTTP requests.
#### Python Server Code First, we need to use `pip` to install the needed **bottle library** in Python. Run the following in terminal to install bottle: ```sh pip install bottle ``` Once imported the bottle, copy the following code and save as **`simple-server.py`**. You may also change the port to something else you prefer but make this matches with the Arduino side. ```py from bottle import run, request, post @post('/') def index(): data = request.body.read() print(data) run(host='0.0.0.0', port=1880, debug=True) ``` #### Arduino Code - Change the `yourNetwork` and `yourPassword` to your WiFi **ssid** and **password**. - Upload the code to Wio Terminal. - Check the Terminal and you can see the incoming HTTP request message from Wio Terminal. ```cpp #include #include const char* ssid = "yourNetwork"; const char* password = "yourPassword"; // Change the following IP to your computer's IP running the server, make sure the Port also match const char* yourLocalIp = "http://10.0.0.233:1880/"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { //Check for the connection delay(500); Serial.println("Connecting.."); } Serial.print("Connected to the WiFi network with IP: "); Serial.println(WiFi.localIP()); } void loop() { if(WiFi.status()== WL_CONNECTED){ //Check WiFi connection status HTTPClient http; http.begin(yourLocalIp); //Specify destination for HTTP request http.addHeader("Content-Type", "text/plain"); //Specify content-type header int httpResponseCode = http.POST("Hello Bottle, from Wio Terminal"); //Send the actual POST request if(httpResponseCode>0){ Serial.print("HTTP Response Code: "); Serial.println(httpResponseCode); //Print return code }else{ Serial.print("Error on sending request: "); Serial.println(httpResponseCode); } http.end(); //Free resources }else{ Serial.println("Error in WiFi connection"); } delay(5000); //Send a request every 5 seconds } ``` ## WebServer Usage With the help of **WebServer library**, you can set up Web Server running on the Wio Terminal. By accessing the server with a browser running on any computer connected to the same network as the Wio Terminal, you can **control hardware from the webpage, read value of a sensor** and much more! ### Simple HelloServer Example This sets up a simple web server on the connected network using Wio Terminal.
- Change the `yourNetwork` and `yourPassword` to your WiFi **ssid** and **password**. - Upload the code to Wio Terminal. - Access the web server by entering Wio Terminal's IP from the same network using browser. ```cpp #include #include #include const char *ssid = "yourNetwork"; const char *password = "yourPassword"; WebServer server(80); const int led = 13; void handleRoot() { digitalWrite(led, 1); server.send(200, "text/plain", "hello from Wio Terminal!"); digitalWrite(led, 0); } void handleNotFound() { digitalWrite(led, 1); String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } server.send(404, "text/plain", message); digitalWrite(led, 0); } void setup(void) { pinMode(led, OUTPUT); digitalWrite(led, 0); Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); server.on("/", handleRoot); server.on("/inline", []() { server.send(200, "text/plain", "this works as well"); }); server.onNotFound(handleNotFound); server.begin(); Serial.println("HTTP server started"); } void loop(void) { server.handleClient(); } ``` ### HTTP Authentication Web Server Example This examples sets up a web server that requires Authentication process, which can be very useful in some cases for security purposes.
- Change the `yourNetwork` and `yourPassword` to your WiFi **ssid** and **password**. - Upload the code to Wio Terminal. - Access the web server by entering Wio Terminal's IP from the same network using browser, and enter pre-set username and password. ```cpp #include #include const char *ssid = "yourNetwork"; const char *password = "yourPassword"; WebServer server(80); const char* www_username = "admin"; const char* www_password = "password"; void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); if (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("WiFi Connect Failed! Rebooting..."); delay(1000); NVIC_SystemReset(); // Reset Wio Terminal } server.on("/", []() { if (!server.authenticate(www_username, www_password)) { return server.requestAuthentication(); } server.send(200, "text/plain", "Login OK"); }); server.begin(); Serial.print("Open http://"); Serial.print(WiFi.localIP()); Serial.println("/ in your browser to see it working"); } void loop() { server.handleClient(); } ``` ## DNSServer Usage We talked about **WebServer**, that we use **IP address** to access it. But if you want to access it by typing in the domain name (such as `www.google.com`), then you need to use the **DNSServer**.
- Using DNSServer must be under **AP mode**. - Introduce the corresponding library `#include `. - Declare `DNSServer` objects. - Start the DNS server using the `start()` method. - Process requests from clients using the `processNextRequest()` method. - Upload the Code to Wio Terminal and Connect your PC to the `DNSServer example` Wi-Fi. - Type `www.wioterminal.com` and `www.wioterminal.com/p1`. ```cpp #include #include #include IPAddress local_IP(192, 168, 1, 1); IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); const byte DNS_PORT = 53; DNSServer dnsServer; WebServer webserver(80); void handleRoot() { webserver.send(200, "text/plain", "Root page accessed via domain name"); } void handleP1() { webserver.send(200, "text/plain", "Page 1 accessed via domain name"); } void setup() { WiFi.mode(WIFI_AP); WiFi.softAPConfig(local_IP, gateway, subnet); WiFi.softAP("DNSServer example"); webserver.on("/", handleRoot); webserver.on("/p1", handleP1); dnsServer.start(DNS_PORT, "www.wioterminal.com", local_IP); //Start the DNS service, example.com is the registered domain name. webserver.begin(); } void loop() { dnsServer.processNextRequest(); webserver.handleClient(); } ``` ## mDNS Usage **What is Multicast DNS(mDNS)?** The [multicast DNS (mDNS)](https://en.wikipedia.org/wiki/Multicast_DNS) protocol resolves hostnames to IP addresses within small networks that do not include a local name server. Multicast DNS is designed for small networks and is intended to increase their user-friendliness. The idea is that users can connect devices in secret LANs without any issues. ### Install the Seeed_Arduino_rpcmDNS 1. Visit the [**Seeed_Arduino_rpcmDNS**](https://github.com/Seeed-Studio/Seeed_Arduino_rpcmDNS) repositories and download the entire repo to your local drive. 2. Now, the Seeed_Arduino_rpcmDNS library can be installed to the Arduino IDE. Open the Arduino IDE, and click `sketch` -> `Include Library` -> `Add .ZIP Library`, and choose the `Seeed_Arduino_rpcmDNS` file that you've have just downloaded. ### mDNS Web Server Example This is an example that sets up a mDNS web server on the Wio Terminal so that other device connected in the same network can browse the webserver at a defined site.
- Change the `yourNetwork` and `yourPassword` to your WiFi **ssid** and **password**. - Upload the code to Wio Terminal. - Access the web server by entering http://WioTerminal.local/ from the same network using browser, and enter pre-set username and password. ```cpp #include #include #include const char* ssid = "yourNetwork"; const char* password = "yourPassword"; // TCP server at port 80 will respond to HTTP requests WiFiServer server(80); void setup(void) { Serial.begin(115200); while(!Serial){ ; } Serial.printf("Setup Start \r\n"); // Connect to WiFi network WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // Set up mDNS responder: // - first argument is the domain name, in this example // the fully-qualified domain name is "esp8266.local" // - second argument is the IP address to advertise // we send our IP address on the WiFi network if (!MDNS.begin("WioTerminal")) { Serial.println("Error setting up MDNS responder!"); while(1) { delay(1000); } } Serial.println("mDNS responder started"); // Start TCP (HTTP) server server.begin(); Serial.println("TCP server started"); // Add service to MDNS-SD MDNS.addService("http", "tcp", 80); Serial.printf("Setup Done \r\n"); } void loop(void) { // Check if a client has connected WiFiClient client = server.available(); if (!client) { return; } Serial.println(""); Serial.println("New client"); // Wait for data from client to become available while(client.connected() && !client.available()){ delay(1); } // Read the first line of HTTP request String req = client.readStringUntil('\r'); // First line of HTTP request looks like "GET /path HTTP/1.1" // Retrieve the "/path" part by finding the spaces int addr_start = req.indexOf(' '); int addr_end = req.indexOf(' ', addr_start + 1); if (addr_start == -1 || addr_end == -1) { Serial.print("Invalid request: "); Serial.println(req); return; } req = req.substring(addr_start + 1, addr_end); Serial.print("Request: "); Serial.println(req); String s; if (req == "/") { IPAddress ip = WiFi.localIP(); String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]); s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nHello from Wio Terminal at "; s += ipStr; s += "\r\n\r\n"; Serial.println("Sending 200"); } else { s = "HTTP/1.1 404 Not Found\r\n\r\n"; Serial.println("Sending 404"); } client.print(s); client.stop(); Serial.println("Done with client"); } ``` ### mDNS-SD Example This is a [mDNS-SD(Service Discovery)](https://en.wikipedia.org/wiki/Zero-configuration_networking#DNS-SD) example which allows you to discover services in the same network.
- Change the `yourNetwork` and `yourPassword` to your WiFi **ssid** and **password**. - Upload the code to Wio Terminal. ```cpp #include #include #include const char* ssid = "yourNetwork"; const char* password = "yourPassword"; // TCP server at port 80 will respond to HTTP requests WiFiServer server(80); void setup(void) { Serial.begin(115200); while(!Serial){ ; } Serial.printf("Setup Start \r\n"); // Connect to WiFi network WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // Set up mDNS responder: // - first argument is the domain name, in this example // the fully-qualified domain name is "esp8266.local" // - second argument is the IP address to advertise // we send our IP address on the WiFi network if (!MDNS.begin("WioTerminal")) { Serial.println("Error setting up MDNS responder!"); while(1) { delay(1000); } } Serial.println("mDNS responder started"); // Start TCP (HTTP) server server.begin(); Serial.println("TCP server started"); // Add service to MDNS-SD MDNS.addService("http", "tcp", 80); Serial.printf("Setup Done \r\n"); } void loop(void) { // Check if a client has connected WiFiClient client = server.available(); if (!client) { return; } Serial.println(""); Serial.println("New client"); // Wait for data from client to become available while(client.connected() && !client.available()){ delay(1); } // Read the first line of HTTP request String req = client.readStringUntil('\r'); // First line of HTTP request looks like "GET /path HTTP/1.1" // Retrieve the "/path" part by finding the spaces int addr_start = req.indexOf(' '); int addr_end = req.indexOf(' ', addr_start + 1); if (addr_start == -1 || addr_end == -1) { Serial.print("Invalid request: "); Serial.println(req); return; } req = req.substring(addr_start + 1, addr_end); Serial.print("Request: "); Serial.println(req); String s; if (req == "/") { IPAddress ip = WiFi.localIP(); String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]); s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\nHello from Wio Terminal at "; s += ipStr; s += "\r\n\r\n"; Serial.println("Sending 200"); } else { s = "HTTP/1.1 404 Not Found\r\n\r\n"; Serial.println("Sending 404"); } client.print(s); client.stop(); Serial.println("Done with client"); } ``` ## WiFiManager Usage We have ported the well known WiFi Manager to the Wio Terminal platform so that you may use your phone or other device to configure Wi-Fi settings for your Wio Terminal! ### Install the Seeed_Arduino_rpcWiFiManager 1. Visit the [**Seeed_Arduino_rpcWiFiManager**](https://github.com/Seeed-Studio/Seeed_Arduino_rpcWiFiManager) repositories and download the entire repo to your local drive. 2. Now, the Seeed_Arduino_rpcWiFiManager library can be installed to the Arduino IDE. Open the Arduino IDE, and click `sketch` -> `Include Library` -> `Add .ZIP Library`, and choose the `Seeed_Arduino_rpcWiFiManager` file that you've have just downloaded. ### WiFiManager Auto Connect Example
This example is the demonstration of the auto connect example. You can use the example to set the WiFi settings for Wio Terminal. - Upload the code to Wio Terminal. - If Wio Terminal have connected to WiFi before, it will auto-connect to the same network. If it cannot connect to any WiFi it will go into AP mode and emit a WiFi. Use your phone to connect to this WiFi and input the WiFi settings. ```cpp #include #include #include #include void setup() { Serial.begin(115200); while(!Serial); // wait till Serial is opened WiFiManager wifiManager; // Uncomment the resetSettings() will wipe out the saved settings //wifiManager.resetSettings(); //Fetches ssid and pass from RTL8720 and tries to connect //if it does not connect it starts an access point with the specified name //here "AutoConnectAP" //and goes into a blocking loop awaiting configuration wifiManager.autoConnect("AutoConnectAP"); //or use this for auto generated name ESP + ChipID //wifiManager.autoConnect(); //if you get here you have connected to the WiFi Serial.println("connected...yeey :)"); Serial.println(WiFi.localIP()); } void loop() { // put your main code here, to run repeatedly: } ```