用RP2040 Game Kit板与ESP32实现简易气象站
2022暑假在家一起练-用RP2040 Game Kit板与ESP32实现简易气象站
标签
嵌入式系统
网络与通信
ESP32
树莓派RP2040
MDYi
更新2022-09-06
北京交通大学
925

0.目录

  1. 项目要求

  2. 实现功能

  3. 项目分析

  4. 天气服务

  5. ESP32开发

  6. RP2040开发

  7. 成果展示

  8. 心得体会

  9. 附件

 

1.项目要求

制作一个简单的气象台,能够实时播放5个城市的气象信息。

 

2.实现功能

  • RP2040 Game Kit板通过提供的ESP32-S2的WiFi模块连接网络

  • 在RP2040 Game Kit上显示某一个城市的气象信息 - 时间、温度、湿度、气压....

  • 通过RP2040 Game Kit上的按键能够切换显示不同城市的信息 ,比如:上海、苏州、东京、洛杉矶、伦敦

 

3.项目分析

RP2040本身不具备联网功能,需利用ESP32-S2模块实现互联网访问,RP2040 Game Kit与ESP32-S2通过串口进行数据传输。天气服务使用和风天气,和风天气相较于目前主流的心知天气可以免费获得更多的天气数据。

 

4.天气服务

和风天气(实时天气 - API | 和风天气开发平台 (qweather.com))中的实时天气API文档对API接口进行了详细介绍。可以注册一个免费开发版账号,然后上传身份证后升级为开发者版本,API访问量即可达到16700次/天,即11.6次/分,完全可以满足我们的项目需要。

FqNCPcv_UGbY6nUsQNHrwj6GcWSY

和风天气的API请求URL为(https://devapi.qweather.com/v7/weather/now?[请求参数]),文档中请求参数与keylocationlangunit共四项,其中keylocation为必选项,将语言lang设为英文en方便后续处理,单位unit为公制单位。

注意:实际使用中由于V7版本默认对返回数据进行了压缩,需要再添加一项禁止压缩的参数gzip=n,否则后续ESP32无法处理。

返回数据如下,实况数据均为近实时数据,相比真实的物理世界会5-20分钟的延迟。

// 北京实况天气 
// 商业版 https://api.qweather.com/v7/weather/now?location=101010100&key=你的KEY
// 开发版 https://devapi.qweather.com/v7/weather/now?location=101010100&key=你的KEY
​
{
  "code": "200",
  "updateTime": "2020-06-30T22:00+08:00",
  "fxLink": "http://hfx.link/2ax1",
  "now": {
    "obsTime": "2020-06-30T21:40+08:00",
    "temp": "24",
    "feelsLike": "26",
    "icon": "101",
    "text": "多云",
    "wind360": "123",
    "windDir": "东南风",
    "windScale": "1",
    "windSpeed": "3",
    "humidity": "72",
    "precip": "0.0",
    "pressure": "1003",
    "vis": "16",
    "cloud": "10",
    "dew": "21"
  },
  "refer": {
    "sources": [
      "QWeather",
      "NMC",
      "ECMWF"
    ],
    "license": [
      "commercial license"
    ]
  }
}

下表为返回数据含义。

code API状态码,具体含义请参考状态码 updateTime 当前API的最近更新时间 fxLink 当前数据的响应式页面,便于嵌入网站或应用 now.obsTime 数据观测时间 now.temp 温度,默认单位:摄氏度 now.feelsLike 体感温度,默认单位:摄氏度 now.icon 天气状况和图标的代码,图标可通过天气状况和图标下载 now.text 天气状况的文字描述,包括阴晴雨雪等天气状态的描述 now.wind360 风向360角度 now.windDir 风向 now.windScale 风力等级 now.windSpeed 风速,公里/小时 now.humidity 相对湿度,百分比数值 now.precip 当前小时累计降水量,默认单位:毫米 now.pressure 大气压强,默认单位:百帕 now.vis 能见度,默认单位:公里 now.cloud 云量,百分比数值。可能为空 now.dew 露点温度。可能为空 refer.sources 原始数据来源,或数据源说明,可能为空 refer.license 数据许可或版权声明,可能为空

code API状态码,具体含义请参考状态码 updateTime 当前API的最近更新时间 fxLink 当前数据的响应式页面,便于嵌入网站或应用 now.obsTime 数据观测时间 now.temp 温度,默认单位:摄氏度 now.feelsLike 体感温度,默认单位:摄氏度 now.icon 天气状况和图标的代码,图标可通过天气状况和图标下载 now.text 天气状况的文字描述,包括阴晴雨雪等天气状态的描述 now.wind360 风向360角度 now.windDir 风向 now.windScale 风力等级 now.windSpeed 风速,公里/小时 now.humidity 相对湿度,百分比数值 now.precip 当前小时累计降水量,默认单位:毫米 now.pressure 大气压强,默认单位:百帕 now.vis 能见度,默认单位:公里 now.cloud 云量,百分比数值。可能为空 now.dew 露点温度。可能为空 refer.sources 原始数据来源,或数据源说明,可能为空 refer.license 数据许可或版权声明,可能为空。

 

5.ESP32开发

ESP32使用Arduino进行开发,创建工程后安装ArduinoJson库(本工程为6.19.4版本)对返回的数据进行解析。

FoSSMBBD5yEkD_eJW4xH3_16LRUT

wifi连接代码如下。

WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.print(".");
  }
