使用ESP8266的天气预报显示
不管是深圳还是香港,一到夏天就没命的下雨,说来就来的雨又说停就停。让人觉得整个岭南地区是不是就只分旱季和雨季。
于是就想有个分钟级的天气预报,普通的app还得用看手机,因为工作的原因,有时候会很久都碰不到手机。于是祭出了吃灰一段时间的ESP8266,自己写一个分钟级的天气检测。
硬件:
ESP8266,带0.91英寸屏幕(128x32,heltec版本)
软件:
Arduino IDE,ArduinoJson
考虑到ESP8266性能太弱,爬网页拿天气数据不太现实,所以就直接用API。最开始用的是高德地图提供的,但是有几个缺点:
- 30分钟更新一次
- 最小提供区域是区级
- 根本不准
于是就去找专业公司,彩云和和风都可以并且免费提供一定的额度。其中,彩云的审核是人工的,当时急着做就直接用和风的api了,正在更新博客的时候收到邮件通知彩云通过审核了。和风的有以下特点:
- api限制是每日1000次
- 支持经纬度
- 实时天气
- 数据信息更全
放图,看一下最终的效果。第一行是天气信息,第二行分别是温度和降水量。
源码
附上源代码,万一有其他人要用。折腾json就花了半天的功夫,c++在便捷性上确实有点拉跨。
/**
Weather OLED
Created on: June 7, 2020
copyright@PA.CI
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include <ESP8266WiFiMulti.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include "heltec.h" // alias for `#include "SSD1306Wire.h"`
const uint8_t fingerprint[20] = {0x02, 0x5f, 0x4b, 0xea, 0x55, 0xb5, 0x64, 0xda, 0xd8, 0xc9, 0xc9, 0x78, 0x0e, 0x3C, 0x7d, 0xd5, 0xe3, 0x8f, 0xe9, 0x4f};
ESP8266WiFiMulti WiFiMulti;
void setup() {
Serial.begin(115200);
for (uint8_t t = 4; t > 0; t--) {
// Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("ssid", "passwd");
}
void loop() {
if ((WiFiMulti.run() == WL_CONNECTED)) {
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setFingerprint(fingerprint);
HTTPClient https;
// Serial.print("[HTTPS] begin...\n");
if (https.begin(*client, "key and parameters")) { // api for the weather and key, parameters
// Serial.print("[HTTPS] GET...\n");
int httpCode = https.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
// Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
// Serial.println(payload);
//go to https://arduinojson.org/v6/assistant/ for modify
const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(8) + JSON_OBJECT_SIZE(13) + 350;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, payload);
String precipitation = doc["HeWeather6"][0]["now"]["pcpn"].as<char*>();
String weather = doc["HeWeather6"][0]["now"]["cond_txt"].as<char*>();
String temperate = doc["HeWeather6"][0]["now"]["tmp"].as<char*>();
// Serial.print(precipitation);
// Serial.print(weather);
// OLED screen
Heltec.begin(true /*DisplayEnable Enable*/, true /*Serial Enable*/);
Heltec.display->init();
Heltec.display->flipScreenVertically();
Heltec.display->setFont(ArialMT_Plain_10);
Heltec.display->drawString(15, 2, weather);
Heltec.display->drawString(15, 17, temperate + "C" + " " + precipitation + "mm");
Heltec.display->display();
// Serial.println();
}
} else {
// Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
https.end();
} else {
// Serial.printf("[HTTPS] Unable to connect\n");
}
}
// Serial.println("Wait 10min before next round...");
delay(600000);
}
楼主牛啊,全是干活,我想采集了。万一哪天倒了,我还能看
不可能!我是不可能倒闭的!
1