|
|
由于国内的心知天气网站免费API只能提供天气和温度数据,而OpenWeather网站免费API却能提供天气,温度,体感温度,湿度,气压,风速,风向,能见度,云量,日出时间,日落时间。因此我已将心知程序更改为
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);
// 必须设置中文字体!!!你原来没这句,必黑屏重启
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, "风向: %d°", weather.windDeg);
u8g2.drawUTF8(0, 44, degStr);
char windStr[20];
sprintf(windStr, "风速: %.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() {
// 不循环刷新,稳定不卡死
} |
|