学习目的:通过两块esp8266模块实现互联,一块作为服务器,另一块作为客户端,连接成功后客户端发送http请求,并通过客户端的按键来控制服务器端的LED 的亮灭!
在这个示例中,ESP8266客户端将会通过HTTP协议向ESP8266服务器发送信息。在运行过程中,客户端ESP8266将会实时检测板上的按键状态,并且把按键状态发送给服务器。服务器在接收到客户端按键状态后,可以根据客户端按键状态来控制服务器端板上的LED点亮和熄灭。最终实现的效果是,我们可以通过客户端ESP8266开发板上的按键来“遥控”服务器上的LED点亮和熄灭。
服务器端代码如下:
/**********************************************************************
项目名称/Project : 零基础入门学用物联网
程序名称/Program name : csd_server
演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,一个以客户端模式运行。
此代码为服务器端代码。此代码主要功能:
- 接收客户端发来的http请求
- 解析客户端请求中的数据信息
- 将解析的数据信息通过串口监视器显示供用户查看
- 将解析的客户端按键状态信息用于控制板上LED的点亮和熄灭
-----------------------------------------------------------------------
***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h> // 使用WiFiMulti库
#include <ESP8266WebServer.h> // 使用WebServer库
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
ESP8266WebServer 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)
void setup(void){
Serial.begin(9600); // 启动串口通讯
Serial.println("");
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); //HIGH 电平 LED灭
// 设置开发板网络环境
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("Failed to Config ESP8266 IP");
}
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 ..."); // 则尝试使用此处存储的密码进行连接。
// 尝试进行wifi连接。
while (wifiMulti.run() != WL_CONNECTED) {
delay(250);
Serial.print('.');
}
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
server.on("/update", handleUpdate); // 处理服务器更新函数
server.begin(); // 启动网站服务
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient(); // 检查http服务器访问
}
void handleUpdate(){
float floatValue = server.arg("float").toFloat(); // 获取客户端发送HTTP信息中的浮点数值
int intValue = server.arg("int").toInt(); // 获取客户端发送HTTP信息中的整数数值
int buttonValue = server.arg("button").toInt(); // 获取客户端发送HTTP信息中的按键控制量
server.send(200, "text/plain", "Received"); // 发送http响应
buttonValue == 0 ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH); //<表达式1> ? <表达式2> : <表达式3>;
//"?"运算符的含义是:先求表达式1的值,如果为真,则执行表达式2,并返回表达式2的结果;
//如果表达式1的值为假,则执行表达式3,并返回表达式3的结果。
// 通过串口监视器输出获取到的变量数值
Serial.print("floatValue = "); Serial.println(floatValue);
Serial.print("intValue = "); Serial.println(intValue);
Serial.print("buttonValue = "); Serial.println(buttonValue);
Serial.println("=================");
}
代码解析:
1.server.arg(“float”)
server.arg(“float”).toFloat(); // 获取客户端发送HTTP信息中的浮点数值
server.arg(“float”)
说明
使用本函数,我们可以获取客户端向ESP8266物联网服务器发送的指定参数的数值。
语法
server.arg(Name)
server.arg(index)
参数
– Name
请求体中的参数名(参数类型: String)
– index
请求体中的参数序列号(参数类型: int)
返回值
指定参数的数值(类型:String)
http://192.168.0.106/?a=1&b=2&c=3
我们可以看到,以上信息中有三个参数,这些参数中,a的数值为1,序列号为2的参数数值为3(序列号0的参数为a, 序列号1的参数为b…)。
server.arg(“a”) = 1
server.arg(2) = 3
2. server.on("/update", handleUpdate); // 处理服务器更新函数
针对客户端的更新请求
// 将需要发送的数据信息放入客户端请求
String url = "/update?float=" + String(clientFloatValue) +
"&int=" + String(clientIntValue) +
"&button=" + String(buttonState);
// 建立字符串,用于HTTP请求
String httpRequest = String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n" +
"\r\n";
客户端代码如下:
/**********************************************************************
项目名称/Project : 零基础入门学用物联网
程序名称/Program name : csd_client
程序目的/Purpose :
演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
一个以客户端模式运行。
此代码为客户端代码。此代码主要功能:
- 通过HTTP协议向服务器发送HTTP请求
- HTTP请求中包含客户端按键开关引脚状态和程序测试数据
http信息发送说明
192.168.0.123/update?float=1.5&int=2&button=0
***********************************************************************/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h> // 使用WiFiMulti库
#define buttonPin D3 // 按钮引脚D3
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
bool buttonState; //存储客户端按键控制数据
float clientFloatValue; //存储客户端发送的浮点型测试数据
int clientIntValue; //存储客户端发送的整数型测试数据
const char* host = "192.168.123.123"; // 即将连接服务器网址/IP
const int httpPort = 80; // 即将连接服务器端口
void setup(void){
Serial.begin(9600); // 启动串口通讯
Serial.println("");
pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式
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 ..."); // 则尝试使用此处存储的密码进行连接。
while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
delay(250);
Serial.print('.');
}
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
}
void loop(void){
// 获取按键引脚状态
buttonState = digitalRead(buttonPin);
// 改变测试用变量数值用于服务器端接收数据检测
clientFloatValue += 1.5;
clientIntValue += 2;
// 发送请求
wifiClientRequest();
delay(1000);
}
void wifiClientRequest(){
WiFiClient client;
// 将需要发送的数据信息放入客户端请求
String url = "/update?float=" + String(clientFloatValue) +
"&int=" + String(clientIntValue) +
"&button=" + String(buttonState);
// 建立字符串,用于HTTP请求
String httpRequest = String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n" +
"\r\n";
Serial.print("Connecting to ");
Serial.print(host);
if (client.connect(host, httpPort)) { //如果连接失败则串口输出信息告知用户然后返回loop
Serial.println(" Sucess");
client.print(httpRequest); // 向服务器发送HTTP请求
Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容以便查阅
Serial.println(httpRequest);
} else{
Serial.println(" failed");
}
client.stop();
}