ESP8266 development application piece ⑦ Tour light version of online access to certain provinces novel coronavirus case

Give a man a fish than giving the fishing, the purpose is not to teach you to develop specific projects, but to learn the ability to learn. I hope you share with friends or classmates around you need, maybe there is a large growth path God cornerstone Boge. . .

Learn, grow QQ group 622,368,884 , do not like not increase, there are a large group of like-minded people Pathfinder

Quick navigation
SCM rookie blog quickly index (quickly find what you want)

If you find it useful, trouble spots like the collection, your support is the driving force bloggers creation.

1 Introduction

    This one, Bo Lord teach you how to implement a simple version of the provinces get the epidemic situation.
   & ensp picture function, as follows:
Here Insert Picture Description
Qualified students can create a webserver html page to display or OLED display

1.1 knowledge base

    Benpian need to use the following knowledge:

  • Applied to ArduinoJson V5 library GitHub portal , the reader is free to download the library into the Arduino installation directory (here directly, bloggers will explain in detail later in the program library, so stay tuned);
  • To use TCP Client, please refer ESP8266 network development trip to articles ⑦ TCP Server & TCP Client
  • STA mode to use, please refer ESP8266 network development trip to articles ④ Station - use ESP8266WiFiSTA library
  • Applied to a key distribution network function, please refer ESP8266 network development trip to articles ⑧ SmartConfig-- a key distribution network

2. Interface Description

Here Insert Picture Description

3.8266 Code

/**
* 日期:2019/02/09
* 功能:武汉加油 中国加油
* 作者:单片机菜鸟
**/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>

#define LED D4
#define DEBUG //是否开启debug功能

#ifdef DEBUG
#define DebugPrintln(message)    Serial.println(message)
#else
#define DebugPrintln(message)
#endif

#ifdef DEBUG
#define DebugPrint(message)    Serial.print(message)
#else
#define DebugPrint(message)
#endif

//声明方法
bool autoConfig();
void smartConfig();
bool sendRequest(const char* host, const char* cityid, const char* apiKey);
bool skipResponseHeaders();
void readReponseContent(char* content, size_t maxSize);
void stopConnect();
void clrEsp8266ResponseBuffer(void);
bool parseUserData(char* content, struct UserData* userData);
  
const unsigned long BAUD_RATE = 115200;// serial connection speed
const unsigned long HTTP_TIMEOUT = 5000;               // max respone time from server
const size_t MAX_CONTENT_SIZE = 3000;                   // max size of the HTTP response
const char* host = "lab.isaaclin.cn";
const char* provice = "广东省";

int flag = HIGH;//默认当前灭灯
WiFiClient client;
char response[MAX_CONTENT_SIZE];
char endOfHeaders[] = "\r\n\r\n";

long lastTime = 0;
// 请求服务间隔
long Delay = 20000;
// 疫情数据变量
int confirmedCount;
int suspectedCount;
int curedCount;
int deadCount;

/**
* @Desc 初始化操作
*/
void setup() {
  Serial.begin(BAUD_RATE);
  pinMode(LED,OUTPUT);
  digitalWrite(LED, HIGH);

  if(!autoConfig()){
    smartConfig();
    DebugPrint("Connecting to WiFi");//写几句提示,哈哈
    while (WiFi.status() != WL_CONNECTED) {
    //这个函数是wifi连接状态,返回wifi链接状态
       delay(500);
       DebugPrint(".");
    }
  }
  
  delay(1000);
  digitalWrite(LED, LOW);
  DebugPrintln("IP address: ");
  DebugPrintln(WiFi.localIP());//WiFi.localIP()返回8266获得的ip地址
  lastTime = millis();
  
  //使能软件看门狗的触发间隔
  ESP.wdtEnable(5000);
}
  
/**
* @Desc  主函数
*/
void loop() {
  while (!client.connected()){
     if (!client.connect(host, 80)){
         flag = !flag;
         digitalWrite(LED, flag);
         delay(500);
         //喂狗
         ESP.wdtFeed();
     }
  }

  if(millis()-lastTime>=Delay){
   //每间隔20s左右调用一次
     lastTime = millis();
     if (sendRequest() && skipResponseHeaders()) {
       clrEsp8266ResponseBuffer();
       readReponseContent(response, sizeof(response));
       if (parseUserData(response)) {
          
       }
     }
  }
  
   //喂狗
   ESP.wdtFeed();
}

