一、硬件组成
- esp32用作主控。(型号为:esp32_devkitc_v4)
- 一块串口屏用作显示。(型号为:TJC3224T024_011)
- Usb转ttl模块用作调试。
二、开发环境搭建(Arduino IDE)
- 进入Arduino官网 https://www.arduino.cc/en/software下载Arduino IDE。安装好后界面如下:
- 搭建esp32开发环境:点击文件/首选项:
输入:https://dl.espressif.com/dl/package_esp32_index.json 保存并重启Arduino
选择工具/开发板管理器
搜索esp32并下载安装
完成后可以看到esp32
三、向api接口发送HTTP请求并解析
1、在Arduino中安装所需要的库文件:点击工具/管理库
在搜索框输入 WiFi ,选中需要安装的库文件
2、设备初始化代码
#include<WiFi.h> //用于连接WiFi网络
#include<HTTPClient.h> //用于向服务端请求数据信息
#include<ArduinoJson.h> //用于解析返回的json数据
const char *dssid = "ssid"; //你的网络名称
const char *password = "password"; //你的网络密码
void setup() { //做设备初始化
Serial.begin(115200); //初始化串口波特率为115200
Serial.println(""); //打印空白行
WiFi.begin(dssid,password);//连接指定wifi
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
} //连接中返回.....
Serial.println("WiFi connected!");//WiFi连接成功
// put your setup code here, to run once:
}
3、请求数据并返回
void loop() {
HTTPClient http; //建立HTTPClient对象
http.begin("https://lab.isaaclin.cn/nCoV/api/overall");//向该网址发送http数据请求
int httpCode = http.GET(); //保存返回的状态码
// put your main code here, to run repeatedly:
if (httpCode > 0) // 如果状态码大于0说明请求过程无异常
{
if (httpCode == HTTP_CODE_OK) // 请求被服务器正常响应,等同于httpCode == 200
{
String payload = http.getString(); // 读取服务器返回的响应正文数据
Serial.println(payload); //串口打印返回的数据
}
}
else
{ //未被响应返回错误码
Serial.printf("[HTTP] GET... failed, error: %s\n",
http.errorToString(httpCode).c_str());
}
http.end(); // 结束当前连接
delay(1200000);//两分钟发送一次请求,过于频繁可能导致ip被接口封掉
}
4、下载验证:开发板型号选择:
PS:端口根据自身情况选择
串口打印结果如下:
返回数据为:
5、对返回数据做json解析: 定义结构体
struct ncov_data{ //该结构体用于保存数据
long currentConfirmedCount;//现存确诊
long currentConfirmedIncr;//较昨日
long confirmedCount;//累计确诊
long confirmedIncr;//较昨日
long curedCount;//累计治愈
long curedIncr;//较昨日
long seriousCount;//现存无症状
long seriousIncr;//较昨日
long deadCount;//累计死亡
long deadIncr;//较昨日
String updateTime;//更新时间
};
Json初始化
ncov_data China_data; //国内疫情数据
ncov_data World_data; //国外疫情数据
DynamicJsonDocument doc(1000); //创建DynamicJsonDocument对象
deserializeJson(doc, payload); //反序列化数据
JsonObject results_0 = doc["results"][0];
解析出的数据赋值
China_data.currentConfirmedCount = results_0["currentConfirmedCount"].as<int>();
China_data.currentConfirmedIncr = results_0["currentConfirmedIncr"].as<int>();
China_data.confirmedCount = results_0["confirmedCount"].as<int>();
China_data.confirmedIncr = results_0["confirmedIncr"].as<int>();
China_data.curedCount = results_0["curedCount"].as<int>();
China_data.curedIncr = results_0["curedIncr"].as<int>();
China_data.deadCount = results_0["deadCount"].as<int>();
China_data.deadIncr = results_0["deadIncr"].as<int>();
China_data.seriousCount = results_0["seriousCount"].as<int>();
China_data.seriousIncr = results_0["seriousIncr"].as<int>();
World_data.currentConfirmedCount = results_0["globalStatistics"]["currentConfirmedCount"].as<long>();
World_data.currentConfirmedIncr = results_0["globalStatistics"]["currentConfirmedIncr"].as<long>();
World_data.confirmedCount = results_0["globalStatistics"]["confirmedCount"].as<long>();
World_data.confirmedIncr = results_0["globalStatistics"]["confirmedIncr"].as<long>();
World_data.curedCount = results_0["globalStatistics"]["curedCount"].as<long>();
World_data.curedIncr = results_0["globalStatistics"]["curedIncr"].as<long>();
World_data.deadCount = results_0["globalStatistics"]["deadCount"].as<long>();
World_data.deadIncr = results_0["globalStatistics"]["deadIncr"].as<long>();
串口打印
Serial.println("");
Serial.println("----------------国内疫情---------------");
Serial.print("现存确诊: ");Serial.println(China_data.currentConfirmedCount);
Serial.print("累计确诊: ");Serial.println(China_data.confirmedCount);
Serial.print("累计治愈: ");Serial.println(China_data.curedCount);
Serial.print("现存无症: ");Serial.println(China_data.seriousCount);
Serial.print("累计死亡: ");Serial.println(China_data.deadCount);
Serial.println("----------------国外疫情---------------");
Serial.print("现存确诊: ");Serial.println(World_data.currentConfirmedCount);
Serial.print("累计确诊: ");Serial.println(World_data.confirmedCount);
Serial.print("累计治愈: ");Serial.println(World_data.curedCount);
Serial.print("累计死亡: ");Serial.println(World_data.deadCount);
四、发送数据到串口屏并显示
1、下载USART HMI串口屏软件,搭建自己喜欢的ui,过程可自行百度,略过。
2、Arduino代码:串口定义
#define TJC Serial2 //串口屏收发串口定义为串口2
初始化
TJC.begin(115200); //初始化收发串口波特率为115200
while (TJC.read() >= 0);//等待串口屏连接成功
字符串定义
char str1[20];
char str2[20];
char str3[20];
char str4[20];
char str5[20];
char str6[20];
char str7[20];
char str8[20];
char str9[20];
char str10[20];
sprintf格式拼接
sprintf(str1, "n0.val=%d\xff\xff\xff", China_data.currentConfirmedCount);
sprintf(str6, "n5.val=%d\xff\xff\xff", China_data.currentConfirmedIncr);
sprintf(str2, "n1.val=%d\xff\xff\xff", China_data.confirmedCount);
sprintf(str7, "n6.val=%d\xff\xff\xff", China_data.confirmedIncr);
sprintf(str3, "n2.val=%d\xff\xff\xff", China_data.curedCount);
sprintf(str8, "n7.val=%d\xff\xff\xff", China_data.curedIncr);
sprintf(str4, "n3.val=%d\xff\xff\xff", China_data.deadCount);
sprintf(str9, "n8.val=%d\xff\xff\xff", China_data.deadIncr);
sprintf(str5, "n4.val=%d\xff\xff\xff", China_data.seriousCount);
sprintf(str10, "n9.val=%d\xff\xff\xff", China_data.seriousIncr);
数据发送
TJC.print(str1);
TJC.print(str2);
TJC.print(str3);
TJC.print(str4);
TJC.print(str5);
TJC.print(str6);
TJC.print(str7);
TJC.print(str8);
TJC.print(str9);
TJC.print(str10);
3、将esp32的rx、tx引脚分别和串口屏的tx、rx引脚相连
4、参考文章 :疫情监控三部曲——在STM32F103 MCU上实现(裸机版) - 云+社区 - 腾讯云 (tencent.com)
五、完整代码
#include<WiFi.h> //用于连接WiFi网络
#include<HTTPClient.h> //用于向服务端请求数据信息
#include<ArduinoJson.h> //用于解析返回的json数据
#define TJC Serial2 //串口屏收发串口定义为串口2
const char *dssid = "DOG"; //你的网络名称
const char *password = "66666666"; //你的网络密码
struct ncov_data{ //该结构体用于保存数据
long currentConfirmedCount;//现存确诊
long currentConfirmedIncr;//较昨日
long confirmedCount;//累计确诊
long confirmedIncr;//较昨日
long curedCount;//累计治愈
long curedIncr;//较昨日
long seriousCount;//现存无症状
long seriousIncr;//较昨日
long deadCount;//累计死亡
long deadIncr;//较昨日
String updateTime;//更新时间
};
void setup() { //做设备初始化
Serial.begin(115200); //初始化串口波特率为115200
TJC.begin(115200); //初始化收发串口波特率为115200
while (TJC.read() >= 0);//等待串口屏连接成功
Serial.println(""); //打印空白行
WiFi.begin(dssid,password);//连接指定wifi
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
} //连接中返回.....
Serial.println("WiFi connected!");//WiFi连接成功
// put your setup code here, to run once:
}
void loop() {
HTTPClient http; //建立HTTPClient对象
http.begin("https://lab.isaaclin.cn/nCoV/api/overall");//向该网址发送http数据请求
int httpCode = http.GET(); //保存返回的状态码
// put your main code here, to run repeatedly:
if (httpCode > 0) // 如果状态码大于0说明请求过程无异常
{
if (httpCode == HTTP_CODE_OK) // 请求被服务器正常响应,等同于httpCode == 200
{
String payload = http.getString(); // 读取服务器返回的响应正文数据
Serial.println(payload); //串口打印返回的数据
ncov_data China_data; //国内疫情数据
ncov_data World_data; //国外疫情数据
DynamicJsonDocument doc(1000); //创建DynamicJsonDocument对象
deserializeJson(doc, payload); //反序列化数据
JsonObject results_0 = doc["results"][0];
//将解析出的数据赋值给结构体
China_data.currentConfirmedCount = results_0["currentConfirmedCount"].as<int>();
China_data.currentConfirmedIncr = results_0["currentConfirmedIncr"].as<int>();
China_data.confirmedCount = results_0["confirmedCount"].as<int>();
China_data.confirmedIncr = results_0["confirmedIncr"].as<int>();
China_data.curedCount = results_0["curedCount"].as<int>();
China_data.curedIncr = results_0["curedIncr"].as<int>();
China_data.deadCount = results_0["deadCount"].as<int>();
China_data.deadIncr = results_0["deadIncr"].as<int>();
China_data.seriousCount = results_0["seriousCount"].as<int>();
China_data.seriousIncr = results_0["seriousIncr"].as<int>();
World_data.currentConfirmedCount = results_0["globalStatistics"]["currentConfirmedCount"].as<long>();
World_data.currentConfirmedIncr = results_0["globalStatistics"]["currentConfirmedIncr"].as<long>();
World_data.confirmedCount = results_0["globalStatistics"]["confirmedCount"].as<long>();
World_data.confirmedIncr = results_0["globalStatistics"]["confirmedIncr"].as<long>();
World_data.curedCount = results_0["globalStatistics"]["curedCount"].as<long>();
World_data.curedIncr = results_0["globalStatistics"]["curedIncr"].as<long>();
World_data.deadCount = results_0["globalStatistics"]["deadCount"].as<long>();
World_data.deadIncr = results_0["globalStatistics"]["deadIncr"].as<long>();
//字符串定义
char str1[20];
char str2[20];
char str3[20];
char str4[20];
char str5[20];
char str6[20];
char str7[20];
char str8[20];
char str9[20];
char str10[20];
char str11[20];
char str12[20];
char str13[20];
char str14[20];
char str15[20];
char str16[20];
char str17[20];
char str18[20];
//使用sprintf进行格式拼接
sprintf(str1, "n0.val=%d\xff\xff\xff", China_data.currentConfirmedCount);
sprintf(str6, "n5.val=%d\xff\xff\xff", China_data.currentConfirmedIncr);
sprintf(str2, "n1.val=%d\xff\xff\xff", China_data.confirmedCount);
sprintf(str7, "n6.val=%d\xff\xff\xff", China_data.confirmedIncr);
sprintf(str3, "n2.val=%d\xff\xff\xff", China_data.curedCount);
sprintf(str8, "n7.val=%d\xff\xff\xff", China_data.curedIncr);
sprintf(str4, "n3.val=%d\xff\xff\xff", China_data.deadCount);
sprintf(str9, "n8.val=%d\xff\xff\xff", China_data.deadIncr);
sprintf(str5, "n4.val=%d\xff\xff\xff", China_data.seriousCount);
sprintf(str10, "n9.val=%d\xff\xff\xff", China_data.seriousIncr);
//发送数据
TJC.print(str1);
TJC.print(str2);
TJC.print(str3);
TJC.print(str4);
TJC.print(str5);
TJC.print(str6);
TJC.print(str7);
TJC.print(str8);
TJC.print(str9);
TJC.print(str10);
TJC.print("page 1\xff\xff\xff");
sprintf(str11, "n10.val=%d\xff\xff\xff", World_data.currentConfirmedCount);
sprintf(str12, "n11.val=%d\xff\xff\xff", World_data.currentConfirmedIncr);
sprintf(str13, "n12.val=%d\xff\xff\xff", World_data.confirmedCount);
sprintf(str14, "n13.val=%d\xff\xff\xff", World_data.confirmedIncr);
sprintf(str15, "n14.val=%d\xff\xff\xff", World_data.curedCount);
sprintf(str16, "n15.val=%d\xff\xff\xff", World_data.curedIncr);
sprintf(str17, "n16.val=%d\xff\xff\xff", World_data.deadCount);
sprintf(str18, "n17.val=%d\xff\xff\xff", World_data.deadIncr);
TJC.print(str11);
TJC.print(str12);
TJC.print(str13);
TJC.print(str14);
TJC.print(str15);
TJC.print(str16);
TJC.print(str17);
TJC.print(str18);
TJC.print("page 0\xff\xff\xff");
//串口打印
// Serial.println("");
// Serial.println("----------------国内疫情---------------");
// Serial.print("现存确诊: ");Serial.println(China_data.currentConfirmedCount);
// Serial.print("累计确诊: ");Serial.println(China_data.confirmedCount);
// Serial.print("累计治愈: ");Serial.println(China_data.curedCount);
// Serial.print("现存无症: ");Serial.println(China_data.seriousCount);
// Serial.print("累计死亡: ");Serial.println(China_data.deadCount);
// Serial.println("----------------国外疫情---------------");
// Serial.print("现存确诊: ");Serial.println(World_data.currentConfirmedCount);
// Serial.print("累计确诊: ");Serial.println(World_data.confirmedCount);
// Serial.print("累计治愈: ");Serial.println(World_data.curedCount);
// Serial.print("累计死亡: ");Serial.println(World_data.deadCount);
}
}
else
{ //未被响应返回错误码
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end(); // 结束当前连接
delay(1200000);//两分钟发送一次请求,过于频繁可能导致ip被接口封掉
}
六、效果展示