简介
在前一段时间淘宝每天签到都能领到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屏幕上