简介
在前一段时间淘宝每天签到都能领到2-3 元的券, 于是便用这些券花了仅仅一元多买到了ESP8266的模组。 于是便想着来画一个ESP8266的最小系统来学习以下ESP8266电路的设计。 于是便有了这次的帖子。 在这次的帖子中我将会介绍ESP8266的最小系统,以及如何使用ESP8266 发送HTTPS请求来获取心知天气的API从而来实现一个天气助手的功能。 并且通过串口数据发送到STM32 使其 STM32解析来自8266的串口消息,并且将数据显示到 Oled屏幕上。
正文
市面上有很多常见的模块,我这里选择的是ESP12F的模组。 关于相关的原理图应用我们可以从之前代理ESP32 、 ESP8266模组的安信可社区(链接地址 https://docs.ai-thinker.com/%E8%A7%84%E6%A0%BC%E4%B9%A6)进行下载。

我们可以在上图中下载ESP12F的规格书。之后打开下载好的PDF文件来查看ESP-12F最小系统的应用电路。

我们来分析以下上面的电路,首先VI-IN 被两个电容进行滤波然后通过上拉电阻将REST和EN进行拉高。 下面红色框内的电路则不可用, 可以直接在原理图上设置为NC。在最小电路的右侧则是为串口通讯和下载电路。 RX和TX反接即可和目标单片机完成通讯。 而GPIO0 拉高的时候则可以保证单片机处于工作的模式, 当GPIO0在上电前被拉低的话,则会进入烧录模式, 我们可以在烧录模式进行代码的下载。 其他的比如GPIO15 则按照官方推荐电路连接即可。
官方手册也有对BOOT模式的说明和解释

接下来便来到我们的电路设计, 在我实际的工作测量下, ESP12F的工作时候请求心知天气的时候电流大概在70MA, 普通运行的时候电流在40MA左右。 所以可以直接用总的LDO来进行供电。
下图为使用立创EDA绘制的原理图, 在GPIO0出增加了一个按钮,使其按下的时候当前的电平能够被拉到GND从而保证ESP8266进入下载模式。

PCB的3D渲染图则为以下所示

心知天气介绍
心知天气是中国气象局官方授权的商业气象服务公司,基于气象数值预报和人工智能技术,提供高精度气象数据、天气监控机器人、气象数据可视化产品等。
当我们在心知天气注册账号后我们可以使用心知天气提供的API接口来获取天气数据等。

我们可以在上图的控制台->免费版-> 访问量统计中。 找到免费版支持的API接口。 我们可以点击上图的链接来获取接口的说明信息。

拷贝下图中的密钥信息填充到上文的KEY中

下图便是一个有效的请求,并且得到了响应的JSON数据。 由于使用的是免费版,所有只能请求未来三天的天气预报(虽然API上显示的是五天)

接下来我们便可以通过Arduino IDE来结合WIFI manager , Arduino Json 和 ArduinoHttpClient 和 WiFiClientSecure来发送HTTPS的数据从而实现天气数据的解析。
代码如下
#include <WiFiManager.h>
#include <ArduinoHttpClient.h>
#include <ArduinoJson.h>
#include <WiFiClientSecure.h> // 引入 WiFiClientSecure
char serverAddress[] = "api.seniverse.com"; // 服务器地址
int port = 443; // HTTPS 默认端口
WiFiClientSecure wifi; // 使用 WiFiClientSecure 以支持 HTTPS
HttpClient client = HttpClient(wifi, serverAddress, port);
// 天气状态映射表
const char* weatherMap[][2] = {
{"晴", "Sunny"},
{"多云", "Cloudy"},
{"晴间多云", "Partly Cloudy"},
{"大部多云", "Mostly Cloudy"},
{"阴", "Overcast"},
{"阵雨", "Shower"},
{"雷阵雨", "Thundershower"},
{"雷阵雨伴有冰雹", "Thundershower with Hail"},
{"小雨", "Light Rain"},
{"中雨", "Moderate Rain"},
{"大雨", "Heavy Rain"},
{"暴雨", "Storm"},
{"大暴雨", "Heavy Storm"},
{"特大暴雨", "Severe Storm"},
{"冻雨", "Ice Rain"},
{"雨夹雪", "Sleet"},
{"阵雪", "Snow Flurry"},
{"小雪", "Light Snow"},
{"中雪", "Moderate Snow"},
{"大雪", "Heavy Snow"},
{"暴雪", "Snowstorm"},
{"浮尘", "Dust"},
{"扬沙", "Sand"},
{"沙尘暴", "Duststorm"},
{"强沙尘暴", "Sandstorm"},
{"雾", "Foggy"},
{"霾", "Haze"},
{"风", "Windy"},
{"大风", "Blustery"},
{"飓风", "Hurricane"},
{"热带风暴", "Tropical Storm"},
{"龙卷风", "Tornado"},
{"冷", "Cold"},
{"热", "Hot"},
{"未知", "Unknown"}
};
const char* translateWeather(const char* weather) {
for (size_t i = 0; i < sizeof(weatherMap) / sizeof(weatherMap[0]); i++) {
if (strcmp(weather, weatherMap[i][0]) == 0) {
return weatherMap[i][1];
}
}
return "Unknown"; // 如果没有找到对应的英文翻译
}
void setup() {
Serial.begin(115200);
// 使用 WiFiManager 自动连接
WiFiManager wm;
bool res = wm.autoConnect();
if (!res) {
Serial.println("Failed to connect");
// ESP.restart(); // Uncomment if you want to restart on failure
} else {
Serial.println("Connected... yey :)");
}
// 允许所有证书(如果不想验证证书,调试时可以使用)
wifi.setInsecure(); // 仅用于调试,生产环境中应使用有效证书
}
void loop() {
// 设置要请求的 URL
const char* url = "/v3/weather/daily.json?key=你的密钥&location=shanghai&language=zh-Hans&unit=c&start=0&days=2";
// 开始请求
client.beginRequest();
client.get(url);
client.endRequest();
// 读取响应状态码和响应体
int statusCode = client.responseStatusCode();
String response = client.responseBody();
if (statusCode > 0) {
// 解析 JSON 数据
DynamicJsonDocument doc(2048); // 适当调整大小
DeserializationError error = deserializeJson(doc, response);
if (!error) {
// 提取所需的数据
const char* cityName = doc["results"][0]["location"]["timezone"]; // 使用地点名称
const char* todayWeather = doc["results"][0]["daily"][0]["text_day"];
const char* todayHigh = doc["results"][0]["daily"][0]["high"];
const char* tomorrowWeather = doc["results"][0]["daily"][1]["text_day"];
const char* tomorrowHigh = doc["results"][0]["daily"][1]["high"];
// 将天气从中文翻译成英文
const char* todayWeatherEnglish = translateWeather(todayWeather);
const char* tomorrowWeatherEnglish = translateWeather(tomorrowWeather);
// 格式化输出,确保在每个数据项之间添加逗号
String output = String(cityName) + ", " +
todayWeatherEnglish + ", " +
todayHigh + ", " + // 注意在这里添加逗号
tomorrowWeatherEnglish + ", " +
tomorrowHigh;
// 打印提取的信息到串口
Serial.println(output);
} else {
Serial.print("JSON Parse Error: ");
Serial.println(error.f_str());
}
} else {
Serial.print("HTTP Request failed, status code: ");
Serial.println(statusCode);
}
// 每 10 秒请求一次
delay(10000);
}由于我们使用的是WIFI manager的库, 那么当ESP8266第一次联网的时候将会进入AP模式(Access point), 它会启动一个热点并且等待用户的设备连接,当用户设备连接上去之后便可以进行配网。 当配网成功后 ESP8266会自动记住这个WIFI的连接信息使其在下一次启动的时候搜索到这个WIFI的时候再自动连接。
注意: 你需要提供上述代码中的KEY成你自己的KEY。并且由于是未来三天的天气数据,实际上请求速度过快没有任何意义。可以手动的调整请求的频率等。
由于本文主要是关于ESP8266的最小电路和HTTPS请求,所以实际上数据的解析和显示我将放到下篇文章中进行展示。下篇文章我将展示如何使用STM32解析来自ESP8266的数据并且将数据显示在I2C协议的OLDE屏幕上
我要赚赏金
