当前位置: 首页 > news >正文

用ESP32和0.96寸OLED做个桌面小摆件:实时显示天气/时间(附完整源码)

用ESP32和0.96寸OLED打造智能桌面天气时钟(附完整项目源码)

在创客圈里,ESP32和OLED屏幕的组合堪称经典CP。今天我们就来玩点实用的——用这两样小东西做个能显示天气和时间的桌面摆件。这可不是简单的"Hello World"级别项目,而是一个融合了Wi-Fi联网、API调用、NTP时间同步等实用技术的完整解决方案。

1. 硬件准备与电路连接

先来看看我们需要哪些硬件材料:

  • ESP32开发板(推荐使用NodeMCU-32S,自带USB转串口)
  • 0.96寸OLED显示屏(SSD1306驱动,I2C接口)
  • 微型面包板和杜邦线若干
  • USB电源线(供电兼下载程序用)

接线示意图

ESP32 OLED 3.3V --- VCC GND --- GND GPIO22 --- SCL GPIO21 --- SDA

注意:不同型号的OLED屏引脚定义可能略有差异,购买时请确认是I2C接口的4针版本(VCC、GND、SCL、SDA)

实际连接时,建议先用万用表检查线路通断。我遇到过好几次因为杜邦线接触不良导致的显示异常,排查起来特别费时间。

2. 开发环境搭建

我们使用PlatformIO作为开发环境,它比Arduino IDE更适合管理依赖库。以下是具体配置步骤:

  1. 安装VSCode和PlatformIO插件
  2. 新建ESP32项目,修改platformio.ini配置文件:
[env:nodemcu-32s] platform = espressif32 board = nodemcu-32s framework = arduino lib_deps = adafruit/Adafruit SSD1306@^2.5.7 adafruit/Adafruit GFX Library@^1.11.3 bblanchon/ArduinoJson@^6.19.4
  1. 安装必要的库:
pio lib install "Adafruit SSD1306" pio lib install "ArduinoJson"

3. 核心代码实现

项目主要分为三个功能模块:OLED驱动、时间同步和天气获取。我们先从最基础的OLED显示开始。

3.1 OLED显示基础

创建oled_display.h头文件,初始化显示驱动:

#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void initOLED() { if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println("OLED分配失败"); for(;;); } display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.display(); }

3.2 时间同步功能

ESP32可以通过NTP协议获取网络时间,首先需要连接WiFi:

#include <WiFi.h> #include <NTPClient.h> #include <WiFiUdp.h> const char* ssid = "你的WiFi名称"; const char* password = "你的WiFi密码"; WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "pool.ntp.org", 8*3600, 60000); void connectWiFi() { WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } timeClient.begin(); } String getFormattedTime() { timeClient.update(); return timeClient.getFormattedTime(); }

3.3 天气数据获取

我们使用和风天气的免费API获取实时天气数据:

#include <HTTPClient.h> #include <ArduinoJson.h> String apiKey = "你的API密钥"; String cityID = "城市ID"; String getWeatherData() { HTTPClient http; String url = "http://api.heweather.net/s6/weather/now?location=" + cityID + "&key=" + apiKey; http.begin(url); int httpCode = http.GET(); if(httpCode == HTTP_CODE_OK) { String payload = http.getString(); DynamicJsonDocument doc(1024); deserializeJson(doc, payload); String weather = doc["HeWeather6"][0]["now"]["cond_txt"].as<String>(); String temp = doc["HeWeather6"][0]["now"]["tmp"].as<String>(); return weather + " " + temp + "°C"; } return "获取失败"; }

4. 功能整合与界面设计

现在我们把各个模块整合起来,设计一个简洁的显示界面:

void displayInfo() { display.clearDisplay(); // 顶部状态栏 display.setCursor(0, 0); display.print(getFormattedTime()); // 中间大字体显示日期 display.setTextSize(2); display.setCursor(0, 20); display.print("2023-07-15"); // 底部天气信息 display.setTextSize(1); display.setCursor(0, 50); display.print(getWeatherData()); display.display(); } void setup() { Serial.begin(115200); initOLED(); connectWiFi(); } void loop() { displayInfo(); delay(60000); // 每分钟更新一次 }

5. 进阶优化技巧

基础功能实现后,我们可以进一步优化用户体验:

5.1 多页面切换

通过按钮实现不同信息页面的切换:

#define BUTTON_PIN 0 int page = 0; void checkButton() { if(digitalRead(BUTTON_PIN) == LOW) { page = (page + 1) % 3; delay(200); // 防抖 } } void displayPage() { switch(page) { case 0: displayClock(); break; case 1: displayWeather(); break; case 2: displaySensorData(); break; } }

5.2 添加传感器数据

连接BME280传感器,显示温湿度:

#include <Adafruit_BME280.h> Adafruit_BME280 bme; void initBME280() { if (!bme.begin(0x76)) { Serial.println("找不到BME280传感器!"); } } String getSensorData() { return String(bme.readTemperature()) + "°C " + String(bme.readHumidity()) + "%"; }

5.3 低功耗优化

对于电池供电的场景,可以启用ESP32的深度睡眠模式:

void deepSleep() { esp_sleep_enable_timer_wakeup(60 * 1000000); // 睡眠60秒 esp_deep_sleep_start(); }

6. 外壳设计与成品展示

一个精致的项目少不了合适的外壳。这里分享几种常见方案:

  1. 3D打印外壳:使用FreeCAD或Tinkercad设计,预留屏幕开口和按钮孔位
  2. 亚克力拼接:激光切割亚克力板,用胶水粘合成立方体
  3. 创意改造:利用现成的相框或小盒子改造

材料清单

  • 3D打印耗材/亚克力板
  • M2螺丝螺母套装
  • 微型按键开关
  • 防滑硅胶垫

最后完成的摆件可以放在书桌、床头或办公室,既实用又彰显极客气质。整个项目的物料成本不超过100元,但获得的成就感和实用价值远超这个数字。

http://www.cnnetsun.cn/news/2003304.html

相关文章:

  • 别再调参了!用Simulink自带的DC Motor模型,5步搞定直流有刷电机双闭环PID仿真
  • FlexSim 19.2 多品种订单拣选:用Process Flow搞定那个让人头疼的‘动态匹配’逻辑
  • 告别密码:用Xshell和OpenSSH在Windows 10/11上搭建安全的SSH密钥隧道
  • 爱加密与腾讯Rightly:全面安全卫士与隐私合规专家的深度对比
  • 2025届最火的五大AI辅助写作工具解析与推荐
  • SystemUI状态栏时钟改造笔记:为你的Android 11 ROM添加“常显秒数”开关
  • LDO稳压芯片:从内部架构到关键参数的深度选型指南
  • 手把手教你用Xilinx Ultrascale+ FPGA解串12-bit ADC的LVDS信号(附完整Verilog代码)
  • 不止写文章!用Gutenberg区块编辑器打造高转化落地页:实战按钮、封面图与多列布局
  • GeoAI Universal Platform:多LLM兼容的地理空间AI平台,技术架构与开箱实践
  • 告别阻塞!STM32L431RCT6串口DMA收发实战,附IDLE中断接收完整代码
  • Deepin/UOS软件包维护者入门:如何手动更新一个deepin-wine应用的版本(从9.3.2到9.4.8实战)
  • 你的竞争对手已经用 AI 实现规模化复制,你还在靠个人能力撑着? 2026企业数字化转型避坑指南
  • Axure中文语言包:3分钟极速汉化指南,让原型设计更高效
  • CSS项目样式如何模块化_应用BEM规范构建组件化逻辑
  • 不止于安装:Manjaro下软件‘突然打不开’的深度排查与修复实战(以微信/Postman为例)
  • CentOS 7.9上Open vSwitch 2.12.0保姆级安装与开机自启配置(附systemd服务文件)
  • 【Hot 100 刷题计划】 LeetCode 287. 寻找重复数 | C++ 数组判环 (快慢指针终极解法)
  • Go语言的runtime.SetFinalizer终结器与对象生命周期中的清理钩子
  • C++ Primer 第5版源码怎么用?手把手教你用GCC和VS2012跑通书里的例子
  • 别再手动改Word了!用Python的docxtpl+Jinja2,5分钟搞定100份合同/报告模板
  • 从实验室到生产:手把手教你用 Open vSwitch (OVS) 在 Ubuntu 上搭建虚拟网络沙盒环境
  • 【CE】Mac逆向入门:从零到一掌握Cheat Engine基础扫描四部曲
  • OpenCV-Python实战:手把手教你用cv2.remap()修复畸变图像(以鱼眼镜头校正为例)
  • 数据殖民主义:AI伦理红线——面向软件测试从业者的审视
  • 五相电机双闭环矢量控制模型_采用邻近四矢量SVPWM_MATLAB_Simulink仿真模型包括
  • 告别虚拟机!用Docker Desktop在Windows 10上5分钟快速搭建一个CentOS开发环境
  • 【Linux从入门到精通】第7篇:Vim编辑器生存指南——从“如何退出”到“指法如飞”
  • STM32 SPI刷屏太慢?试试DMA+中断优化,实测刷屏时间从XXms降到387ms
  • VGA时序详解与FPGA实现避坑指南:从800x600@60Hz到你的第一幅图像