Serial.println("");
Serial.println("WiFi connected");

获取天气数据代码如下。

void getLivesWratherData(HeFengCurrentData *data, String city)
{
    std::unique_ptr<WiFiClientSecure> client(new WiFiClientSecure);
    client->setInsecure();
    HTTPClient https;
    String url = getUrl(privateKey, city);
    if (https.begin(*client, url))
    {
        int httpCode = https.GET();
        if (httpCode > 0)
        {
            if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY)
            {
                String respone = https.getString();
                deserializeWeatherData(data, respone, city);
            }
        }
        else
        {
            Serial.printf("[HTTPS] GET... failed, error: %s\r\n", https.errorToString(httpCode).c_str());
        }
        https.end();
    }
    else
    {
        Serial.printf("[HTTPS] Unable to connect\r\n");
    }
}

由于和风天气API不能返回实时天气,还需要通过NTP服务器对实时时间进行获取。

NTP服务器选择CN.NTP.ORG.CN,NTP服务器与很多,可以通过以下网页查看NTP服务器(公共 NTP 网络时间服务器地址大全 Public NTP Server - DNS.iCoA.CN),其返回数据格式基本一致。

NTP服务器配置代码。

// NTP授时服务器
const char *ntpServer = "CN.NTP.ORG.CN"; // NTP server
const long gmtOffset_sec = 8 * 3600;     // GMT offset in seconds
const int daylightOffset_sec = 0;        // daylight saving offset in seconds

// 配置NTP服务器
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

获取到的时间和天气数据通过串口1进行发送,波特率115200bits/s,通信协议如下。

内容长度(字节)备注帧起始标志1固定为0x00年1从1900年开始月1范围[0,11]日1范围[1,31]时1范围[0,23]分1范围[0,59]秒1范围[0,59]星期1范围[0,6](周日为第一天)城市代码4行政区划代码温度1单位:摄氏度体感温度1单位:摄氏度天气2天气图标代码风向2风向360角度风力1风力等级风速1单位:公里/小时湿度1相对湿度,百分比数值降水量4当前小时累计降水量,单位:毫米气压2单位:百帕能见度1单位:公里云量1百分比数值露点温度1可能为空帧结束标志1固定为0xFF

ESP32接收到城市代码后进行一次天气与时间更新,接收的数据帧格式见RP2040开发部分。

ESP32上传固件时需要先按住BOOT再连接至电脑,或者按住BOOT再按下RST。

 

6.RP2040开发

RP2040使用PlatformIO进行开发,开发板选择Raspberry Pi Pico,安装TFT_eSPI库(本工程为2.4.30版本)进行屏幕驱动,具体配置见代码附件。

RP2040使用串口1,配置为16与17引脚(在pins_arduino.h文件中配置)。

// Serial
#define PIN_SERIAL_TX (16u)
#define PIN_SERIAL_RX (17u)

RP2040在每次按下按键时进行按键中断,中断后更改目前的城市代码,并发送一次请求给ESP32,发送请求的代码如下。

void requestWeatherData(int cityCode)
{
    itoa(cityCode, txBuf, 10);
    txBuf[9] = '\r';
    txBuf[10] = '\n';
    Serial1.println(txBuf);
}

RP2040每5分钟自动请求一次天气与时间数据,对本地时间进行校准,同时刷新天气数据。

由于进行全局刷新屏幕会有闪烁现象,因此采用局部刷新方式,设立以下标志位,只有当数据发生变化时将标志位置1,局部刷新后将标志位重新置0。

//局部刷新标志位
bool flag_refreshSec = false;
bool flag_refreshMin = false;
bool flag_refreshHour = false;
bool flag_refreshDay = false;
bool flag_refreshMonth = false;
bool flag_refreshYear = false;
bool flag_refreshWeek = false;
bool flag_refreshWeather = false;
bool flag_refreshHumidity = false;
bool flag_refreshTemp = false;
bool flag_refreshPressure = false;
bool flag_refreshCity = false;

RP2040的BOOT键与按键B复用,按住BOOT后重启进入烧录模式。

需要注意的是,RP2040的后方连接排针后下角为1脚。

FvybZL6jzWWKlIB_056dj4Gr8qN9

 

7.成果展示

实物如图所示。

FuuMzljSIl4OcYmkRUKkl69npWPb

 

8.心得体会

  • ESP32使用PlatformIO开发体验较好,相较于Arduino功能更加完善。

  • RP2040使用microPython的开发效率比较低,因此选择了C++。

  • 和风天气的免费版数据更加全面,API访问次数虽有限制,但仍可以满足需求,相较于和风天气与高德天气API使用体验更好。

  • RP2040的按键未做消抖,有时候会发生误触。

 

9.附件

附件见百度网盘

链接:https://pan.baidu.com/s/1RsR1okFQ2NftGWrr_i66CQ?pwd=sqfk 
提取码:sqfk

团队介绍
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号