授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。
共同学习成长QQ群 622368884,不喜勿加,里面有一大群志同道合的探路人
如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。
1.前言
这一篇,博主将教大家怎么去实现一个简易版本的获取省份疫情情况。
&ensp功能的图片,如下:
有条件的同学可以建立一个webserver html页面来显示或者用OLED显示
1.1 知识储备
本篇需要用到以下知识点:
- 运用到ArduinoJson V5库,github传送门,请读者自行下载该库放到Arduino安装目录(这里直接使用,博主后面计划会详细讲解该库,敬请期待);
- 运用到TCP Client,请参考 ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
- 运用到STA模式,请参考 ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
- 运用到一键配网功能,请参考 ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
2. 接口说明
3. 8266代码
/**
* 日期: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.总结
武汉加油,中国加油,疫情早日结束。
来源:CSDN
作者:单片机菜鸟哥
链接:https://blog.csdn.net/dpjcn1990/article/details/104237240