尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

ESP32智能邮箱制作:称重传感器+低功耗通知系统

ESP32智能邮箱制作:称重传感器+低功耗通知系统 1. 先别急着接传感器把需求拆干净再做做这个智能邮箱项目的起因特别简单我家邮箱在小区的公共区域离门口得走两分钟每天跑一趟十有八九是空的可真当里面有账单或包裹的时候又总是错过。后来我留意到不少邻居其实也面临同样的问题只是大家习惯性地每天“开盲盒”。于是我就想能不能做一个基于 Arduino 的智能邮箱用传感器检测邮箱里有没有被投入新邮件再把通知推送到手机上。这个项目能解决的问题非常具体你不再需要每天跑去开箱也不用在等包裹时反复“遛弯”。它适合三类人参考——家里有独立邮箱又想折腾点实用小项目的玩家、租住在多层公寓但门口有公共信箱的用户、以及刚入门 Arduino 想找个完整案例练手的学习者。整个项目做下来硬件成本可以控制在百元以内代码量也不大算是嵌入式入门里难得的“做完真能用”的项目。不过我在动手之前踩过一个教训别一上来就挑传感器、焊线、写代码。智能邮箱的核心不是“检测”而是“判断”。邮箱门开合一次可能是投递也可能是取信邮递员一天投递两次也可能一次都没有风大的时候门要是没关紧传感器会反复触发。如果只做一个“门开关检测”那做的就是个门铃不是智能邮箱。所以我在设计之初就给自己定了三条需求边界只检测“投递动作”即邮箱门被打开后确实有新邮件放进了邮箱通过手机实时通知最好不依赖额外服务器能离线运行数月电池供电室外环境不用频繁维护。这三条边界直接决定了后边的所有选型。我把摄像头、语音识别、远程开锁这类花哨功能全部砍掉不是因为做不出来而是因为每多一个复杂度就多一个故障点。一个智能设备挂在室外一角它的首要指标永远是稳定而不是可玩性。1.1 为什么我不用摄像头也不用门磁开关先说说摄像头方案。市面上确实有带摄像头的智能邮箱产品拍摄投递画面然后推送到手机。但这类方案有几个毛病第一持续通电或者频繁唤醒对供电要求高第二隐私问题很敏感邻居经过你的邮箱摄像头也在录容易起纠纷第三视频识别“是否有邮件”其实并不简单需要云端算法。所以我从一开始就没考虑摄像头。门磁开关是另一个常见思路。把干簧管或者微动开关装在邮箱门上门开触发一次状态变化。它的优点是结构简单、代码好写而且几乎不耗电。但问题也很明显门开不等于有新邮件。可能是你自己取件也可能是小孩好奇掀了一下门甚至风大吹开又关上。如果每次开门都发通知用不了一周你就会把通知权限关掉。我最后用的方案是“门状态变化 邮箱内部邮件感知”双重条件。也就是说系统需要区分两种行为门被打开后邮箱内部的邮件状态发生了变化这时候才判定为投递门被打开但内部状态没变那就只是取件或者误触不发通知。这个逻辑写起来不难但在传感器选型上就要选一个能感知“邮箱肚子里有没有东西”的传感器。1.2 传感器方案对比红外、称重还是超声波围绕“感知邮箱内部是否有邮件”我认真评估过三种传感器各有优劣这里直接给出我对比后的结论。传感器类型检测方式优点缺点适合场景红外对射/反射式光电邮件进入时阻断或反射红外光便宜、响应快、体积小易受阳光干扰大邮件可能不触发纸质信件为主的室内或遮光邮箱称重传感器电阻应变片HX711邮箱底部压力变化最可靠、可检测重量增量、误报率最低成本稍高、需要校准、电路稍复杂室外环境、混合邮件和包裹超声波传感器测量内部物体距离不需要物理接触、能测堆叠高度邮件形状不规则时读数漂移、功耗偏高对精度要求不高的场景我一开始用了红外对射装在邮箱内部两侧邮件投进来时切断红外光束触发一次。测试了两周发现问题不少夏天太阳角度低的时候阳光能从投递口照进来直接打在接收头上导致误触发寄来的杂志比较宽把整个投递口都堵了红外光束持续被阻断反而无法分辨一次投递还是两次投递。后来我换成了称重传感器方案把应变片贴在邮箱底板上用 HX711 读取压力变化。称重方案有个天然优势它可以区分“有没有增加重量”投递一件就多一件的重量逻辑上非常符合人类的直觉。1.3 板子选择从 Arduino Uno 到 ESP32 的演进再用 Arduino Uno 做原型验证几乎是我的习惯。Uno 布线方便、引脚标注清晰、网上资料多很适合在面包板上先把传感器和逻辑跑通。我的建议是第一步不要追求一步到位先用 Uno 称重传感器 串口打印把“投递检测”这件事调通再谈联网和低功耗。跑通原型之后我换成了 ESP32。原因有三个第一ESP32 自带 Wi-Fi可以直接推通知不用再外接一个 ESP8266 模块或网络扩展板第二ESP32 支持深度睡眠Deep Sleep电流可以降到几十微安级别这对电池供电的室外设备至关重要第三它也有 ADC 和 I2C 接口HX711 直接就能接上去。ESP8266 也是可以的功耗比 ESP32 更低价格也更便宜。但 ESP32 在 I/O 和模拟输入上更宽裕调试起来少很多限制。如果你手里已经有 NodeMCU 或 D1 Mini也可以直接用代码部分几乎通用只需要注意引脚编号不同即可。2. 硬件清单与接线实操照着买照着接就行ESP32 开发板推荐带有 CP2102/CH340 串口芯片的版本驱动好装HX711 称重模块 5kg 或 10kg 电阻应变片式称重传感器微动开关或干簧管模块用于检测门开合3.7V 锂电池或两节 18650 电池 5V 升压板如 MT3608、SX1308拉丝铝板或亚克力板固定传感器用导线若干、防水密封盒、硅胶密封胶可选0.96 寸 OLED 显示屏调试时显示重量和状态可能有人会问为什么还需要微动开关前面不是说门开不等于投递吗这里要解释清楚微动开关是为了记录“门曾开过一次”这个事件而称重传感器是为了判断“邮箱内部是否有重量变化”。两者配合才能实现前面说的“双重条件判定”。单独用称重传感器有一个问题有人打开邮箱门但什么都没放然后又关上重量不会变化这时候你没法知道发生过一次开门——当然如果只检测投递这种事件也不重要。但加上门开关可以更准确地记录投递过程的时间点甚至能让你知道“邮递员在门前停留了几秒钟”可玩性更高。2.1 安装位置是决定误报率的关键传感器的安装位置直接决定整套系统稳不稳定。先说称重传感器。电阻应变片的原理是弹性体受力变形后贴在它表面的应变片电阻值发生变化再通过 HX711 的差分放大器和 24 位 ADC 读取出微小的电压差。所以安装的核心要求是邮箱的底部载荷必须完整地传递到传感器的敏感区域不能有悬空、松动或者只压到传感器边缘的情况。我的做法是在邮箱内部放一块厚度在 5mm 以上的硬质 PVC 板四周垫上硅胶脚垫把称重传感器固定在这块板下方传感器再接触邮箱底板。这样邮件放在板上时压力会通过 PVC 板均匀传给传感器。如果直接传感器贴箱底邮件落到板上时冲击力分布不均读数会跳得很厉害很容易误判。微动开关装在邮箱门框的关门位置。要让门在正常关闭时能压住微动开关的簧片门开启时簧片释放。这里有个容易被忽略的细节邮箱门如果已经被锈蚀或变形关合位置本身就晃动微动开关会反复抖动。解决办法是在代码里做 200ms 的软件去抖同时用热熔胶把微动开关的位置固定住。如果选用红外对射传感器安装位置建议在投递口的正下方、邮箱内部离顶盖 5cm 左右的位置。要避免阳光直射和外部灯光直射。并且最好加一个遮光罩用黑色热缩管套在接收管上只留一个小的窗口。这样能显著减少环境光干扰。2.2 接线参考图与元器件选型要点接线其实不复杂我按 ESP32 D1 Mini 型号来列一份对照表你用其他板子时只需要改对应引脚号。HX711 模块ESP32 引脚说明VCC3V3给模块供电GNDGND共地SCKGPIO 18时钟引脚DTDOUTGPIO 19数据引脚微动开关模块ESP32 引脚说明VCC3V3模块供电GNDGND共地OUTGPIO 4接入开关信号代码中启用内部上拉称重传感器的接线要看具体是四线制还是六线制。最常用的是四线制红色E接 HX711 的 E黑色E-接 E-白色A-接 A-绿色A接 A。如果传感器的线序和你手上的不一致一定要用万用表测一下电阻也可以直接看传感器标签上的颜色表别凭感觉接。我最初就接反过 A/A-结果读数始终为负且跳动排查了半天。HX711 模块供电要注意很多 HX711 模块板上带有稳压芯片可以接受 2.7V 到 5.5V 的宽电压输入。直接用 ESP32 的 3V3 供电没问题。但有些模块是直通式的内部没有稳压VCC 直接给传感器激励电压这时候尽量用 5V 供电传感器的灵敏度和线性度会更好。这种情况需要把 HX711 的 VCC 接到 ESP32 的 VIN 或 5V 引脚但要注意 ESP32 的 5V 输出来自 USB 或锂电池升压后的电源必须保证它稳定。2.3 电源与功耗想要几个月不换电池就得学会“睡”室外智能设备最大的敌人不是下雨是耗电。如果只写一个 loop() 循环每 200ms 读一次重量、每 10 秒连一次 Wi-Fi任何电池都撑不过一周。所以电源设计上我用了两级策略深度睡眠 按需唤醒。ESP32 的深度睡眠模式能把核心工作电流降到 10μA 左右这意味着可以以极低功耗待机。唤醒方式有两种定时唤醒和外部 GPIO 唤醒。在这个项目里我用两个唤醒源组合微动开关接在 GPIO 4 上并设置为 EXT0 唤醒。邮箱门打开时开关状态变化会触发 GPIO 电平跳变ESP32 从深度睡眠中被唤醒。同时设置一个每 8 小时定时唤醒的定时器用于每天定时上报一次电池电量和设备在线状态。被唤醒后主程序执行以下流程上电初始化 → 读取重量 → 判断重量是否变化 → 如果变化且此前门开过就推通知 → 完成所有工作后立即进入深度睡眠。整个过程应该在 30 秒内完成。Wi-Fi 连接是最耗时的我实测 ESP32 连接家庭路由器平均需要 3 到 8 秒这也是手机通知会有几秒延迟的原因。电池选择上我试用过两节 18650 串联通过稳压模块降到 5V也试用过单节 3.7V 锂电池经过升压模块到 5V。实测下来单节 18650 加上 SX1308 升压方案在一个月约发生 60 次唤醒的用量下能坚持约 3 到 4 个月。如果只是单纯投递通知、不频繁上报半年无压力。关键是升压模块待机电流要小有些模块空载就有 10mA 以上的自耗那电池就全浪费在模块自己身上了。选购时留意卖家标注的“静态功耗”尽量选低于 100μA 的型号。3. 代码核心逻辑与参数调优这几段代码可以直接抄这个项目的难点不在某个高深的算法而在状态判断的健壮性。我写了很多版本最终沉淀下来的是一个极简的状态机。下面把最核心的几段代码贴出来并逐段解释为什么这么写。3.1 用状态机判断投递事件别一开门就发通知先说明总体逻辑系统维护一个 doorOpened 变量表示“在本次通电周期内门是否被打开过”。微动开关检测门的开合称重传感器检测重量的变化。只有当“门开过”并且“重量比之前增加了”同时满足才判定为一次投递。// 核心状态变量 bool doorOpened false; bool mailDelivered false; float lastWeight 0.0f; void loop() { // 1. 读取门磁状态带软件去抖 bool doorNow readDoorWithDebounce(); if (doorNow true !doorOpened) { doorOpened true; // 记录开门时间点方便后续扩展 openTime millis(); } // 2. 读取当前重量 float weight hx711.get_units(5); // 读取5次取平均 // 3. 如果门开过且重量比存档增加超过阈值判定投递 if (doorOpened (weight - lastWeight DELTA_THRESHOLD)) { mailDelivered true; lastWeight weight; sendNotify(weight - lastWeight); // 重置状态等待下一次投递 doorOpened false; } // 4. 如果重量减少说明用户已取走邮件更新存档值 if (weight lastWeight - 5.0f) { lastWeight weight; doorOpened false; } delay(200); }注意第 4 步当重量减少时直接把 lastWeight 更新为当前重量同时把 doorOpened 置为 false。这一步处理的是“邮递员来取信或者你自己把邮件拿走”的场景。如果不重置下一次门打开时重量增加到比上一次多系统会误判为新的投递。阈值 DELTA_THRESHOLD 的设定非常关键。设得太小一张小纸片就会误触发设得太大一封信的重量可能检测不到。我的经验值是 20g 到 30g。为什么是这个范围因为一般普通信封重量在 10g 到 20g一本杂志 200g 以上一个手机盒 500g 以上。如果要检测到普通信件阈值必须低于标准信件的重量但又不能太低因为称重传感器的读数在开门震动瞬间会有噪声波动1-2g 的波动非常常见。取 20g 以上可以稳定过滤震动噪声同时不会漏掉期刊或小包裹。如果你们的场景主要是大件快递可以直接调到 100g 以上。3.2 HX711 标定与读数稳定化HX711 读出来的并不是直接的重力单位而是一个由应变片电阻变化经过 ADC 转换后的原始计数值。要显示成克数需要两点第一个是比例系数第二个是去皮零点。#include HX711.h HX711 scale; void setup() { Serial.begin(115200); scale.begin(19, 18); // DT, SCK scale.set_scale(398.6f); // 这个值需要标定 scale.tare(10); // 校准零点空箱状态下运行 } // 标定方法 // 1. 空邮箱时调用 scale.tare()让读数为0 // 2. 放一个已知重量比如500g的砝码/矿泉水 // 3. 读取 scale.get_units(5) 得到原始值 raw // 4. 用 raw 500 * factor 反推 factor即 factor raw / 500 // 5. 将 factor 写入 set_scale(factor)标定的过程其实很简单但有一个坑称重传感器弹性体会随着温度变化产生零点漂移。冬天和夏天的同一重量读到的原始值可能差好几克。所以我建议在代码里不要每次上电都读取一个固定的标定零点而是在系统初始化时先读取一次“空箱重量”并把它作为当前零点。但这样又引入了一个问题如果当时箱子里已经有邮件那这个“零点”就包含了邮件重量。解决方法是只有同时满足“门关闭”且“重量变化不大”时才认为可以更新零点。也就是在系统静置超过 5 分钟且重量波动小于 5g 时自动执行一次去皮。这段逻辑稍复杂但写进去以后长期运行的稳定性会好很多。关于读数稳定化HX711 模块自带 24 位 ADC分辨率很高但也更容易受噪声干扰。有三个改进措施在 HX711 供电端并联一个 100μF 电解电容和 0.1μF 瓷片电容滤掉电源纹波。采样时用 get_units(5) 或 get_units(10)多次采样取平均。读数中间插入 10ms 的稳定等待让应变片从机械震动中恢复。3.3 通知链路Blynk 最省事Pushover 更克制通知推送到手机是用户体验最关键的一环。我试过三种方案分别是 Blynk、Pushover 和邮箱 SMTP。Blynk 的优势是上手极快。你只需要在手机安装 Blynk 应用创建一个项目添加一个通知组件和几个数值组件然后拿到模板的 auth token在代码里调用Blynk.virtualWrite和Blynk.notify就能实现推送。缺点也很明显Blynk 的免费额度有限制通知组件和设备的绑定关系绑定在官方云上如果你用的是免费版每月通知次数有上限。但作为个人项目完全够用。Pushover 是我现在的主力方案。它的 API 接口无比简单只需要向它的 API 地址 POST 一条消息就能推送到手机支持 iOS/Android 客户端。很多家庭自动化项目都内置了 Pushover 的支持稳定性和速度都很好。初始使用需要一次性买断 app价格很便宜后面不再有订阅费用。邮箱 SMTP 方案也有不少人用直接在代码里发一封邮件到自己的邮箱。对老人和不需要装 App 的场景比较友好。但 SMTP 需要处理认证、TLS、可能被服务商限流的问题代码量不小而且邮箱客户端并没有“重点提醒”的推送弹窗时效性不如 Pushover 或 Blynk。我给的推荐是如果你想要最省事、最快速的成品效果用 Blynk如果你愿意多花十几分钟把项目做得更“专业”一点用 Pushover。下面是 Pushover 的发送函数示例它会在投递事件触发时调用。#include WiFi.h #include HTTPClient.h String serverName http://api.pushover.net/1/messages.json; String pushoverToken 你的应用Token; String pushoverUser 你的用户Key; bool sendPushover(String message) { HTTPClient http; http.begin(serverName); http.addHeader(Content-Type, application/x-www-form-urlencoded); String postData token pushoverToken user pushoverUser title 智能邮箱 message message; int httpCode http.POST(postData); http.end(); return (httpCode 200); }有一点要特别提醒HTTP 的 POST 请求如果 message 里有中文一定先做 URL 编码否则推送内容会显示乱码或直接失败。保险起见我一般只推送简短英文或直接写“您有一封新邮件”这样的固定文案避免编码问题。4. 实际运行中的常见问题与排查技巧这个项目在外面跑了大概半年遇到过不少问题。我把最有价值的几条整理成速查表应该比很多“示例代码”更有参考价值。4.1 高频误报一星期收到二十条“新邮件”通知高频误报的根源大多数情况不是传感器坏了而是阈值设得太低、没做去抖、或者安装位置松动。排查步骤先把系统切到调试模式通过串口打印每次读取到的重量值和门状态观察一段时间看问题事件发生时传感器的读数。如果是开门瞬间重量突变引起的误报把采样次数从 5 次提高到 10 次并加一个 500ms 的稳定延时。如果是大风吹动邮箱导致称重传感器产生微小形变就把 DELTA_THRESHOLD 从 20g 提上去。我之前用 20g 在春秋两季没事到了冬季风大的时候误报明显增多调到 50g 后问题解决。另外有一个很难发现的误报原因称重传感器固定螺丝松动。只需要一个螺丝没有拧紧长期震动后传感器底座松了静态读数会周期性漂移误报概率大增。所以安装完成后一定要用螺纹紧固胶或者硅胶点封固定。4.2 通知丢失邮件进了箱手机却没动静通知丢失的第一排查点是 Wi-Fi 连接。ESP32 在深度睡眠后重新连网有时会卡在连接路由器阶段特别是在弱信号区域。解决方法是在代码里加一个连接超时判断超过 8 秒没有连上就主动重启重启后重新连接成功率大幅提升。第二排查点是电源。如果电池电压低于 3.3VESP32 在射频模块工作期间就可能会出现瞬时掉电导致 Wi-Fi 模块刚连上就重启。这个现象非常隐蔽因为大部分时候能正常跑只是偶尔丢通知。可以在代码里通过analogRead(35)引脚检测电池分压后的电压。低于某个阈值时发一条“电池电量低”的告警通知比收到一封邮件通知还重要。第三排查点是 Pushover/Blynk 的服务端限流。免费版的 Blynk 每 24 小时的通知次数有限制如果你在测试阶段频繁触发可能已经被限流。遇到这类问题不用怀疑自己的代码看看服务商的配额即可。4.3 电池续航不足刚充满的电池一个月就报警续航不足几乎都是“假睡眠”的问题。很多人以为进入了esp_deep_sleep_start()就万事大吉了但实际上几个坑会悄悄耗掉电量外部设备没断电。HX711 模块和微动开关模块直接接在 3V3 上即使 ESP32 进入深度睡眠外部模块仍在取电。HX711 模块在没有通信时功耗其实不低实测约 5mA 左右这会让电池寿命缩短数十倍。解决方法是用一个 NPN 三极管或 P-MOS 管做外部设备的电源开关GPIO 25在进入睡眠前拉低让外部设备完全断电。电池管理和升压模块自身耗电。SX1308 升压模块静态电流在几十微安到一毫安不等选型时要挑低静态功耗的。或者干脆用 5V 输入的 USB-PD 充电宝方案待机电流极低。唤醒频率过高。如果代码里定时唤醒周期设得太短比如每 30 分钟唤醒一次上报状态累计耗电也会很可观。我将定时上报改成了每 12 小时一次对投递通知完全没有影响电池续航却从 3 周延长到了 4 个月。还有一点和冬天低温相关锂电池在 0°C 以下放电效率大幅下降尤其是镍氢或普通锂离子电池。我在室外测试时冬天电池一次充满只能坚持两周还以为是设备出故障了。后来换成了耐低温的锂电池并给电池盒贴了保温棉情况才缓解。如果你所在地区冬季很冷要么选耐低温电池要么干脆设计成太阳能加锂电池的混合供电。5. 进阶玩法数据面板、离线兜底与我的几点心得到这里一个能稳定运行的智能邮箱已经完成了。不过既然用了 Arduino/ESP32不加点可玩性总觉得亏了。我分享三个自己觉得最值得折腾的方向。5.1 投递时间数据面板画一张邮递员的“作息表”每次投递事件触发时除了推送通知把时间戳和重量增量记到一个结构体里通过一个简单的 HTTP 接口上报到局域网内的 Node-RED、树莓派或者自己写的 Web 页面。积累一两个月后你能画出邮递员每天大概几点来投递的分布图。这个数据的价值就出来了你可以专门在大概率投递的时间点去看邮箱减少“跑空了”的次数。我甚至能看出我家小区邮递员的投递习惯是有规律的周一到周五基本都是上午 10 点到 11 点这个区间只有节假日会随机。实现方式很简单在 ESP32 的 HTTP 端写一个 POST 回调把下面的 JSON 格式的数据发送到内网某个 HTTP 服务{ timestamp: 1700000000, weight_g: 45.6, battery_v: 3.89, events: mail }而后端用任何一门你熟的脚本语言接收、存储、展示都行。这个过程本身也是一个把嵌入式设备和互联网应用打通的好项目。5.2 离线兜底即使断网也不能让邮件状态“失联”室外设备总有断网的可能比如路由器重启、网络运营商故障、甚至被风吹断供电。如果系统只依赖云推送一旦断网整个智能邮箱就变成了“哑巴”。我的做法是在邮箱旁边加一个小的 OLED 显示屏同时也加了一个带蜂鸣器的模块。在断网状态下ESP32 检测到 Wi-Fi 连接失败后不会装死而是把“新邮件已投递”这个状态显示在 OLED 屏幕上。同时蜂鸣器短鸣三声提醒站在邮箱旁边的人。这样即使手机没收到通知只要你路过邮箱也能看到屏上的状态。等到 Wi-Fi 恢复后ESP32 会自动重连并把断网期间积压的投递事件一次性补发通知。这个兜底逻辑说复杂也复杂说简单也简单核心就是代码里加一个状态数组把所有没有成功推送的事件缓存在 RTC 内存中。RTC 内存在深度睡眠期间不会丢失正好适合这个场景。5.3 玩了大半年我最后悔和最得意的几个决定最后分享一些复盘心得。最后悔的是初期用了红外对射器方案没仔细考察太阳光的干扰白白折腾了一周。如果一开始就听人劝、做个同步对比测试就不会有那周的无穷调试了。后来换称重传感器一步到位省了很多后续麻烦。最得意的是把整机功耗控制到了“以月为单位”。这个能力其实比投递检测本身更有价值。它让我意识到嵌入式项目里选择适合的唤醒机制和电源拓扑比在代码里优化循环要重要得多。很多朋友自己做智能设备功能全跑通了但续航只有几天最后只能插着电源线用那就失去了“无线智能”的意义。还有一个细节想提醒大家室外盒子的防水一定要做够。我用的防水密封盒接线孔用航空插头传感器线从底部出然后用硅胶封死。但因为箱子内部有电池和电子元件温度变化会产生冷凝水。我在盒子底部放了两个小包的干燥剂每两个月换一次。这个小小的动作避免了多次因为受潮导致的读数漂移。如果你也打算做一个类似的智能邮箱我的建议是先不要急着追求“聪明”先把“稳定感知”做扎实再加上通知功能最后再去想低功耗和数据积累。这三步走完你实际上就已经完成了一个从原型到产品化的完整循环了。
返回列表