ESP8266 development tour application part ⑦ simple version online access to new coronavirus in specific provinces

It is better to teach people to fish than to teach people to fish. The purpose is not to teach you specific project development, but to learn the ability of learning. I hope you can share it with your friends or classmates who are in need around you. Maybe there is a foundation stone of Bogor in the way of growth of God...

Learn and grow together QQ group 622368884, don't add if you don't like it, there are a large group of like-minded explorers in it

Fast navigation
The blog index of the rookie of single chip microcomputer (quickly find what you want)

If you think it's useful, please like collection. Your support is the power of blogger's creation.

Article directory

1. Preface

In this article, the blogger will teach you how to achieve a simple version of the epidemic situation in the province.
Picture of the & ENSP function, as follows:

Conditional students can build a web server HTML page to display or use OLED to display

1.1 knowledge reserve

This article needs to use the following knowledge points:

  • Applied to ArduinoJson V5 library, github portal , please download the library and put it into the Arduino installation directory (for direct use here, the blogger plans to explain the library in detail later, please look forward to it);
  • For application to TCP Client, please refer to ESP8266 development tour network chapter ⑦ TCP server & TCP Client
  • For the application of STA mode, please refer to ESP8266 development tour network chapter ④ Station - use of esp8266wifi STA Library
  • For the application of one key distribution network function, please refer to ESP8266 development tour network ⑧ SmartConfig - one key distribution network

2. Interface description

3. 8266 code

/**
* Date: February 9, 2019
* Function: Wuhan refueling China refueling
* Author: single chip rookie
**/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>

#define LED D4
#define DEBUG //Whether to enable the debug function

#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

//Declarative method
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 = "Guangdong Province";

int flag = HIGH;//Default current off
WiFiClient client;
char response[MAX_CONTENT_SIZE];
char endOfHeaders[] = "\r\n\r\n";

long lastTime = 0;
// Request service interval
long Delay = 20000;
// Epidemic data variables
int confirmedCount;
int suspectedCount;
int curedCount;
int deadCount;

/**
* @Desc Initialize operation
*/
void setup() {
  Serial.begin(BAUD_RATE);
  pinMode(LED,OUTPUT);
  digitalWrite(LED, HIGH);

  if(!autoConfig()){
    smartConfig();
    DebugPrint("Connecting to WiFi");//Write a few hints, ha ha
    while (WiFi.status() != WL_CONNECTED) {
    //This function is the wifi connection status and returns the wifi connection status
       delay(500);
       DebugPrint(".");
    }
  }
  
  delay(1000);
  digitalWrite(LED, LOW);
  DebugPrintln("IP address: ");
  DebugPrintln(WiFi.localIP());//WiFi.localIP() returns the ip address obtained by 8266
  lastTime = millis();
  
  //Trigger interval of enable software watchdog
  ESP.wdtEnable(5000);
}
  
/**
* @Desc  Main function
*/
void loop() {
  while (!client.connected()){
     if (!client.connect(host, 80)){
         flag = !flag;
         digitalWrite(LED, flag);
         delay(500);
         //feed a dog
         ESP.wdtFeed();
     }
  }

  if(millis()-lastTime>=Delay){
   //Call every 20s or so
     lastTime = millis();
     if (sendRequest() && skipResponseHeaders()) {
       clrEsp8266ResponseBuffer();
       readReponseContent(response, sizeof(response));
       if (parseUserData(response)) {
          
       }
     }
  }
  
   //feed a dog
   ESP.wdtFeed();
}

/**
* Automatically enter SmartConfig mode after 20 seconds of automatic connection
*/
bool autoConfig(){
  WiFi.mode(WIFI_AP_STA);     //Set esp8266 working mode
  WiFi.begin();
  delay(2000);//When the module is just started, the delay will be stable
  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;
}

/**
* Turn on SmartConfig
*/
void smartConfig()
{
  WiFi.mode(WIFI_STA);
  delay(1000);
  DebugPrintln("Wait for Smartconfig");
  // Waiting for distribution network
  WiFi.beginSmartConfig();
  while (1){
    DebugPrint(".");
    delay(200);
    flag = !flag;
    digitalWrite(LED, flag);
    
    if (WiFi.smartConfigDone()){
      //smartconfig configuration complete
      DebugPrintln("SmartConfig Success");
      WiFi.mode(WIFI_AP_STA);     //Set esp8266 working mode
      WiFi.setAutoConnect(true);  // Set up automatic connection
      break;
    }
  }
}

/**
* @Send request instruction
*/
bool sendRequest() {
  // We now create a URI for the request
  //Knowing weather
  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 Skip the HTTP header so that we are at the beginning of the response body
*/
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 Read body from HTTP server response
*/
void readReponseContent(char* content, size_t maxSize) {
  size_t length = client.readBytes(content, maxSize);
  delay(100);
  content[length] = 0;
  client.flush();//This code needs to be added otherwise it will be found that client.find will fail every other time
}
  
// Close connection to HTTP server
void stopConnect() {
  client.stop();
}
 
void clrEsp8266ResponseBuffer(void){
    memset(response, 0, MAX_CONTENT_SIZE);      //empty
}

bool parseUserData(char* content) {
//    --Calculate the optimal size of JSON buffer according to the data we need to parse
//   If you use StaticJsonBuffer
//    const size_t BUFFER_SIZE = 1024;
//   Allocate a temporary memory pool on the stack
//    StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
//    --If the memory pool of the stack is too large, use DynamicJsonBuffer jsonBuffer instead
  DynamicJsonBuffer jsonBuffer;
  
  JsonObject& root = jsonBuffer.parseObject(content);
  
  if (!root.success()) {
    Serial.println("JSON parsing failed!");
    return false;
  }

  // --------Corresponding provincial data-----------
  JsonObject& provinces = root["results"][0];
  const char* country = provinces["country"]; // "China"
  const char* provinceName = provinces["provinceName"]; // Province
  confirmedCount = provinces["confirmedCount"];
  suspectedCount = provinces["suspectedCount"];
  curedCount = provinces["curedCount"];
  deadCount = provinces["deadCount"];
  
  // --------Serial port printing real-time epidemic information-----------
  Serial.printf("%s Real time data of new pneumonia",provice);
  Serial.println("-----------------------------------------");

  Serial.printf("Diagnosis:%d | Doubtful:%d | Cure:%d | Death:%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"]; // "Ningbo"
    confirmedCount = ciry["confirmedCount"];
    suspectedCount = ciry["suspectedCount"];
    curedCount = ciry["curedCount"];
    deadCount = ciry["deadCount"];
    Serial.printf("%s | Diagnosis:%d | Doubtful:%d | Cure:%d | Death:%d",cityName,confirmedCount,suspectedCount,curedCount,deadCount);
    Serial.println();
  }
  Serial.println("-----------------------------------------");
  return true;
}

4. summary

Come on Wuhan, come on China, the epidemic will end as soon as possible.

119 original articles published, 607 praised and 210 thousand visited+
Private letter follow

Tags: network JSON Web Server github

Posted on Sun, 09 Feb 2020 01:16:35 -0800 by douga