本次选择的是任务二:
制作一个自动联网的天气预报仪,在设计界面显示温湿度、天气情况、空气质量以及未来三天内的天气变化。
简介:
本项目的主要功能是自动连接到网络上OpenWeather提供的天气API,获取到天气数据,再对获取到的数据进行JSON解析,将数据显示到屏幕上。项目功能简洁,工作稳定,可长时间工作。
硬件介绍:
Wio Terminal 是基于SAMD51的微控制器,具有 Realtek RTL8720DN 支持的无线连接,与Arduino和MicroPython兼容。它的运行速度为 120MHz (最高可达200MHz), 4MB 外部闪存和 192KB RAM。它同时支持蓝牙和Wi-Fi,为物联网项目提供了骨架。Wio Terminal自身配有 a 2.4” LCD屏幕, 板载IMU(LIS3DHTR),麦克风,蜂鸣器,microSD卡槽,光传感器和红外发射器(IR 940nm)。 最重要的是它还有两个用于Grove生态系统 的多功能Grove端口和40个Raspberry pi兼容的GPIO引脚,用于支持更多附加组件。
主要功能介绍:
1、使用rpcWiFi和HTTPClient库,通过访问Openweather的API获取天气数据。
2、通过ArduinoJson库解析获取到的天气数据,得到温湿度、天气情况、空气质量以及未来三天内的天气信息。
3、使用TFT_eSPI库,将数据显示到屏幕上。
关键性代码及说明:
1、依赖的库
ArduinoJson
Seeed Arduino FS
Seeed Arduino rpcUnified
Seeed Arduino rpcWiFi
Seeed Arduino SFUD
Seeed_Arduino_LCD
Seeed_Arduino_mbedtls
2、发送网络请求,获取JSON数据
String NETWorkGetJSON(String API)
{
HTTPClient http;
String payload;
Serial.print("[HTTP] begin...\n");
//tft.setFreeFont(&FreeSansBoldOblique12pt7b); //select Free, Sans, Bold, Oblique, 12pt.
//tft.drawString("Begin", 70, 80);
// configure traged server and url
http.begin(API);
Serial.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0)
{
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK)
{
payload = http.getString();
//Serial.println(payload);
}
}
else
{
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
return payload;
}
3、JSON解析数据
DynamicJsonDocument doc_current(600);
deserializeJson(doc_current, payloadCurrentJSON);
// 获取天气状况
JsonArray weather_A = doc_current["weather"];
JsonObject weather = weather_A[0];
const char* icon_current = weather["icon"];
Serial.println(icon_current);
const char* description_current = weather["description"];
Serial.println(description_current);
// 获取温湿度
JsonObject main = doc_current["main"];
float temp_current = main["temp"];
Serial.println(temp_current);
float humidity_current = main["humidity"];
Serial.println(humidity_current);
float temp_max = main["temp_max"];
Serial.println(temp_max);
float temp_min = main["temp_min"];
Serial.println(temp_min);
// 空气质量
DynamicJsonDocument doc_AQI(600);
deserializeJson(doc_AQI, payloadAQIJSON);
// 获取空气质量
JsonArray list_AQI = doc_AQI["list"];
JsonObject list_A = list_AQI[0];
JsonObject list_main = list_A["main"];
int main_aqi= list_main["aqi"];
Serial.println(main_aqi);
// 未来三天天气
deserializeJson(doc_Forecast, payloadForecastJSON);
DISPAYForecastData(9); // 第一天
DISPAYForecastData(17); // 第二天
DISPAYForecastData(25); // 第三天
4、显示数据
// 温度
tft.setFreeFont(FSB24);
tft.drawString(String(int(temp_current)), 0, 0);
tft.setFreeFont(FSB12);
tft.drawString("C", 48, 12);
// 湿度
tft.setFreeFont(FSB18);
tft.drawString(String(int(humidity_current)), 12, 48);
tft.setFreeFont(FSB9);
tft.drawString("%", 48, 60);
// 天气图标
//tft.setFreeFont(FSB24);
//tft.drawString(icon_current, 250, 0);
drawImage<uint16_t>(String(String("W_")+String(icon_current)+String(".bmp")).c_str(), 250, 0);
tft.setFreeFont(FSB9);
String temp = String(description_current);
//tft.drawString(temp, 300-temp.length()*9, 40);
// 最高和最低气温
tft.setFreeFont(FSB9);
temp = String(int(temp_min))+String("C ~")+String(int(temp_max))+String("C");
tft.drawString(temp, 300-temp.length()*9, 60);
// 空气质量
ShowWeatherAQI(100, 10, main_aqi);
// 未来三天的天气
DISPAYForecastData( 9); // 第一天
DISPAYForecastData(17); // 第二天
DISPAYForecastData(25); // 第三天
功能演示结果:
将Wio Terminal通过TYPE-C数据线连接到电源上后,会自动连接到WiFi上,然后获取对应的天气数据。
总结:
这次参加Funpack的活动,收货满满的。。得益于Arduino中丰富的库函数,总体来说源码方面的开发还是比较轻松的。难度比较大的是JSON数据的解析和显示中文的问题,后面参考了提供的案例,慢慢的也调试出来了,最终也顺利的完成了项目。