ESP32+串口屏组成的疫情监控平台

Posted 海狗先森

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP32+串口屏组成的疫情监控平台相关的知识,希望对你有一定的参考价值。

一、硬件组成

  1. esp32用作主控。(型号为:esp32_devkitc_v4)
  2. 一块串口屏用作显示。(型号为:TJC3224T024_011)
  3. Usb转ttl模块用作调试。

二、开发环境搭建(Arduino IDE)

  1. 进入Arduino官网 https://www.arduino.cc/en/software下载Arduino IDE。安装好后界面如下:
  2. 搭建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串口屏软件 start [USART HMI 资料中心] (tjc1688.com)
 

               官网有创建工程和基本使用的详细教程

               本人在此创建了两个界面,通过按钮控件进行切换,并使用全局变量保存来自单片机的                   数据并显示。可根据个人喜好搭建自己的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被接口封掉

六、效果展示

以上是关于ESP32+串口屏组成的疫情监控平台的主要内容,如果未能解决你的问题,请参考以下文章

esp32cam接错烧了

stm32f373利用esp8266连接onenet平台

STM32+ESP8266连接腾讯云物联网开发平台 2STM32+ESP8266-01S连接腾讯云

ESP32-Micropython串口通信

Arduino框架下ESP32重启原因串口信息输出示例

unbuntu14.04下的串口软件monicom的使用