学习目的:客户端会定时向服务器发送请求信息。服务器一旦接收到客户端请求后,会把服务器开发板上的按键引脚状态发送给客户端。客户端在接收到这一信息后,会利用该信息来控制客户端的LED点亮和熄灭。最终实现的效果是,通过控制服务器端的板上按键,我们可以控制客户端板上LED的点亮和熄灭。
服务器端代码
/**********************************************************************
项目名称/Project : 零基础入门学用物联网
程序名称/Program name : cgd_server
程序目的/Purpose :
演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
一个以客户端模式运行。用户可通过服务器端开发板上按钮控制客户端的板上LED点亮和熄灭
此代码为服务器端代码。此代码主要功能:
- 实时获取服务器端开发板上按钮引脚状态
- 当有客户端向ESP8266服务器的/update发送请求时,将服务器的按键引脚状态
通过响应信息回复给客户端
***********************************************************************/
#include <ESP8266WiFi.h> // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h> // ESP8266WiFiMulti库
#include <ESP8266WebServer.h> // ESP8266WebServer库
#define buttonPin D3 // 按钮引脚D3
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
IPAddress local_IP(192, 168, 123, 123); // 设置ESP8266-NodeMCU联网后的IP
IPAddress gateway(192, 168, 123, 1); // 设置网关IP(通常网关IP是WiFI路由IP)
IPAddress subnet(255, 255, 255, 0); // 设置子网掩码
IPAddress dns(192,168,123,1); // 设置局域网DNS的IP(通常局域网DNS的IP是WiFI路由IP)
bool pinState; // 存储引脚状态用变量
void setup(){
Serial.begin(9600); // 启动串口通讯
Serial.println("");
pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式
// 设置开发板网络环境
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("Failed to ESP8266 IP");
}
//通过addAp函数存储 WiFi名称 WiFi密码
wifiMulti.addAP("TPLINK", "TPLINK123"); // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
wifiMulti.addAP("taichi-maker2", "87654321"); // 用户可自行增加、修改、删除此处网络连接信息。
wifiMulti.addAP("taichi-maker3", "13572468");
// 尝试网络连接
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) {
delay(1000);
Serial.print(i++); Serial.print(' ');
}
// WiFi连接成功后,通过串口监视器输出连接信息
Serial.println("");
Serial.print("Connected to ");
Serial.println(WiFi.SSID());
Serial.print("IP address:\t");
Serial.println(WiFi.localIP());
// 设置网络服务器
esp8266_server.on("/update", handleUpdate); // 处理客户端HTTP请求LED状态
esp8266_server.begin();
Serial.println("HTTP esp8266_server started");
}
void loop(){
pinState = digitalRead(buttonPin); // 获取引脚状态
esp8266_server.handleClient(); // 处理http服务器访问
}
// 处理客户端HTTP请求LED状态button: 1
void handleUpdate() {
String pinStateStr;
pinState == HIGH ? pinStateStr = "1" : pinStateStr = "0";
esp8266_server.send(200, "text/html", "buttonState: " + pinStateStr);
}
客户端代码
/**********************************************************************
项目名称/Project : 零基础入门学用物联网
程序名称/Program name : cgd_client
日期/Date(YYYYMMDD) : 20200228
程序目的/Purpose :
演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
一个以客户端模式运行。
此代码为客户端代码。此代码主要功能:
- 定时向服务器发送请求信息,从而获取服务器开发板上按钮状态
- 将服务器端发来的按钮引脚电平状态解析为数字量,并且用该数字量控制板上LED点亮和熄灭
***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象
const char* host = "192.168.123.123"; // 网络服务器IP
const int httpPort = 80; // http端口80
void setup(){
Serial.begin(9600);
Serial.println("");
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
wifiMulti.addAP("TPLINK", "TPLINK123"); // 将需要连接的一系列WiFi ID和密码输入这里
wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
Serial.println("Connecting ...");
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
delay(1000);
Serial.print(i++); Serial.print(' ');
}
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println("");
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // WiFi名称
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // IP
}
void loop(){
wifiClientRequest();
delay(3000);
}
void wifiClientRequest(){
WiFiClient client; // 建立WiFiClient对象
bool buttonState; // 储存服务器按钮状态变量
Serial.print("Connecting to "); Serial.print(host);
// 连接服务器
if (client.connect(host, httpPort)){
Serial.println(" Success!");
// 建立客户端请求信息
String httpRequest = String("GET /update") + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n" +
"\r\n";
// 发送客户端请求
Serial.println("Sending request: ");Serial.print(httpRequest);
client.print(httpRequest);
// 获取服务器响应信息中的按钮状态信息
while (client.connected() || client.available()){
if(client.find("buttonState:")){
buttonState = client.parseInt();
Serial.print("buttonState: " );
Serial.println(buttonState);
}
}
} else{
Serial.println(" failed!");
}
Serial.println("===============");
client.stop(); // 停止客户端
// 根据服务器按键状态点亮或熄灭LED
buttonState == 0 ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH);
}
// 获取服务器响应信息中的按钮状态信息
while (client.connected() || client.available()){
if(client.find("buttonState:")){
buttonState = client.parseInt();
Serial.print("buttonState: " );
Serial.println(buttonState);
}
}
if(client.find("buttonState:")){
buttonState = client.parseInt();
Serial.print("buttonState: " );
Serial.println(buttonState);
}
buttonState = client.parseInt();
bool buttonState; // 储存服务器按钮状态变量
parseInt();
说明
parseInt函数可用于从设备接收到的数据中寻找整数数值。
本函数属于Stream类。该函数可被Stream类的子类所使用,如(Serial, WiFiClient, File 等)。
语法
stream.parseInt()
注:此处stream为概念对象名称。在实际使用过程中,需要根据实际使用的stream子类对象名称进行替换。如:
Serial.parseInt()
wifiClient.parseInt()
参数
无
返回值
在输入信息中找到的整数数值。类型:long
所以结果符合:buttonState = client.parseInt();