物联网的最终是实时获取数据来控制物件完成相应的动作
esp8266作为服务端,产生json数据
1. 实时读取A0、 D1、D2以及D3引脚的读数。
2. 当有客户端请求时,通过响应信息将引脚读数和测试数据信息发送给客户端。
信息发送格式为json格式。以下为该json信息的示例:
该实例的解析使用官方提供的工具实现生成代码
{
"info": {
"name": "taichimaker",
"url": "www.taichi-maker.com",
"email": "taichimaker@163.com"
},
"digital_pin": {
"d1": "1",
"d2": "0",
"d3": "1"
},
"analog_pin": {
"a0": "500"
}
}
/**
* ESP8266客户端请求JSON信息,请求的数据是实时发生改变的
* 由两块esp8266开发板来完成,一块是用于作为服务器,一块是用于客户端请求
* 创建服务端来监控esp8266的实时引脚状态来控制,通过wifi局域网来访问
*/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
//洪定义
#define buttonPin D3
//建立ESP8266WIFIMulti对象
ESP8266WiFiMulti wifiMulti;
//建立网络服务器对象,该对象用于响应HTTP请求,监听端口80
ESP8266WebServer esp8266_server(80);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// 将引脚设置为输入上拉模式
pinMode(D1, INPUT_PULLUP);
pinMode(D2, INPUT_PULLUP);
pinMode(buttonPin, INPUT_PULLUP); // NodeMCU开发板按键连接在D3引脚上
//通过addAp函数存储 WiFi名称 WiFi密码
wifiMulti.addAP("nova", "wifi.danke.life");
wifiMulti.addAP("taichi-maker2", "87654321");
int i = 0;
//每隔一秒发送连接wifi直到wifi连接成功
while (wifiMulti.run() != WL_CONNECTED) { // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
delay(1000); // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
Serial.print(i++); Serial.print(' '); // 将会连接信号最强的那一个WiFi信号。
} // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
// 此处while循环判断是否跳出循环的条件。
//打印服务端地址
Serial.println(WiFi.localIP()); // NodeMCU的IP地址
//网络建立成功后,就开始写被访问的规则
esp8266_server.on("/",handleRoot);
esp8266_server.begin();//启动网络服务
}
void loop() {
//处理http服务器访问
esp8266_server.handleClient();
}
void handleRoot(){//处理网站目录"/"的访问请求
esp8266_server.send(200,"application/json",rootJson());
}
String rootJson(){
//const size_t capacity = JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(3)+140;
const size_t capacity = JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(3)+140;
DynamicJsonDocument doc(capacity);
JsonObject info = doc.createNestedObject("info");
info["name"] = "taichimaker";
info["url"] = "www.taichi-maker.com";
info["email"] = "taichimaker@163.com";
JsonObject digital_pin = doc.createNestedObject("digital_pin");
digital_pin["d1"] = String(digitalRead(D1));
digital_pin["d2"] = String(digitalRead(D2));
digital_pin["d3"] = String(digitalRead(D3));
JsonObject analog_pin = doc.createNestedObject("analog_pin");
analog_pin["a0"] = String(analogRead(A0));
String jsonCode;
serializeJson(doc,jsonCode);
return jsonCode;
}
客户端程序
客户端的功能为:
1. 向服务器端请求json数据信息
2. 解析服务器端响应的json信息内容。
3. 将解析后的数据信息显示于串口监视器
4. 利用服务器端D3引脚(按键引脚)读数来控制客户端开发板上LED的点亮和熄灭
/**
* 客户端主要的程序,通过获取服务端的数据解析输出到控制台
* 主要的功能实现
* 1. 向服务器端请求json数据信息
* 2. 解析服务器端响应的json信息内容。
* 3. 将解析后的数据信息显示于串口监视器
* 4. 利用服务器端D3引脚(按键引脚)读数来控制客户端开发板上LED的点亮和熄灭
*/
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象
const char* host = "192.168.43.163"; // 将要连接的服务器地址
const int httpPort = 80; // 将要连接的服务器端口
void setup() {
Serial.begin(9600);
//设置开发板的引脚,设置为输出模式
pinMode(LED_BUILTIN,OUTPUT);
//设置为高电平模式,led点亮
digitalWrite(LED_BUILTIN,HIGH);
//设置连接WiFi
wifiMulti.addAP("nova", "wifi.danke.life"); // 将需要连接的一系列WiFi ID和密码输入这里
//连接WiFi
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()); // WiFi名称
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // IP
}
void loop() {
//每隔3秒请求服务器
httpRequest();
delay(3000);
}
// 向服务器请求信息并对信息进行解析
void httpRequest(){
//创建对象
WiFiClient client;
// String httpRequest =String("GET /") + "HTTP/1.1\r\n" +
// "Host: " + host + "\r\n" +
// "Connection: close\r\n\r\n";
String httpRequest = String("GET /") + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n";
//连接服务器
if (client.connect(host, 80)){
Serial.println("connect Success!!");
//向服务器发送http请求
client.print(httpRequest);
Serial.println("Sending request: ");
Serial.println(httpRequest);
// 获取并显示服务器响应状态行
String status_response = client.readStringUntil('\n');
Serial.print("status_response: ");
Serial.println(status_response);
// 使用find跳过HTTP响应头
if(client.find("\r\n\r\n")){
Serial.println("Found Header End. Start Parsing.");
}
parseInfo(client);
}else{
Serial.println(" connection failed!");
}
//断开客户端与服务器连接工作
client.stop();
}
void parseInfo(WiFiClient client){
const size_t capacity = JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(3) + 140;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, client);
JsonObject info = doc["info"];
const char* info_name = info["name"]; // "taichimaker"
const char* info_url = info["url"]; // "www.taichi-maker.com"
const char* info_email = info["email"]; // "taichimaker@163.com"
JsonObject digital_pin = doc["digital_pin"];
const char* digital_pin_d1 = digital_pin["d1"]; // "1"
const char* digital_pin_d2 = digital_pin["d2"]; // "0"
const char* digital_pin_d3 = digital_pin["d3"]; // "1"
const char* analog_pin_a0 = doc["analog_pin"]["a0"]; // "500"
String info_name_str = info["name"].as<String>();
bool d3_bool = digital_pin["d3"].as<int>();
Serial.print("info_name_str = ");Serial.println(info_name_str);
Serial.print("d3_bool = ");Serial.println(d3_bool);
if(d3_bool == 0){
digitalWrite (LED_BUILTIN, LOW);
}else{
digitalWrite(LED_BUILTIN, HIGH);
}
}
可能在拼接访问路径可能会有问题!!!所以要注意