行业知识
【Wio Terminal】使用WiFi(3)- Wi-F的高级使用
使用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 #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
这是使用HTTPClient库的HTTPs连接。您可以参考此向您想要访问的网站发送HTTPs GET请求!
您可以按照此链接查找网站的根CA。
- 将yourNetwork和yourPassword更改为你的WiFi ssid和密码。
- 将代码上传到Wio Terminal。
#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
这是一个使用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 #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 matchconst 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
在WebServer库的帮助下,你可以在Wio Terminal上设置并运行Web服务器。通过在与Wio Terminal连接到同一网络的任何计算机上运行的浏览器访问服务器,你可以从网页上控制硬件,读取传感器的值等等!
简单 HelloServer 示例
这将在连接的网络上使用Wio Terminal设置一个简单的Web服务器。
- 将yourNetwork和yourPassword更改为您的WiFi ssid和密码。
- 将代码上传到Wio Terminal。
- 使用浏览器从同一网络输入Wio Terminal的IP地址来访问web服务器。
#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; iHTTP Authentication Web Server
这个示例设置了一个需要身份验证过程的Web服务器,这在某些情况下出于安全考虑可能非常有用。
- 将yourNetwork和yourPassword更改为您的WiFi ssid和密码。
- 将代码上传到Wio Terminal。
- 使用浏览器从同一网络输入Wio Terminal的IP地址来访问Web服务器,并输入预设的用户名和密码。
#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
我们讨论了WebServer,我们使用IP地址来访问它。 但是,如果您想通过键入域名(例如www.google.com)来访问它,则需要使用DNSServer。
- 使用DNSServer必须在AP模式下。
- 引入相应的库#include 。
- 声明DNSServer对象。
- 使用start()方法启动DNS服务器。
- 使用processNextRequest()方法处理来自客户端的请求。
- 将代码上传到Wio Terminal,并将您的PC连接到DNSServer示例Wi-Fi。
- 输入www.wioterminal.com和www.wioterminal.com/p1。
#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
什么是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 #include #include const char* ssid = "yourNetwork";const char* password = "yourPassword";// TCP server at port 80 will respond to HTTP requestsWiFiServer 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
这是一个mDNS-SD(服务发现)示例,允许您发现同一网络中的服务。
关于基于DNS的服务发现:
- 将 yourNetwork 和 yourPassword 更改为您的 WiFi ssid 和密码。
- 将代码上传到 Wio Terminal。
#include #include #include const char* ssid = "yourNetwork";const char* password = "yourPassword";// TCP server at port 80 will respond to HTTP requestsWiFiServer 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
我们已经将广为人知的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 #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:}