/**
* 自动连接20s 超过之后自动进入SmartConfig模式
*/
bool autoConfig(){
  WiFi.mode(WIFI_AP_STA);     //设置esp8266 工作模式
  WiFi.begin();
  delay(2000);//刚启动模块的话 延时稳定一下
  DebugPrintln("AutoConfiging ......");
  for(int index=0;index<10;index++){
    int wstatus = WiFi.status();
    if (wstatus == WL_CONNECTED){
      DebugPrintln("AutoConfig Success");
      DebugPrint("SSID:");
      DebugPrintln(WiFi.SSID().c_str());
      DebugPrint("PSW:");
      DebugPrintln(WiFi.psk().c_str());
      return true;
    }else{
      DebugPrint(".");
      delay(500);
      flag = !flag;
      digitalWrite(LED, flag);
    } 
  }
  DebugPrintln("AutoConfig Faild!");
  return false;
}

/**
* 开启SmartConfig功能
*/
void smartConfig()
{
  WiFi.mode(WIFI_STA);
  delay(1000);
  DebugPrintln("Wait for Smartconfig");
  // 等待配网
  WiFi.beginSmartConfig();
  while (1){
    DebugPrint(".");
    delay(200);
    flag = !flag;
    digitalWrite(LED, flag);
    
    if (WiFi.smartConfigDone()){
      //smartconfig配置完毕
      DebugPrintln("SmartConfig Success");
      WiFi.mode(WIFI_AP_STA);     //设置esp8266 工作模式
      WiFi.setAutoConnect(true);  // 设置自动连接
      break;
    }
  }
}

/**
* @发送请求指令
*/
bool sendRequest() {
  // We now create a URI for the request
  //心知天气
  String GetUrl = "/nCoV/api/area";
  GetUrl += "?latest=1";
  GetUrl += "&province=";
  GetUrl += provice;
  
  // This will send the request to the server
  client.print(String("GET ") + GetUrl + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(1000);
  return true;
}
 
/**
* @Desc 跳过 HTTP 头,使我们在响应正文的开头
*/
bool skipResponseHeaders() {
  // HTTP headers end with an empty line
  bool ok = client.find(endOfHeaders);
  if (!ok) {
    DebugPrintln("No response or invalid response!");
  }
  return ok;
}
 
/**
* @Desc 从HTTP服务器响应中读取正文
*/
void readReponseContent(char* content, size_t maxSize) {
  size_t length = client.readBytes(content, maxSize);
  delay(100);
  content[length] = 0;
  client.flush();//这句代码需要加上  不然会发现每隔一次client.find会失败
}
  
// 关闭与HTTP服务器连接
void stopConnect() {
  client.stop();
}
 
void clrEsp8266ResponseBuffer(void){
    memset(response, 0, MAX_CONTENT_SIZE);      //清空
}

bool parseUserData(char* content) {
//    -- 根据我们需要解析的数据来计算JSON缓冲区最佳大小
//   如果你使用StaticJsonBuffer时才需要
//    const size_t BUFFER_SIZE = 1024;
//   在堆栈上分配一个临时内存池
//    StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
//    -- 如果堆栈的内存池太大,使用 DynamicJsonBuffer jsonBuffer 代替
  DynamicJsonBuffer jsonBuffer;
  
  JsonObject& root = jsonBuffer.parseObject(content);
  
  if (!root.success()) {
    Serial.println("JSON parsing failed!");
    return false;
  }

  // -------- 对应省数据 -----------
  JsonObject& provinces = root["results"][0];
  const char* country = provinces["country"]; // "中国"
  const char* provinceName = provinces["provinceName"]; // "省份"
  confirmedCount = provinces["confirmedCount"];
  suspectedCount = provinces["suspectedCount"];
  curedCount = provinces["curedCount"];
  deadCount = provinces["deadCount"];
  
  // -------- 串口打印实时疫情信息 -----------
  Serial.printf("%s新型肺炎疫情实时数据",provice);
  Serial.println("-----------------------------------------");

  Serial.printf("确诊:%d | 疑似:%d | 治愈:%d | 死亡:%d",confirmedCount,suspectedCount,curedCount,deadCount);
  Serial.println();
  // -------- cities -----------
  JsonArray& cities = provinces["cities"];

  for( int index = 0; index < cities.size(); index ++){
    JsonObject& ciry = cities[index];
    const char* cityName = ciry["cityName"]; // "宁波"
    confirmedCount = ciry["confirmedCount"];
    suspectedCount = ciry["suspectedCount"];
    curedCount = ciry["curedCount"];
    deadCount = ciry["deadCount"];
    Serial.printf("%s | 确诊:%d | 疑似:%d | 治愈:%d | 死亡:%d",cityName,confirmedCount,suspectedCount,curedCount,deadCount);
    Serial.println();
  }
  Serial.println("-----------------------------------------");
  return true;
}

4. Summary

Come Wuhan, China refueling, an early end to the epidemic.

Published 119 original articles · won praise 607 · views 210 000 +

Guess you like

Origin blog.csdn.net/dpjcn1990/article/details/104237240