使用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:
}