用ESP32-S3和ST7735打造迷你信息站天气、时钟与传感器数据显示实战在物联网和智能家居快速发展的今天嵌入式开发者常常需要一个简单直观的信息展示终端。ESP32-S3凭借其强大的WiFi/BLE双模连接能力和丰富的外设接口配合1.8寸ST7735彩色显示屏可以构建一个功能全面却又小巧精致的桌面信息站。本文将带你从零开始实现一个能够显示实时天气、网络时钟和本地传感器数据的实用设备。1. 硬件准备与环境搭建1.1 硬件组件清单制作这个迷你信息站你需要准备以下硬件ESP32-S3开发板推荐使用带有USB-TypeC接口的版本如ESP32-S3-DevKitC-1ST7735显示屏1.8寸TFT LCD分辨率128x160温湿度传感器DHT22或BME280后者还能测量气压连接线材杜邦线若干电源供应5V/1A USB电源适配器1.2 硬件连接指南ESP32-S3与ST7735的接线方式如下ESP32-S3引脚ST7735引脚备注3.3VVCC电源正极GNDGND电源地线IO12RES复位信号线IO13DC数据/命令选择线IO14CS片选信号线IO1SDASPI数据线(MOSI)IO0SCLSPI时钟线(SCK)IO11BL背光控制可选对于DHT22传感器连接方式更简单ESP32-S3 IO2 — DHT22 DATA 3.3V — VCC GND — GND1.3 开发环境配置首先确保你已经安装了Arduino IDE和必要的开发板支持在Arduino IDE中打开首选项在附加开发板管理器网址中添加https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json通过开发板管理器安装ESP32支持包安装必要的库TFT_eSPI用于驱动ST7735NTPClient用于网络时间同步ArduinoJson用于解析天气API数据DHT sensor library或Adafruit_BME280根据你的传感器选择2. 显示屏驱动与基础UI实现2.1 配置TFT_eSPI库正确配置是驱动ST7735的关键。找到Arduino库文件夹中的TFT_eSPI/User_Setup.h文件进行如下修改#define ST7735_DRIVER #define TFT_WIDTH 128 #define TFT_HEIGHT 160 #define ST7735_GREENTAB3 #define TFT_MOSI 1 // IO1 #define TFT_SCLK 0 // IO0 #define TFT_CS 14 // IO14 #define TFT_DC 13 // IO13 #define TFT_RST 12 // IO12 #define SPI_FREQUENCY 270000002.2 基础显示功能实现创建一个基本的显示框架包含以下元素#include TFT_eSPI.h TFT_eSPI tft TFT_eSPI(); void setup() { tft.init(); tft.setRotation(3); // 根据你的安装方向调整 tft.fillScreen(TFT_BLACK); // 绘制顶部状态栏 tft.fillRect(0, 0, 128, 20, TFT_NAVY); tft.setTextColor(TFT_WHITE, TFT_NAVY); tft.drawString(Info Station, 5, 5, 2); // 主显示区域划分 tft.drawFastHLine(0, 25, 128, TFT_WHITE); } void loop() { // 后续内容将在这里添加 }2.3 字体与图形优化ST7735虽然小巧但通过合理使用字体和图形元素可以大幅提升显示效果// 在setup()中添加字体设置 tft.loadFont(NotoSansBold20); // 需要先通过工具转换字体 // 绘制一个带阴影的按钮效果 void drawButton(int x, int y, int w, int h, String text) { tft.fillRoundRect(x, y, w, h, 5, TFT_DARKGREEN); tft.fillRoundRect(x2, y2, w, h, 5, TFT_GREEN); tft.setTextColor(TFT_WHITE, TFT_GREEN); tft.drawString(text, x10, y8, 2); }3. 网络功能实现3.1 WiFi连接与时间同步可靠的网络连接是获取天气和同步时间的基础#include WiFi.h #include NTPClient.h #include WiFiUdp.h const char* ssid your_SSID; const char* password your_PASSWORD; WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, pool.ntp.org, 8*3600, 60000); void connectToWiFi() { tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.drawString(Connecting WiFi..., 5, 30, 2); WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); tft.drawString(., 110, 30, 2); } tft.fillRect(5, 30, 120, 20, TFT_BLACK); tft.drawString(WiFi Connected!, 5, 30, 2); delay(1000); timeClient.begin(); timeClient.update(); }3.2 天气数据获取使用免费的天气API获取实时数据以OpenWeatherMap为例#include HTTPClient.h #include ArduinoJson.h String getWeatherData() { if(WiFi.status() ! WL_CONNECTED) return ; HTTPClient http; String url http://api.openweathermap.org/data/2.5/weather?qBeijingunitsmetricappidYOUR_API_KEY; http.begin(url); int httpCode http.GET(); if(httpCode HTTP_CODE_OK) { String payload http.getString(); DynamicJsonDocument doc(1024); deserializeJson(doc, payload); float temp doc[main][temp]; int humidity doc[main][humidity]; String weather doc[weather][0][main]; return weather String(temp,1) C String(humidity) %; } return ; }4. 传感器数据采集与显示4.1 温湿度传感器集成以DHT22为例实现环境数据采集#include DHT.h #define DHTPIN 2 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); void setupSensors() { dht.begin(); } String readDHTData() { float h dht.readHumidity(); float t dht.readTemperature(); if (isnan(h) || isnan(t)) { return Sensor Error; } return In: String(t,1) C String(h,0) %; }4.2 多数据源整合显示创建一个统一的显示更新函数合理安排屏幕空间void updateDisplay() { static unsigned long lastUpdate 0; if(millis() - lastUpdate 5000) return; // 5秒更新一次 lastUpdate millis(); // 清空主显示区域 tft.fillRect(0, 26, 128, 134, TFT_BLACK); // 显示时间 timeClient.update(); String timeStr timeClient.getFormattedTime().substring(0,5); tft.setTextColor(TFT_YELLOW, TFT_BLACK); tft.drawString(timeStr, 5, 35, 4); // 显示日期 String dateStr String(timeClient.getDay()) / String(timeClient.getMonth()); tft.drawString(dateStr, 5, 65, 2); // 显示天气 String weather getWeatherData(); tft.setTextColor(TFT_CYAN, TFT_BLACK); tft.drawString(weather, 5, 90, 2); // 显示室内数据 String sensorData readDHTData(); tft.setTextColor(TFT_GREEN, TFT_BLACK); tft.drawString(sensorData, 5, 110, 2); // 显示WiFi信号强度 int rssi WiFi.RSSI(); tft.drawString(WiFi: String(rssi) dBm, 5, 130, 1); }5. 高级功能与优化5.1 低功耗优化虽然作为桌面设备不需要特别考虑功耗但良好的电源管理仍是好习惯void powerManagement() { // 夜间自动降低亮度 int hour timeClient.getHours(); if(hour 22 || hour 7) { analogWrite(11, 50); // 低亮度 } else { analogWrite(11, 255); // 全亮度 } // 长时间无操作进入深度睡眠 static unsigned long lastActive millis(); if(millis() - lastActive 3600000) { // 1小时无操作 esp_sleep_enable_timer_wakeup(3600 * 1000000); // 1小时后唤醒 esp_deep_sleep_start(); } }5.2 用户交互设计添加简单的按钮交互功能#define BUTTON_PIN 3 void checkUserInput() { static bool lastState HIGH; bool currentState digitalRead(BUTTON_PIN); if(lastState HIGH currentState LOW) { // 按钮按下切换显示模式 static int displayMode 0; displayMode (displayMode 1) % 3; switch(displayMode) { case 0: // 默认模式 // ...更新显示... break; case 1: // 详细天气模式 // ...显示更多天气细节... break; case 2: // 传感器历史数据 // ...显示最近几小时的数据变化... break; } } lastState currentState; }5.3 数据持久化与趋势分析利用ESP32-S3的RTC内存存储短期数据观察变化趋势struct SensorHistory { float temp[24]; float humidity[24]; int index; }; RTC_DATA_ATTR SensorHistory history; void updateHistory() { float t dht.readTemperature(); float h dht.readHumidity(); history.temp[history.index] t; history.humidity[history.index] h; history.index (history.index 1) % 24; } void drawHistoryGraph() { // 绘制温度变化曲线 int baseY 80; int lastX 10, lastY baseY - history.temp[0]; for(int i1; i24; i) { int x 10 i*5; int y baseY - history.temp[i]; tft.drawLine(lastX, lastY, x, y, TFT_RED); lastX x; lastY y; } // 类似方法绘制湿度曲线... }6. 外壳设计与最终组装虽然代码功能已经完备但一个精美的外壳能让项目更加完美3D打印外壳使用PLA材料打印一个紧凑的外壳留出显示屏开口和散热孔电源管理添加一个锂电池充放电模块实现断电保护防眩光处理在显示屏表面加装防眩光膜改善可视性磁吸底座在外壳底部嵌入磁铁方便吸附在金属表面最终你将拥有一个功能全面、外观专业的桌面信息站能够实时显示网络同步的精确时间当地天气状况和预报室内环境温湿度数据WiFi连接状态历史数据趋势图这个项目不仅实用还展示了ESP32-S3强大的处理能力和丰富的外设接口以及如何通过精心设计在小尺寸屏幕上呈现丰富信息。你可以进一步扩展功能比如添加空气质量监测、日历事件提醒等打造属于你的个性化信息中心。