用ESP32-S2模块的物联网平台制作一个本地气象台/温度计
制作一个本地气象台/温度计显示当前本地的时间、温度和气象信息
标签
嵌入式系统
测试
2022寒假在家练
MMA
更新2022-03-02
1311

1 项目需求

制作一个本地气象台/温度计

  • 利用OLED显示
  • 显示当前本地的时间、温度和气象信息

2 完成的功能及达到的性能

  • 能够达到项目要求的联网校准时间,获取天气信息,并在屏幕上显示出来的目标。程序的主要实现的功能模块如下图所示。包括:
  • 联网模块:乐鑫公司的ESP32-S2-Mini-1模组内置 ESP32-S2 Wi-Fi MCU 芯片。可以方便的进行联网。乐鑫提供的文档介绍说,这个芯片支持802.11 b/g/n。Bit rate: 802.11n up to 150 Mbps。
  • 校准时间模块:校准时间是用国际标准时间和本地芯片内的时钟时间进行同步。国际标准时间是通过连接ntpserver:pool.ntp.org来实现的。
  • 获取天气模块:网上有免费的和付费的提供天气服务的网站。有的需要注册。这里使用的是有其他人维护好的接口。我们只要调用接口就可以得到返回的天气数据。天气数据主要有json和xml格式的数据。我们这里的程序使用的是json的数据格式。 网络存在的好用的天气接口实际不多,要不就是商用收费的。有些使用比较繁琐。所以另一种方法是自己搭建一个服务器,就是自己做一个天气的接口,给其他的程序调用。
  • 解析天气数据模块:天气数据获取来之后,是json格式的数据。因为使用Arduino编程有常用的库函数进行解析。后面介绍。
  • 屏幕显示模块:这里要找到屏幕的驱动芯片类型。经过查看原理图。屏幕使用128*64 OLED。是6pin的spi接口方式。9经过网络搜索找到对应的驱动程序即可完成功能。
  • 经过以上模块的配合,最后实现了日期,地点,温度,PM2.5,相对湿度,AQI等天气数据的屏幕显示。这些信息只刷新一次。芯片内的时钟和国际时间进行了校准,并能够实时显示在OLED屏幕上。如下图所示。

Fj6UJ9qNUkbPKX8toP8O0r9AUDcW

FoieACtCSryrSU0OubjOAllxSKNA

FoeiNGDoh9_C3igUExj5pXpgzCWV

3 实现思路

  • 使用Arduino平台完成项目。有可用的库函数方便程序的编写。联网方面使用Arduino的wifi模块,采用station模式。可以连接外部网络。
  • 用HTTPClient.h模块负责从pool.ntp.org获取时间数据。ntp有固定的格式。提供固定的参数即可。
  • 用ArduinoJson.h负责解析气象网站返回的json格式的数据。解析回来的格式类似于列表的数据结构。方便在屏幕输出。完成数据准备。
  • 用Adafruit_SSD1306.h负责屏幕的输出。用SSD1306驱动。Adafruit有相关写好的库。

FpgidYlrlhZmldgn5yIB2PFlhzqY

4 实现过程

定义wifi和取时间的时区,我们用东8区。选择夏令时。

const char* ssid = "360_N7";
const char* password =  "myl458724";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600*8;    //时区
const int   daylightOffset_sec = 3600; //夏令时

WiFiClient wifi_Client;
HTTPClient http_client;

配置时间的代码如下:

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); 

 

先用wifi模块进行联网。并反馈到屏幕,联网的状态,获取的IP地址。

 WiFi.mode(WIFI_STA);
    display.println(F("WiFi Con.."));
    display.display();
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        
    }
    display.clearDisplay();
    display.setCursor(0,0); 
    display.println (WiFi.localIP());
    display.display();
    delay(2000);

解析json数据。这里使用C语言的方法。其实列表的数据结构可以在网页上先看一下返回值,然后再看用哪个值在哪一级的列表里。

  DynamicJsonDocument doc(2048);
    deserializeJson(doc, rsp);
    JsonObject obj = doc.as<JsonObject>();

    display.clearDisplay();
    //String city= "Tian Jin";
    String ymd0=obj["data"]["forecast"][0]["ymd"];
    *a=ymd0;
    String wendu0=obj["data"]["wendu"];
    *b=wendu0;
    String shidu0=obj["data"]["shidu"];
    *c=shidu0;
    String pm250=obj["data"]["pm25"];
    *d=pm250;
    String aqi0=obj["data"]["forecast"][0]["aqi"];
    *e=aqi0;

    
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); 
    
}

把解析的结果在屏幕显示出来。这里主要是128*64个位置的控制,注意别超出屏幕的界限。

display.setCursor(0,0); 
    display.print (F("Tian Jin,"));
    display.println (ymd);
    display.print (&timeinfo,"%H:%M:%S");
    display.println ("");
    display.print (F("T:"));
    display.print (wendu);
    display.print (F("C,"));
    display.print (F("Humidity:"));
    display.println (shidu);
    //display.print (F(","));
    display.print (F("PM25:"));
    display.print (pm25);
    display.print (F(","));
    display.print (F("AQI:"));
    display.print (aqi);
    //display.print (F(","));
    display.display();
    delay(1000);
    display.clearDisplay();

5 遇到的主要难题

程序编写因为使用了Arduino平台,有丰富的库函数可用降低了难度。硬件平台还有许多可以尝试的功能。ESP32也是挺强大的处理器,但他的文档主要在IDF的C平台,尤其是linux下的使用。也是后面需要学习的功能。

开始的平台搭建,还是遇到了许多问题,也尝试了不同的平台。最后选择了Arduino。因为这个开发环境能下载到。难点在于新接触的芯片,要有试错学习的过程。

感谢硬禾学堂提供的学习机会。学无止境,越学越不足,看到的越广阔。而不是纸上谈兵,可以实践中体会。

附件下载
weather_local1.zip
团队介绍
我是一名机械工程师,现在在天津工作。参加硬禾学堂的活动,扩展自己的电路技能。
团队成员
MMA
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号