拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于ESP32与Home Assistant的智能喂奶计时器:从硬件连接到米家同步

最近在折腾智能家居想给家里的喂奶记录做个自动化方案。网上方案要么太复杂要么需要额外买设备。正好手头有闲置的ESP32和一块墨水屏就琢磨着能不能自己做一个。核心需求很简单每次喂奶按一下按钮屏幕开始计时并显示同时把这次喂奶事件同步到米家App里方便全家查看记录。折腾了一圈发现单纯用ESP32直连米家比较麻烦而Home AssistantHA作为智能家居中枢既能轻松接入ESP32设备又能通过插件将数据同步到米家。于是一个基于ESP32 墨水屏 Home Assistant 米家的喂奶计时器方案就诞生了。本文将手把手带你复现这个项目从硬件连接、固件开发、HA配置到米家接入完整走一遍。即使你是物联网开发新手跟着步骤也能做出来。1. 项目核心思路与硬件准备1.1 项目架构与工作流程整个项目的核心思路是ESP32作为数据采集和显示终端Home Assistant作为智能中枢和协议桥梁米家作为最终的用户交互界面。具体工作流程如下触发家长按下连接在ESP32上的物理按钮。记录与显示ESP32记录按下按钮的时间戳并在本地的墨水屏上显示本次喂奶的开始时间、距离上次喂奶的间隔并启动一个计时器显示本次喂奶已持续时长。上报数据ESP32通过Wi-Fi将这次喂奶事件包含时间戳、事件类型等发送到家庭内网的Home Assistant服务器。中枢处理Home Assistant接收到数据更新其内部的传感器状态。我们可以在这里设置自动化比如喂奶超过30分钟发出提醒。同步至米家利用Home Assistant的第三方集成如Xiaomi Miot Auto将Home Assistant里的这个“喂奶计时器传感器”同步到米家App中。远程查看家人打开米家App即可在设备列表里看到喂奶记录和当前状态实现信息共享。这个架构的优势在于ESP32只需要实现简单的数据上报和显示复杂的集成、自动化、远程访问都由Home Assistant承担大大降低了嵌入式端的开发难度。1.2 硬件清单与连接你需要准备以下硬件组件型号/规格数量说明主控芯片ESP32开发板如ESP32-WROOM-321核心控制器负责逻辑、联网和驱动。显示屏2.9英寸或4.2英寸三色墨水屏带SPI接口1用于低功耗显示信息。推荐使用GxEPD2库支持的型号如GDEW029T5。输入设备轻触按键开关1-2用于开始计时、重置等操作。电源USB数据线或3.7V锂电池1供电。如果长期使用建议接充电宝或5V电源。连接线杜邦线母对母、公对母若干用于连接各组件。电阻10kΩ 电阻1-2按键的上拉/下拉电阻。接线示意图以ESP32 DevKit V1为例墨水屏以GDEW029T5为例通常需要连接以下引脚VCC- ESP32的3.3VGND- ESP32的GNDDIN/MOSI- ESP32的GPIO 23CLK/SCK- ESP32的GPIO 18CS/SS- ESP32的GPIO 5DC- ESP32的GPIO 17RST- ESP32的GPIO 16BUSY- ESP32的GPIO 4注意不同型号的墨水屏引脚定义可能不同请务必查阅你的屏幕资料手册。按键连接以使用一个按键为例按键一端接ESP32的GPIO 13可自定义。按键另一端接GND。在GPIO 13和3.3V之间连接一个10kΩ上拉电阻。这样按键未按下时引脚读数为高电平1按下时为低电平0。2. 软件开发环境搭建我们将使用Arduino IDE来开发ESP32的固件因为它对新手友好库生态丰富。2.1 安装Arduino IDE与ESP32开发板支持从Arduino官网下载并安装最新版Arduino IDE。打开IDE点击文件-首选项。在“附加开发板管理器网址”中填入以下地址https://espressif.github.io/arduino-esp32/package_esp32_index.json如果有其他网址用逗号隔开。点击工具-开发板-开发板管理器。搜索“esp32”找到由Espressif Systems提供的“ESP32”开发板包点击安装。安装过程可能需要一些时间。2.2 安装必要的库本项目需要两个核心库GxEPD2用于驱动墨水屏。这是目前对ESP32支持较好的墨水屏库。ArduinoJson用于处理与Home Assistant通信的JSON数据。安装方法点击项目-加载库-管理库...在库管理器中分别搜索“GxEPD2”和“ArduinoJson”并安装。2.3 准备Home Assistant环境你需要一个正在运行的Home Assistant。安装方式有多种推荐最简单在树莓派、旧电脑或虚拟机上安装Home Assistant OS。Docker安装适合有一定Linux和Docker经验的用户。直接安装在Linux系统上通过Python虚拟环境安装。确保你的Home Assistant可以正常访问并且ESP32所在的网络能够连接到HA服务器的IP地址通常是你的家庭路由器IP段如192.168.1.x。3. ESP32固件开发详解固件的核心功能连接Wi-Fi、监听按键、更新屏幕、向Home Assistant发送数据。3.1 创建新项目与基础配置在Arduino IDE中新建一个项目。首先包含必要的头文件和定义全局变量、常量。// 喂奶计时器 - ESP32 with E-Ink Home Assistant #include WiFi.h #include HTTPClient.h #include ArduinoJson.h #include GxEPD2_BW.h // 我们使用黑白驱动如果你的屏是三色用GxEPD2_3C #include Fonts/FreeMonoBold12pt7b.h // 选择一种字体 // 1. 网络配置 const char* ssid 你的Wi-Fi名称; const char* password 你的Wi-Fi密码; const char* haServer http://192.168.1.100:8123; // 你的HA地址和端口 const char* haToken 你的HA长期访问令牌; // 在HA侧边栏“配置文件”最下方创建 // 2. 硬件引脚定义 #define BUTTON_PIN 13 // 按键连接的GPIO #define EINK_CS 5 #define EINK_DC 17 #define EINK_RST 16 #define EINK_BUSY 4 // 3. 墨水屏对象定义 // 根据你的屏幕型号修改以下是2.9英寸黑白屏的示例 GxEPD2_BWGxEPD2_290, GxEPD2_290::HEIGHT display(GxEPD2_290(EINK_CS, EINK_DC, EINK_RST, EINK_BUSY)); // 4. 全局变量 unsigned long lastFeedTime 0; // 上次喂奶的时间戳毫秒 unsigned long currentFeedStartTime 0; // 本次喂奶开始时间戳 bool isFeeding false; // 当前是否正在喂奶 String lastInterval --; // 上次喂奶间隔显示文本 int buttonState HIGH; int lastButtonState HIGH; void setup() { Serial.begin(115200); pinMode(BUTTON_PIN, INPUT_PULLUP); // 使用内部上拉电阻按键另一端接GND initDisplay(); connectToWiFi(); // 尝试从HA获取上次记录的时间可选进阶功能 // fetchLastFeedTimeFromHA(); } void loop() { checkButton(); updateDisplay(); // 如果正在喂奶每10秒更新一次计时显示 if (isFeeding (millis() - currentFeedStartTime) % 10000 50) { updateDisplay(); } delay(50); // 简单的防抖和降低CPU占用 }3.2 核心功能函数实现接下来我们逐一实现setup中调用的函数。初始化显示屏void initDisplay() { display.init(115200, true, 2, false); // 初始化使用SPI 10MHz重置 display.setRotation(1); // 根据你的屏幕方向调整0-3 display.setFont(FreeMonoBold12pt7b); display.setTextColor(GxEPD_BLACK); display.fillScreen(GxEPD_WHITE); displayDisplay(); // 清屏为白色 } void displayDisplay() { display.display(false); // false表示局部刷新更快true全刷更干净 }连接Wi-Fivoid connectToWiFi() { Serial.print(Connecting to ); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(); Serial.println(WiFi connected.); Serial.println(IP address: ); Serial.println(WiFi.localIP()); }按键检测与逻辑处理这是核心逻辑按下按键表示一次喂奶事件开始或结束本项目简化为按下即开始一次新记录并结束上一次。void checkButton() { buttonState digitalRead(BUTTON_PIN); // 检测下降沿按键按下 if (buttonState LOW lastButtonState HIGH) { delay(50); // 简单防抖 if (digitalRead(BUTTON_PIN) LOW) { // 确认按下 onFeedButtonPressed(); } } lastButtonState buttonState; } void onFeedButtonPressed() { Serial.println(Feed button pressed!); unsigned long now millis(); // 计算与上次喂奶的间隔分钟 if (lastFeedTime 0) { unsigned long interval (now - lastFeedTime) / 60000; // 转换为分钟 lastInterval String(interval) min; } else { lastInterval First; } // 更新喂奶时间记录 lastFeedTime now; currentFeedStartTime now; isFeeding true; // 1. 更新本地屏幕 updateDisplay(); // 2. 发送事件到Home Assistant sendFeedEventToHA(now); // 3. 可选蜂鸣器提示或LED闪烁 }更新墨水屏显示墨水屏刷新慢要优化显示逻辑尽量减少全屏刷新。void updateDisplay() { display.setPartialWindow(0, 0, display.width(), display.height()); // 设置局部刷新区域这里实际是全屏 display.firstPage(); do { display.fillScreen(GxEPD_WHITE); display.setCursor(10, 30); display.print(Baby Feeding Timer); display.setCursor(10, 70); display.print(Last Interval:); display.setCursor(180, 70); display.print(lastInterval); display.setCursor(10, 110); display.print(Status:); display.setCursor(100, 110); if (isFeeding) { display.print(FEEDING); // 计算并显示本次喂奶持续时间 unsigned long feedingDuration (millis() - currentFeedStartTime) / 1000; // 秒 int minutes feedingDuration / 60; int seconds feedingDuration % 60; display.setCursor(10, 150); display.print(Duration: ); display.print(minutes); display.print(m ); display.print(seconds); display.print(s); } else { display.print(READY); display.setCursor(10, 150); display.print(Press to start); } // 显示上次喂奶时间 display.setCursor(10, 190); display.print(Last Feed:); if (lastFeedTime 0) { // 这里可以添加时间格式转换函数将时间戳转为可读时间 display.setCursor(130, 190); display.print(formatTime(lastFeedTime)); } } while (display.nextPage()); } // 一个简单的时间格式化函数示例未处理日期 String formatTime(unsigned long timestamp) { unsigned long seconds timestamp / 1000; int hours (seconds % 86400L) / 3600; int minutes (seconds % 3600) / 60; char buffer[10]; sprintf(buffer, %02d:%02d, hours, minutes); return String(buffer); }与Home Assistant通信核心我们将通过Home Assistant的RESTful API来创建一个传感器并更新其状态。 首先需要在HA中手动创建一个“辅助元素”传感器或者通过API自动创建。这里我们采用通过API发送状态更新的方式假设传感器已经创建好。void sendFeedEventToHA(unsigned long eventTime) { if (WiFi.status() ! WL_CONNECTED) { Serial.println(WiFi not connected!); return; } HTTPClient http; String url String(haServer) /api/states/sensor.baby_feeding; // sensor.baby_feeding 是你的实体ID // 构建JSON数据 DynamicJsonDocument doc(512); doc[state] feeding; // 状态可以是 feeding, ready等 JsonObject attributes doc.createNestedObject(attributes); attributes[last_feed_time] eventTime; // 时间戳 attributes[last_interval] lastInterval; // 间隔文本 attributes[friendly_name] Baby Feeding Timer; // 友好名称 String jsonString; serializeJson(doc, jsonString); http.begin(url); http.addHeader(Content-Type, application/json); http.addHeader(Authorization, Bearer String(haToken)); // 认证 int httpCode http.PUT(jsonString); // 使用PUT方法更新状态 if (httpCode 0) { String payload http.getString(); Serial.printf([HTTP] PUT... code: %d\n, httpCode); Serial.println(payload); } else { Serial.printf([HTTP] PUT... failed, error: %s\n, http.errorToString(httpCode).c_str()); } http.end(); }在Home Assistant中创建传感器备用方法如果你不想在代码中动态创建可以提前在HA的configuration.yaml文件中添加一个模板传感器或者更简单在HA界面上创建进入HA侧边栏配置-设备与服务-辅助元素。点击右下角创建辅助元素。选择传感器。名称填Baby Feeding Timer实体ID会自动生成如sensor.baby_feeding_timer。单位可以留空或填“状态”。创建后记下这个实体ID并更新上面代码中的URL/api/states/sensor.baby_feeding_timer。4. Home Assistant配置与自动化ESP32端完成后我们需要在Home Assistant中配置使其能接收数据并同步到米家。4.1 获取长期访问令牌在HA网页界面点击左下角你的用户名滚动到最下方找到“长期访问令牌”点击“创建令牌”为其命名如“ESP32_Feeding_Timer”然后复制生成的令牌字符串。此令牌只显示一次请妥善保存并填入ESP32代码的haToken变量中。4.2 验证ESP32通信将完整的Arduino代码编译上传到ESP32。按下按键后查看串口监视器波特率115200。你应该能看到连接Wi-Fi成功的日志以及发送HTTP请求到HA的日志。 在HA的侧边栏点击开发者工具-状态。在实体输入框中输入你定义的实体ID如sensor.baby_feeding。当你按下ESP32的按键后刷新或监听此实体应该能看到其状态从unknown变为feeding并且属性中包含了时间戳等信息。4.3 创建喂奶记录自动化可选我们可以利用HA的自动化功能当传感器状态变为feeding时生成一条永久的喂奶记录。进入配置-自动化与场景-创建自动化。选择“从空自动化开始”。触发器选择“状态”实体选择你的喂奶传感器如sensor.baby_feeding从*变为feeding。动作选择“调用服务”。服务选择input_datetime.set_datetime。这是一个用于记录时间的辅助元素。首先你需要创建一个input_datetime辅助元素命名为“Last Feed DateTime”。在动作配置中目标实体选择这个input_datetime。在“服务数据”中填入{ timestamp: {{ now().timestamp() }} }这样每次喂奶input_datetime都会更新为当前时间这个时间会被永久记录即使ESP32重启也不会丢失。5. 接入米家App这是实现远程查看的关键。由于米家生态相对封闭我们通过Home Assistant的第三方集成“Xiaomi Miot Auto”来反向接入。5.1 安装Xiaomi Miot Auto集成在HA的配置-设备与服务-集成页面点击右下角“添加集成”。搜索“Xiaomi Miot Auto”并安装。安装后按照提示登录你的小米账号不建议使用主账号可新建子账号或使用扫码登录。集成会自动拉取你米家账号下的设备。但我们需要的是将HA的设备暴露给米家。5.2 将HA传感器暴露为米家设备Xiaomi Miot Auto集成本身主要用来接入米家设备到HA。要将HA实体暴露给米家通常需要借助另一个集成如“Home Assistant Cloud”需付费订阅或使用“Node-RED”配合“miot”节点等更复杂的方式。这里介绍一个通过“智能音箱”间接实现的实用方法在HA中确保你的喂奶传感器实体sensor.baby_feeding和记录时间的input_datetime实体是存在的。在HA中安装并配置“Google Assistant”或“Amazon Alexa”集成这通常需要一些网络条件本文不展开。在这些语音助手集成中将上述实体“暴露”给语音助手。在米家App中绑定同一个小米账号的“小爱音箱”技能。当小爱音箱接入了Google Assistant或Alexa后理论上可以通过语音查询这些由HA暴露出来的设备状态。更直接的方法是如果你有一台小爱音箱Pro带蓝牙Mesh网关有些教程可以通过本地局域网协议将HA的虚拟设备同步过去但这需要较深的折腾。更稳定简单的替代方案推荐使用Telegram Bot或AppDaemon创建通知如果米家接入太复杂一个极佳的替代方案是使用HA的Telegram Bot集成在HA中安装“Telegram Bot”集成。在Telegram中找BotFather创建一个机器人获取token。在HA配置中填入token并获取你的Chat ID。创建一个自动化当喂奶事件触发时调用telegram_bot.send_message服务将“宝宝于XX时间开始吃奶了”这样的消息发送到你的Telegram。家人全部安装Telegram加入同一个群组即可实时收到推送。这比在米家App里找设备更直观及时。6. 常见问题与排查在开发过程中你可能会遇到以下问题问题现象可能原因排查思路ESP32无法连接Wi-FiSSID/密码错误、路由器设置如MAC过滤、信号弱检查代码中的SSID/密码用手机确认网络查看串口日志。墨水屏不显示或花屏引脚连接错误、库型号不匹配、供电不足逐一检查接线在GxEPD2_Example中测试你的屏幕型号尝试外接5V供电。HTTP请求失败返回401HA长期令牌错误、令牌未生效、URL错误检查haToken是否填写正确在HA中确认令牌已创建检查URL中的IP、端口和实体ID。HTTP请求失败返回404HA中对应的实体不存在在HA开发者工具中检查实体ID是否存在或先在HA界面创建辅助传感器。按键按下无反应引脚接触不良、内部上拉未启用、按键损坏用digitalRead读取引脚状态并打印到串口确认按下时电平变化检查接线。屏幕刷新太慢墨水屏全刷特性、刷新代码逻辑问题确保使用display.display(false)局部刷新只在必要内容变化时调用updateDisplay()。Home Assistant中看不到状态更新防火墙阻止、ESP32与HA不在同一网段确保ESP32能ping通HA服务器IP检查HA配置中的http:模块是否启用且未限制内网IP。7. 项目优化与扩展建议一个基础版本完成后可以考虑以下优化让项目更实用双按键设计一个键用于“开始喂奶”另一个键用于“结束喂奶/换边”这样可以更精确记录单次喂奶时长。数据持久化使用ESP32的Preferences库或LittleFS文件系统将lastFeedTime等关键数据保存到闪存中。这样即使断电重启历史记录也不会丢失。低功耗优化喂奶间隙ESP32可以进入深度睡眠Deep Sleep仅由按键中断唤醒。这需要硬件上连接按键到ESP32的RTC唤醒引脚如GPIO 33。显示优化增加喂奶历史记录列表最近5次。显示今日喂奶总次数和总时长。使用更美观的字体和布局。HA自动化增强创建“喂奶统计”传感器计算今日、本周的喂奶频率。设置提醒自动化如果距离上次喂奶超过3小时通过TTS在小爱音箱上播放提醒。将喂奶数据记录到InfluxDB或MySQL数据库用于长期分析和可视化如Grafana面板。外壳与电源设计并3D打印一个外壳将ESP32、屏幕、按键集成进去并使用锂电池供电使其成为一个独立的便携设备。这个项目完美结合了嵌入式硬件ESP32、本地智能中枢Home Assistant和消费级物联网平台米家的优点。它不仅解决了喂奶记录这个具体问题更提供了一个模板如何利用开源硬件和软件桥接个人定制化需求与成熟商业生态。你可以将此模式扩展到其他家庭数据记录场景如宠物喂食、植物浇水、药品提醒等。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门