前言

玩ESP一定会需要获取网络上的各种讯息,而比较入门的内容就是获取网络时间,通过连接NTP服务器来完成。

另一个家是获取气温和天气,通常用在时钟类的项目上面。

这里提供最简单的方法说明如何获取,以及要怎么样方便快捷的解析JSON

用到的头文件以及功能

#include <Thread.h> //多线程

#include <U8g2lib.h>  //U8glib,一个知名绘图库

#include <Wire.h> //I2C相关函数

#include <WiFi.h> //ESP32 Wifi相关函数

#include "time.h" //时间的处理

#include <HTTPClient.h> //获取http

#include <ArduinoJson.h> //解析json

1. 连接网络和时间获取

所有的基本就是连接网络,这里使用Wifi进行连接,因为从简所以先定义ssid和密码

const char *ssid = "wifi账号"; //

const char *password = "wifi的密码";

然后就是定义ntp服务器,使用的是阿里云的服务器需要注意的是夏令时和时区的时间偏移,我们是北京时间,GMT+8所以就是28800

const char *ntpServer = "ntp.aliyun.com"; //时间服务器

const long gmtOffset_sec = 28800;         //时间偏移

const int daylightOffset_sec = 0;

然后就是启动wifi,等待wifi连接,这里用到的连接函数是Wifi.begin(),然后通过判断Wifi.status()是否是WL_CONNECTED来判断ESP32这会儿有没有连接到路由器

这里我用一个变量i来做计数器,达到127时候就提示出错,连不上网。

WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)

  {

    delay(50);

    Serial.print(".");

    //u8g2.setCursor(2 + (i++), );

    u8g2.drawLine(0, 0, (i++), 0);

    u8g2.sendBuffer();

    if (i == 127)

    {

      DisError();

    }

  }

如果连接上,就是获取时间,使用configTime函数来完成

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

最后断开连接,关闭ESP32的Wifi功能达到省电的目的,实测关闭Wifi仅打开OLED的情况下功耗在20ma左右。

WiFi.disconnect(true);

  WiFi.mode(WIFI_OFF);

整个函数如下

//获取网上的时间

void getNetTime()

{

  int i = 0;

  Serial.printf("Connecting to %s ", ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)

  {

    delay(50);

    Serial.print(".");

    //u8g2.setCursor(2 + (i++), );

    u8g2.drawLine(0, 0, (i++), 0);

    u8g2.sendBuffer();

    if (i == 127)

    {

      Desirer();

    }

  }

  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

  u8g2.setDrawColor(1);

  u8g2.setFont(font1);

  u8g2.setCursor(10, 48);

  clearHalf();

  u8g2.setDrawColor(1);

  u8g2.print("Get Time!"); //TODO 获取时间的提示

  // u8g2.sendBuffer();


  printLocalTime();

  Serial.println(" CONNECTED");

  WiFi.disconnect(true);

  WiFi.mode(WIFI_OFF);

}

获取天气和JSON解析

要获取天气需要在连接Wifi的情况下,具体在上一章节进行了说明,在连接到Wifi热点/路由器的情况下,访问API,获取JSON并且解析出天气和气温,这是ESP32在这一个章节要做的事情。

因为是在线获取,所以需要使用动态JSON解析,这里使用的库是AduinoJson,使用DynamicJsonDocument 来初始化一个存储Json数据的内存空间

DynamicJsonDocument doc(2048);

我们使用的是心知天气,它的api格式如下,需要自行去注册账号并且申请API(完全免费),如何申请在本文中略过。需要自定义的有API私钥和你所在的城市。

String tagethttp = "https://api.seniverse.com/v3/weather/now.json?key=这里填写你的API Key &location=这里填城市拼音名称&language=en";

这里需要实例化一个HTTPClient,然后使用begin函数去尝试连接

HTTPClient https;

https.begin(tagethttp);

完成https连接后,在这里需要描述一下ArduinoJson的用法,用于解析我们用API获取到的数据

直接获取的天气的Json数据是这样的:

{"results":[{"location":{"id":"WX4FBXXFKE4F","name":"Beijing","country":"CN","path":"Beijing,Beijing,China","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"Overcast","code":"9","temperature":"26"},"last_update":"2021-08-11T21:24:24+08:00"}]}

浏览器优化后可以看出来是一个多层结构,分为location和now

esp32 定时重启 esp32 时间_esp32

ArduinoJson可以帮助我们快速简单的解析数据,它是以层层分析的形式,首先获取到Json数据,此时是字符串

String payload = https.getString();

之后需要解析为Json,存储到刚才划分的DynamicJsonDocument存储空间

deserializeJson(doc, payload);

接着就是先用JsonObject来获取整个Json数据中,now那部分内容

JsonObject results_0 = doc["results"][0];

JsonObject results_0_now = results_0["now"];

接着是获取天气

weather = results_0_now["text"];

以及气温

temperature = results_0_now["temperature"];

这样就可以完成所有解析了。

整个获取天气和气温,解析JSON代码如下,我用U8G2来实现OLED显示:

int temperature = 0;
const char *weather;
void getHttp() //TODO 获取http网页
{
  DynamicJsonDocument doc(2048);
  HTTPClient https;
  https.begin(tagethttp);
  int httpCode = https.GET();
  u8g2.setFont(font1);
  u8g2.clear();
  u8g2.setCursor(3, 50);
  if (httpCode > 0)
  {

    u8g2.sendBuffer();
    String payload = https.getString();
    deserializeJson(doc, payload);
    JsonObject results_0 = doc["results"][0];
    JsonObject results_0_now = results_0["now"];
    weather = results_0_now["text"];
    temperature = results_0_now["temperature"];
  }
  else
  {

    u8g2.print("Get http Failed");
    u8g2.sendBuffer();
    delay(1000);
  }
}

更多工具

这里还要提供一个方法,是使用在线工具来快速的预览你获得的数据,以及筛选他们的结果

https://wandbox.org/permlink/hcB7LwkuBtcUc3u6

esp32 定时重启 esp32 时间_数据_02

在上面这边写一些代码,就可以在下面直接查看到最终输出的结果,可以说是非常快速而且容易使用。