使用WiFi(3)
- Wi-F的高級使用
- HTTPClient 的使用
- HTTP GET
- HTTPs GET
- HTTP POST
- WebServer
- HTTP Authentication Web Server
- DNSServer
- mDNS
- mDNS-SD
- WiFiManager
Wi-F的高級使用
本節介紹了一些WiFi的高級庫用法,如HTTPClient、DNSServer和WebServer庫。通過實現這些庫,您可以使用簡單的API開發物聯網項目。
請確保您已更新了最新的固件和依賴庫。
HTTPClient 的使用
HTTPClient用于使對web服務器的HTTPGET、POST和PUT請求變得非常容易。這里有一些例子供您入門!
HTTP GET
這是一個使用HTTPClient進行簡單HTTP連接并將響應打印回串行監視器的示例。
- 將yourNetwork和yourPassword更改為你的WiFi ssid和密碼。
- 將代碼上傳到Wio Terminal。
#include <rpcWiFi.h>
#include <HTTPClient.h>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 connectiondelay(500);Serial.println("Connecting..");}Serial.print("Connected to the WiFi network with IP: ");Serial.println(WiFi.localIP());
}void loop() {// wait for WiFi connectionif((WiFi.status() == WL_CONNECTED)) {HTTPClient http;Serial.print("[HTTP] begin...\n");// configure traged server and urlhttp.begin("http://www.example.com/index.html"); //HTTPSerial.print("[HTTP] GET...\n");// start connection and send HTTP headerint httpCode = http.GET();// httpCode will be negative on errorif(httpCode > 0) {// HTTP header has been send and Server response header has been handledSerial.printf("[HTTP] GET... code: %d\n", httpCode);// file found at serverif(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
這是使用HTTPClient庫的HTTPs連接。您可以參考此向您想要訪問的網站發送HTTPs GET請求!
您可以按照此鏈接查找網站的根CA。
- 將yourNetwork和yourPassword更改為你的WiFi ssid和密碼。
- 將代碼上傳到Wio Terminal。
#include <rpcWiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>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 connectiondelay(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")) { // HTTPSSerial.print("[HTTPS] GET...\n");// start connection and send HTTP headerint httpCode = https.GET();// httpCode will be negative on errorif (httpCode > 0) {// HTTP header has been send and Server response header has been handledSerial.printf("[HTTPS] GET... code: %d\n", httpCode);// file found at serverif (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
這是一個使用Wio Terminal的HTTPClient向Web服務器發送HTTP POST請求的示例。在此演示中,我們使用python在個人電腦上設置一個簡單的web服務器,該服務器可以接收并響應HTTP請求。
Python服務器端代碼
首先,我們需要在Python中使用pip安裝所需的bottle庫。在終端中運行以下命令以安裝bottle:
pip install bottle
導入bottle后,復制以下代碼并將其保存為simple-server.py。你也可以將端口更改為你喜歡的其他端口,但要確保它與Arduino端匹配。
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代碼
- 將yourNetwork和yourPassword更改為你的WiFi ssid和密碼。
- 將代碼上傳到Wio Terminal。
- 檢查終端,你可以看到來自Wio Terminal的傳入HTTP請求消息。
#include <rpcWiFi.h>
#include <HTTPClient.h>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 connectiondelay(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 statusHTTPClient http;http.begin(yourLocalIp); //Specify destination for HTTP requesthttp.addHeader("Content-Type", "text/plain"); //Specify content-type headerint httpResponseCode = http.POST("Hello Bottle, from Wio Terminal"); //Send the actual POST requestif(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
在WebServer庫的幫助下,你可以在Wio Terminal上設置并運行Web服務器。通過在與Wio Terminal連接到同一網絡的任何計算機上運行的瀏覽器訪問服務器,你可以從網頁上控制硬件,讀取傳感器的值等等!
簡單 HelloServer 示例
這將在連接的網絡上使用Wio Terminal設置一個簡單的Web服務器。
- 將yourNetwork和yourPassword更改為您的WiFi ssid和密碼。
- 將代碼上傳到Wio Terminal。
- 使用瀏覽器從同一網絡輸入Wio Terminal的IP地址來訪問web服務器。
#include <rpcWiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>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 connectionwhile (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
這個示例設置了一個需要身份驗證過程的Web服務器,這在某些情況下出于安全考慮可能非常有用。
- 將yourNetwork和yourPassword更改為您的WiFi ssid和密碼。
- 將代碼上傳到Wio Terminal。
- 使用瀏覽器從同一網絡輸入Wio Terminal的IP地址來訪問Web服務器,并輸入預設的用戶名和密碼。
#include <rpcWiFi.h>
#include <WebServer.h>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
我們討論了WebServer,我們使用IP地址來訪問它。 但是,如果您想通過鍵入域名(例如www.google.com)來訪問它,則需要使用DNSServer。
- 使用DNSServer必須在AP模式下。
- 引入相應的庫#include <DNSServer.h>。
- 聲明DNSServer對象。
- 使用start()方法啟動DNS服務器。
- 使用processNextRequest()方法處理來自客戶端的請求。
- 將代碼上傳到Wio Terminal,并將您的PC連接到DNSServer示例Wi-Fi。
- 輸入www.wioterminal.com和www.wioterminal.com/p1。
#include <rpcWiFi.h>
#include <DNSServer.h>
#include <WebServer.h>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
什么是Multicast DNS(mDNS)?
Multicast DNS(mDNS)協議在沒有本地名稱服務器的小型網絡中將主機名解析為IP地址。Multicast DNS專為小型網絡設計,旨在提高其用戶友好性。其想法是,用戶可以在秘密的局域網中連接設備而不會出現任何問題。
Install the Seeed_Arduino_rpcmDNS
下載Seeed_Arduino_rpcmDNS,并安裝到Arduino
mDNS Web Server示例
這是一個在Wio Terminal上設置mDNS Web服務器的示例,以便在同一網絡中連接的其他設備可以在定義的站點上瀏覽該Web服務器。
- 將yourNetwork和yourPassword更改為你的WiFi ssid和密碼。
- 將代碼上傳到Wio Terminal。
- 使用瀏覽器從同一網絡輸入http://WioTerminal.local/來訪問Web服務器,并輸入預設的用戶名和密碼。
#include <rpcWiFi.h>
#include <RPCmDNS.h>
#include <WiFiClient.h>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 networkWiFi.begin(ssid, password);Serial.println("");// Wait for connectionwhile (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 networkif (!MDNS.begin("WioTerminal")) {Serial.println("Error setting up MDNS responder!");while(1) {delay(1000);}}Serial.println("mDNS responder started");// Start TCP (HTTP) serverserver.begin();Serial.println("TCP server started");// Add service to MDNS-SDMDNS.addService("http", "tcp", 80);Serial.printf("Setup Done \r\n");
}void loop(void)
{// Check if a client has connectedWiFiClient client = server.available();if (!client) {return;}Serial.println("");Serial.println("New client");// Wait for data from client to become availablewhile(client.connected() && !client.available()){delay(1);}// Read the first line of HTTP requestString req = client.readStringUntil('\r');// First line of HTTP request looks like "GET /path HTTP/1.1"// Retrieve the "/path" part by finding the spacesint 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<!DOCTYPE HTML>\r\n<html>Hello from Wio Terminal at ";s += ipStr;s += "</html>\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
這是一個mDNS-SD(服務發現)示例,允許您發現同一網絡中的服務。
關于基于DNS的服務發現:
- 將 yourNetwork 和 yourPassword 更改為您的 WiFi ssid 和密碼。
- 將代碼上傳到 Wio Terminal。
#include <rpcWiFi.h>
#include <RPCmDNS.h>
#include <WiFiClient.h>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 networkWiFi.begin(ssid, password);Serial.println("");// Wait for connectionwhile (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 networkif (!MDNS.begin("WioTerminal")) {Serial.println("Error setting up MDNS responder!");while(1) {delay(1000);}}Serial.println("mDNS responder started");// Start TCP (HTTP) serverserver.begin();Serial.println("TCP server started");// Add service to MDNS-SDMDNS.addService("http", "tcp", 80);Serial.printf("Setup Done \r\n");
}void loop(void)
{// Check if a client has connectedWiFiClient client = server.available();if (!client) {return;}Serial.println("");Serial.println("New client");// Wait for data from client to become availablewhile(client.connected() && !client.available()){delay(1);}// Read the first line of HTTP requestString req = client.readStringUntil('\r');// First line of HTTP request looks like "GET /path HTTP/1.1"// Retrieve the "/path" part by finding the spacesint 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<!DOCTYPE HTML>\r\n<html>Hello from Wio Terminal at ";s += ipStr;s += "</html>\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
我們已經將廣為人知的WiFi管理器移植到Wio Terminal平臺上,這樣您就可以使用手機或其他設備為Wio Terminal配置WiFi設置了!
Install the Seeed_Arduino_rpcWiFiManager
下載Seeed_Arduino_rpcWiFiManager
WiFiManager Auto Connect示例
這個示例是自動連接功能的演示。您可以使用此示例為Wio Terminal設置WiFi。
- 將代碼上傳到Wio Terminal。
- 如果Wio Terminal之前已經連接過WiFi,它將自動連接到同一網絡。如果它無法連接到任何WiFi,它將進入AP模式并發出WiFi信號。使用手機連接到此WiFi并輸入WiFi設置。
#include <rpcWiFi.h>
#include <DNSServer.h>
#include <WebServer.h>
#include <WiFiManager.h>void setup() {Serial.begin(115200);while(!Serial); // wait till Serial is openedWiFiManager 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 configurationwifiManager.autoConnect("AutoConnectAP");//or use this for auto generated name ESP + ChipID//wifiManager.autoConnect();//if you get here you have connected to the WiFiSerial.println("connected...yeey :)");Serial.println(WiFi.localIP());
}void loop() {// put your main code here, to run repeatedly:
}