|
|
由于國內(nèi)的心知天氣網(wǎng)站免費(fèi)API只能提供天氣和溫度數(shù)據(jù),而OpenWeather網(wǎng)站免費(fèi)API卻能提供天氣,溫度,體感溫度,濕度,氣壓,風(fēng)速,風(fēng)向,能見度,云量,日出時(shí)間,日落時(shí)間。因此我已將心知程序更改為
OpenWeather程序:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <SPI.h>
#include <dht11.h>
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 5, /* data=*/4, /* reset=*/ U8X8_PIN_NONE);
//使用ST7920顯示
dht11 DHT11;
#define DHT11PIN 14
const char* ssid = "******"; //你的WIFI名稱
const char* password = "******"; //你的WIFI密碼
const char* host = "api.openweathermap.org"; //你的API密鑰
const char* apiKey = "******";
const char* city = "Beijing";
WiFiClient client;
struct Weather {
float temp;
float feelsLike;
int humidity;
float pressure;
float windSpeed;
int windDeg;
String weather;
};
Weather weather;
// 英文天氣 → 中文
String weatherToCN(String en) {
if (en == "Clear") return "晴天";
if (en == "Clouds") return "多云";
if (en == "Rain") return "下雨";
if (en == "Drizzle") return "毛毛雨";
if (en == "Thunderstorm")return "雷暴";
if (en == "Snow") return "下雪";
if (en == "Mist") return "薄霧";
if (en == "Fog") return "大霧";
if (en == "Haze") return "霧霾";
return en;
}
float getValue(String json, String key) {
int idx = json.indexOf(key);
if (idx == -1) return -999;
return json.substring(idx + key.length()).toFloat();
}
String getWeatherMain(String json) {
int idx = json.indexOf("\"main\":\"");
if (idx == -1) return "N/A";
int end = json.indexOf("\"", idx + 8);
return json.substring(idx + 8, end);
}
void parseWeather(String json) {
weather.temp = getValue(json, "\"temp\":");
weather.feelsLike = getValue(json, "\"feels_like\":");
weather.humidity = getValue(json, "\"humidity\":");
weather.pressure = getValue(json, "\"pressure\":");
weather.windSpeed = getValue(json, "\"speed\":");
weather.windDeg = getValue(json, "\"deg\":");
weather.weather = getWeatherMain(json);
}
void getWeather() {
if (!client.connect(host, 80)) {
Serial.println("連接失敗");
return;
}
String url = "/data/2.5/weather?q=" + String(city)
+ "&appid=" + apiKey
+ "&units=metric";
client.print("GET " + url + " HTTP/1.1\r\n"
"Host: " + String(host) + "\r\n"
"Connection: close\r\n\r\n");
delay(100);
String res = client.readStringUntil('\0');
parseWeather(res);
client.stop();
}
// ==================== ST7920 顯示 ====================
void showWeatherOnOLED() {
u8g2.clearBuffer();
u8g2.setContrast(255);
// 必須設(shè)置中文字體!!!你原來沒這句,必黑屏重啟
u8g2.setFont(u8g2_font_wqy12_t_gb2312a);
int chk = DHT11.read(DHT11PIN);
int t= (float)DHT11.temperature;
int h=(float)DHT11.humidity;
u8g2.drawUTF8(0, 12, "天氣: ");
u8g2.drawUTF8(32, 12, weatherToCN(weather.weather).c_str());
char tempStr[20];
sprintf(tempStr, "溫度: %.0f %C", weather.temp);
u8g2.drawUTF8(70, 12, tempStr);
char humiStr[20];
sprintf(humiStr, "濕度: %d %%", weather.humidity);
u8g2.drawUTF8(0, 28, humiStr);
char feelStr[20];
sprintf(feelStr, "體感: %.0f %C", weather.feelsLike);
u8g2.drawUTF8(70, 28, feelStr);
char degStr[20];
sprintf(degStr, "風(fēng)向: %d°", weather.windDeg);
u8g2.drawUTF8(0, 44, degStr);
char windStr[20];
sprintf(windStr, "風(fēng)速: %.0f %M", weather.windSpeed);
u8g2.drawUTF8(70, 44, windStr);
u8g2.drawUTF8(0, 60, "室溫: C");
u8g2.setCursor(32,60);
u8g2.print(t);
u8g2.drawUTF8(70, 60, "濕度: %");
u8g2.setCursor(102,60);
u8g2.print(h);
u8g2.sendBuffer();
delay(10000);
digitalWrite(15, LOW);
digitalWrite(13, LOW);
}
void setup() {
Serial.begin(115200);
u8g2.begin();
pinMode(15, OUTPUT);
digitalWrite(15, HIGH);
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
u8g2.clearBuffer();
u8g2.setContrast(255);
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.drawUTF8(0, 40, "OpenWeather");
u8g2.sendBuffer();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi 已連接");
getWeather();
Serial.println("===== 天氣 =====");
Serial.println("天氣: " + weatherToCN(weather.weather));
Serial.printf("溫度: %.1f°C\n", weather.temp);
Serial.printf("體感: %.1f°C\n", weather.feelsLike);
Serial.printf("濕度: %d%%\n", weather.humidity);
showWeatherOnOLED();
}
void loop() {
// 不循環(huán)刷新,穩(wěn)定不卡死
} |
|