測器設計與實現(xiàn))
1. 項目緣起一個被忽視的日常痛點養(yǎng)過寵物的人尤其是養(yǎng)貓養(yǎng)狗的朋友應該都遇到過這個場景你正忙著手頭的工作或者沉浸在追劇的快樂中家里的毛孩子突然跑過來用爪子扒拉你或者在你腳邊焦躁地轉圈。你一開始可能不明所以直到它把你引到它的水碗邊你低頭一看——碗里空空如也一滴水都不剩了。那一刻愧疚感瞬間涌上心頭。我們總想著給它們最好的食物、最舒適的窩卻常常忽略了最基礎、也最關鍵的飲水問題。寵物缺水尤其是貓咪可能不會像餓了那樣明顯叫喚但它們長期飲水不足的后果卻很嚴重比如泌尿系統(tǒng)疾病、腎臟負擔加重等。我自己就曾因為工作太投入連續(xù)兩天忘記給家里的貓主子添水直到發(fā)現(xiàn)它頻繁去廁所卻尿不出來才驚出一身冷汗趕緊送去醫(yī)院。那次經(jīng)歷讓我意識到依賴記憶和肉眼檢查來保證水碗常滿實在是太不可靠了。于是一個簡單的想法誕生了為什么不做一個“空水碗警報器”呢它不需要多復雜核心功能就一個——當水碗里的水低于某個閾值時自動提醒主人。這個項目聽起來簡單但真要動手實現(xiàn)從傳感器選型、電路設計到提醒方式每一步都有不少門道。今天我就把自己從構思到實現(xiàn)這個“空水碗警報器”的全過程包括踩過的坑和最終驗證有效的方案詳細分享出來。無論你是電子愛好者還是單純的寵物家長想親手為愛寵做點小東西這篇內容都能給你提供一條清晰的路徑。2. 核心需求拆解與方案選型動手之前我們先別急著畫電路圖或寫代碼。一個好的項目始于對需求的清晰理解。這個“空水碗警報器”到底要做什么我們把它的核心需求拆解成幾個具體的技術指標。2.1 功能邊界定義首先它不是一個自動飲水機。自動飲水機是主動提供循環(huán)流動的水而我們的警報器是一個被動的監(jiān)測裝置。它的核心使命是“監(jiān)測”和“報警”不負責“供給”。明確了這一點我們就能避免把簡單問題復雜化。具體功能包括水位檢測能準確判斷碗中的水位是否低于預設的安全線。狀態(tài)提示當水位過低時能發(fā)出明確、不易被忽略的提醒。低功耗與安全由于需要長期插電或使用電池工作功耗必須低。同時整個裝置必須絕對防水且使用安全電壓防止寵物啃咬或水濺造成危險。非侵入式安裝最好能不改變寵物原有的飲水習慣不占用碗內太多空間易于清洗。2.2 傳感器選型為什么是光電式水位檢測是項目的核心。常見的水位檢測方案有好幾種我們需要根據(jù)家用寵物水碗的場景逐一分析。浮球開關機械結構簡單便宜。但寵物水碗通常不深浮球需要一定行程才能觸發(fā)精度不高。而且機械部件在碗內寵物喝水時可能碰到產生誤觸發(fā)或損壞。清洗碗時也很麻煩。導電式探針利用水的導電性。需要將兩個金屬探針伸入水中通過檢測探針間電阻來判斷水位。缺點很明顯金屬探針長期浸泡在水中容易電解、氧化影響可靠性如果使用直流電還可能加速電解反應同樣存在清洗不便和寵物可能觸碰的問題。電容式傳感器可以做到非接觸式檢測將傳感器貼在碗的外壁通過檢測介電常數(shù)的變化來感知水位。這是一個很好的方向但對碗的材質厚度、均勻度有要求且校準相對復雜不同材質的碗陶瓷、不銹鋼、塑料響應曲線不同。光電式傳感器紅外對管這是我最終選擇的方案。它由一個紅外發(fā)射管和一個紅外接收管組成。當它們之間沒有水時紅外光直接照射到接收管輸出一種狀態(tài)比如高電平當水位上升漫過傳感器探頭時紅外光在水與空氣的界面發(fā)生折射大部分光線無法到達接收管輸出狀態(tài)翻轉變?yōu)榈碗娖?。選擇光電式傳感器的理由很充分非接觸式檢測相對傳感器可以封裝在一個防水探頭內只有探頭尖端需要接觸水大大減少了與水接觸的面積和腐蝕風險。無機械活動部件可靠性高不怕寵物撥弄。響應速度快光電轉換是瞬間的沒有機械延遲。易于安裝可以設計成夾在碗邊或者用一個重物底座沉入碗底探頭朝上檢測特定高度水位。當然它也有缺點如果水中有很多漂浮物比如寵物毛、灰塵或者氣泡可能會干擾光線傳播造成誤判。但在相對干凈的飲用水中這個問題不突出。我們可以通過軟件防抖邏輯連續(xù)檢測到幾次低水位才報警來進一步規(guī)避。2.3 提醒方式如何有效觸達主人報警方式必須有效。在廚房里放個蜂鳴器你在臥室可能根本聽不見。因此我考慮了多層提醒方案本地聲光報警作為基礎提醒在設備上集成一個LED燈和一個小蜂鳴器。當你在家時可以第一時間注意到。無線網(wǎng)絡推送核心這是解決“人不在家”或“人在其他房間”問題的關鍵。通過Wi-Fi模塊將報警信息推送到手機App如通過MQTT協(xié)議到Home Assistant、或使用微信/釘釘機器人或者發(fā)送一條短信/電話。這樣無論你在公司上班還是在臥室睡覺都能即時收到提醒。冗余設計可以考慮增加一個物理按鍵用于手動測試設備狀態(tài)和消音。基于以上分析我的方案框架確定為STM32或其他低功耗MCU作為主控 光電水位傳感器 Wi-Fi模塊如ESP-01S 本地聲光報警。這個組合在成本、功耗和功能上取得了較好的平衡。3. 硬件設計與實現(xiàn)細節(jié)方案定了接下來就是把想法變成實物。硬件部分是整個項目的基石需要仔細考量每一個細節(jié)。3.1 主控芯片選型STM32與ESP8266的權衡很多人可能會直接想到用ESP8266比如NodeMCU或ESP-01S作為主控因為它自帶Wi-Fi開發(fā)簡單。我最初也是這么想的但仔細評估后我選擇了STM32F103C8T6俗稱“藍色藥丸”作為主控而將ESP-01S僅作為Wi-Fi從機使用。理由如下功耗控制更精細STM32在低功耗模式下的電流可以做到微安級而ESP8266即使在深度睡眠下功耗也相對較高。我們的設備需要7x24小時待機功耗是重要指標。STM32可以大部分時間處于停機Stop模式僅定時喚醒比如每10秒檢測一次傳感器檢測完立刻又進入睡眠。而ESP8266只在需要發(fā)送報警信息時才由STM32喚醒發(fā)送完畢后立即進入深度睡眠。這種主從架構比ESP8266全程待機要省電得多。I/O資源與可靠性STM32的GPIO更多驅動能力更強處理傳感器信號和本地聲光報警更穩(wěn)定。將通信任務剝離給專門的Wi-Fi模塊也使得系統(tǒng)架構更清晰萬一網(wǎng)絡部分出問題不影響核心的檢測功能。成本與靈活性STM32F103和ESP-01S都是極其廉價且常見的模塊組合起來成本可控。未來如果想升級為藍牙報警或增加其他傳感器STM32的擴展性也更好。3.2 水位傳感器模塊制作這是硬件部分的核心。我購買了一對常用的3mm紅外發(fā)射管和接收管。關鍵步驟在于封裝并排固定將發(fā)射管和接收管并排間隔約3-5mm固定在一小段熱縮管或塑料管內。注意管子的發(fā)射/接收窗口要對齊且朝同一方向。灌膠防水使用環(huán)氧樹脂AB膠進行灌封。這是至關重要的一步必須確保膠水完全覆蓋焊點并延伸到導線部分形成完整的防水層。灌膠前最好用硅膠模具做出一個光滑的探頭形狀。我第一次做的時候防水沒做好探頭根部滲水導致內部電路短路報廢。測試與校準封裝完成后萬用表測電阻確認絕緣性。然后搭建一個簡單電路給發(fā)射管串聯(lián)一個150-220歐姆的限流電阻接電源3.3V接收管接一個10K的上拉電阻到3.3V輸出端接STM32的GPIO。將探頭放入空碗和滿水碗中觀察輸出電平的變化。正常情況下空碗空氣中接收管導通輸出低電平約0V浸入水中后輸出變?yōu)楦唠娖郊s3.3V。這個邏輯可以根據(jù)你的電路設計調整。注意紅外對管對可見光也有一定敏感性。最好在探頭外部包裹一層深色熱縮管或涂黑以減少環(huán)境光干擾。也可以在軟件上采用發(fā)射管間歇性點亮比如點亮10ms熄滅90ms接收端只在點亮窗口期采樣的方式來有效抵抗環(huán)境光干擾。3.3 電路連接與電源考慮整體電路原理并不復雜STM32的某個GPIO配置為推挽輸出控制紅外發(fā)射管電源。接收管的輸出信號連接到STM32的另一個GPIO配置為上拉輸入。STM32的另一個GPIO控制一個LED燈和一個有源蜂鳴器。STM32的串口UART與ESP-01S的TXD/RXD交叉連接用于AT指令通信。ESP-01S的CH_PD和RST引腳也由STM32的GPIO控制以便徹底斷電或復位。電源部分需要重點設計。如果打算長期使用電池推薦使用18650鋰電池搭配TP4056充電模塊和升壓模塊將3.7V升到5V或3.3V。如果靠近插座使用5V/1A的USB電源適配器更省心。務必在電源入口處加上濾波電容如100uF電解并聯(lián)0.1uF瓷片以穩(wěn)定電壓。3.4 結構設計與安裝硬件不能只是堆在桌面上。我使用了一個小型防水接線盒Junction Box作為外殼。將STM32核心板、ESP-01S、蜂鳴器等集成在里面。水位傳感器的探頭通過密封格蘭頭電纜防水接頭引出。外殼可以放在水碗旁邊。對于探頭安裝我設計了兩種方式沉底式用一根硬質電線如包塑鐵絲將探頭彎成一個倒L形末端用耐水膠粘一個配重如不銹鋼螺母。這樣探頭可以直立在水碗底部檢測固定高度的水位。優(yōu)點是安裝簡單缺點是可能會被好奇的寵物撥動。側壁夾持式3D打印一個夾子可以夾在碗的邊緣探頭水平伸入碗內。通過調節(jié)夾子的高度可以精確設定報警水位線。這種方式更穩(wěn)固且易于調整。4. 軟件邏輯與避坑指南硬件搭好了接下來就是賦予它靈魂的軟件部分。軟件的核心是低功耗管理和可靠的報警邏輯。4.1 STM32主程序流程我的程序基于HAL庫開發(fā)主要流程是一個大循環(huán)但大部分時間MCU都在睡眠。// 偽代碼邏輯 int main() { 硬件初始化GPIO, UART, RTC... 配置RTC定時喚醒例如10秒 首次讀取傳感器狀態(tài)記錄當前水位 while(1) { // 1. 進入停機模式等待RTC喚醒 HAL_PWR_EnterSTOPMode(...); // 2. 被喚醒后首先重新初始化系統(tǒng)時鐘HAL庫要求 SystemClock_Config(); // 3. 檢測水位傳感器 點亮紅外發(fā)射管 HAL_Delay(5); // 短暫穩(wěn)定 讀取接收管GPIO狀態(tài) 熄滅紅外發(fā)射管 // 4. 邏輯判斷 if (當前狀態(tài) 低水位 上次狀態(tài) 高水位) { // 水位剛剛下降到閾值以下 低水位計數(shù)器; if (低水位計數(shù)器 3) { // 連續(xù)3次檢測確認防抖 觸發(fā)本地報警LED閃爍蜂鳴器響 喚醒ESP-01S并發(fā)送網(wǎng)絡報警 將“報警已觸發(fā)”標志位置位 } } else if (當前狀態(tài) 高水位) { // 水位正?;蛟陂撝狄陨?低水位計數(shù)器 0; // 清零計數(shù)器 if (“報警已觸發(fā)”標志位有效) { 停止本地報警 通知ESP-01S發(fā)送“水位已恢復”消息可選 清除“報警已觸發(fā)”標志位 } } // 5. 更新狀態(tài)準備下一次睡眠 上次狀態(tài) 當前狀態(tài) // 如果處于報警狀態(tài)可以縮短睡眠時間比如改為2秒檢測一次 根據(jù)報警標志位重新配置RTC喚醒時間 } }4.2 與ESP-01S的通信AT指令讓STM32控制ESP-01S發(fā)送網(wǎng)絡報警是軟件部分的一個小難點。ESP-01S通常工作在AT指令模式。通信邏輯如下喚醒與初始化當需要發(fā)送報警時STM32先拉高ESP-01S的CH_PD引腳使其上電然后延遲幾百毫秒等待模塊啟動。接著通過串口發(fā)送“AT\r\n”測試指令等待“OK”回應。確保模塊就緒。連接Wi-Fi發(fā)送ATCWJAP你的SSID,你的密碼\r\n等待連接成功。建立TCP連接假設你有一個內網(wǎng)的服務器比如跑著Node-RED或簡單TCP服務程序的電腦。發(fā)送ATCIPSTARTTCP,服務器IP,端口號\r\n。發(fā)送數(shù)據(jù)連接成功后發(fā)送ATCIPSEND數(shù)據(jù)長度\r\n收到“”提示后發(fā)送實際的報警數(shù)據(jù)例如“PET_WATER_LOW”。清理與休眠發(fā)送完成后發(fā)送ATCIPCLOSE\r\n關閉連接。最后發(fā)送ATGSLP0\r\n讓ESP-01S進入深度睡眠如果支持或者直接拉低CH_PD引腳斷電。踩坑記錄AT指令的響應處理一定要做好超時和錯誤重試機制。我一開始沒有處理“ERROR”響應當Wi-Fi信號不好時指令失敗程序就卡死了。后來加入了每條指令發(fā)送后等待特定響應或超時失敗則重試3次的邏輯穩(wěn)定性大大提升。另外發(fā)送完CIPSEND指令后一定要等待“”提示符再發(fā)數(shù)據(jù)否則數(shù)據(jù)會丟失。4.3 服務器端與消息推送為了接收ESP-01S發(fā)來的報警信息我用了最簡單的方法在家庭局域網(wǎng)內的一臺舊電腦樹莓派更好上用Python寫了一個簡單的TCP服務器。# 簡易TCP服務器示例 (Python) import socket HOST 0.0.0.0 # 監(jiān)聽所有接口 PORT 12345 # 與ESP-01S中設置的端口一致 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() print(f服務器監(jiān)聽在 {PORT} 端口...) while True: conn, addr s.accept() with conn: print(連接來自:, addr) data conn.recv(1024) if data: message data.decode(utf-8).strip() print(收到消息:, message) if message PET_WATER_LOW: # 在這里觸發(fā)推送調用短信API、發(fā)送郵件、或通知Home Assistant print(觸發(fā)低水位報警推送) # 例如調用Home Assistant的REST API觸發(fā)一個自動化 # requests.post(http://homeassistant:8123/api/..., ...)這個服務器收到“PET_WATER_LOW”消息后可以進一步調用其他服務比如Home Assistant通過其REST API觸發(fā)一個自動化在手機App上發(fā)送一條通知。釘釘/微信機器人調用機器人Webhook發(fā)送消息到群聊。短信/電話API使用云服務商的API如阿里云、騰訊云發(fā)送緊急短信。我選擇了集成到Home Assistant中因為它本身就是一個家庭自動化平臺可以很方便地設置“當收到TCP消息時向所有家庭成員手機推送通知”的自動化并且可以記錄歷史報警事件。5. 實測、優(yōu)化與擴展思考電路焊好了代碼燒錄了服務器也跑起來了。接下來就是最激動人心的實測階段也是問題集中爆發(fā)的階段。5.1 初期測試與問題排查我把組裝好的設備放在貓咪的水碗旁探頭用沉底式安裝。頭幾個小時一切正常。但到了晚上問題出現(xiàn)了誤報警。明明水還有大半碗手機卻收到了報警通知。排查過程如下檢查硬件探頭防水完好電路連接正常。用手電筒照探頭發(fā)現(xiàn)即使在水里如果光線從特定角度射入接收管還是能收到一些反射光導致狀態(tài)翻轉。檢查軟件防抖我已經(jīng)設置了連續(xù)3次檢測到低水位才報警按理說能過濾瞬時干擾。觀察現(xiàn)場我蹲在旁邊觀察了很久終于發(fā)現(xiàn)了原因。貓咪喝水時舌頭會快速舔動水面造成水面劇烈波動和產生大量氣泡。當氣泡覆蓋在探頭表面時會形成短暫的“空氣層”導致傳感器誤判為“無水狀態(tài)”。雖然每次波動時間很短但我的檢測周期是10秒一次如果某次采樣剛好捕捉到了氣泡覆蓋的瞬間就會被記錄一次“低水位”。連續(xù)幾次采樣都可能遇到這種情況從而觸發(fā)誤報。5.2 針對性優(yōu)化措施找到了根因解決思路就清晰了軟件層面加強濾波將“連續(xù)檢測到低水位”的次數(shù)閾值從3次提高到5次或6次。同時引入“狀態(tài)穩(wěn)定時間”判斷。只有低水位狀態(tài)持續(xù)超過一定時間比如30秒才最終確認報警。這能有效過濾喝水引起的瞬時波動。硬件層面改善探頭在探頭頭部套上一小段致密的海綿套類似某些水質檢測筆的護套。海綿可以被水浸濕但能阻隔大的氣泡直接附著在光學窗口上同時水分子可以自由通過不影響檢測。這是一個非常有效且低成本的改進。調整檢測周期在非報警狀態(tài)下將檢測周期從10秒延長到30秒甚至60秒。這既降低了功耗也減少了“撞上”貓咪喝水瞬間的概率。一旦進入報警狀態(tài)再將檢測周期縮短以便在水加滿后快速恢復正常狀態(tài)提示。經(jīng)過這些優(yōu)化后設備運行了一周再也沒有發(fā)生誤報警只有在真正水快喝完時才會可靠地提醒我。5.3 功耗實測與續(xù)航評估優(yōu)化后我用萬用表串聯(lián)測量了設備在正常工作模式睡眠60秒喚醒檢測一次下的平均電流。STM32在停機模式下電流約20μA喚醒工作瞬間電流約10mA但持續(xù)時間極短幾十毫秒。ESP-01S僅在報警時被喚醒工作發(fā)送數(shù)據(jù)過程持續(xù)約5-8秒期間電流約70mA。粗略估算一下假設一天報警2次每次ESP-01S工作10秒。那么STM32部分日均功耗 ≈ (20μA * 24h) (10mA * 24*3600/60 * 0.05s) 非常小可忽略。ESP-01S部分日均功耗 ≈ 70mA * 10s * 2 / 3600 ≈ 0.39 mAh。 如果使用一顆2000mAh的18650電池理論續(xù)航可以達到2000 / (0.39/24) ≈ 1230天超過三年當然這是理想情況實際要考慮電池自放電、電路靜態(tài)功耗等但支撐幾個月到一年絕對沒問題。如果使用USB供電則完全無需擔心續(xù)航。5.4 項目擴展方向這個基礎版本實現(xiàn)后還可以根據(jù)需求進行很多有趣的擴展水質監(jiān)測增加一個TDS總溶解固體傳感器探頭可以粗略了解水的潔凈度提醒你該換水了而不僅僅是沒水了。飲水統(tǒng)計通過水位變化的頻率和幅度粗略估算寵物一天的飲水次數(shù)和總量生成簡單的統(tǒng)計圖表對于關注寵物健康的家長很有價值。多碗管理如果你家有多個水點可以設計一個主控設備搭配多個無線水位探頭使用Zigbee或LoRa實現(xiàn)集中監(jiān)控。聯(lián)動自動化與智能插座聯(lián)動報警后自動打開水泵為水碗補水但這需要改造水碗復雜度上升背離了初衷。這個“空水碗警報器”項目從發(fā)現(xiàn)需求到最終穩(wěn)定運行花了我?guī)讉€周末的時間。最大的收獲不是做出了一個設備而是在這個過程中系統(tǒng)地實踐了從需求分析、方案選型、硬件制作、軟件編程到調試優(yōu)化的完整流程。它解決了一個真實、細微卻重要的生活痛點?,F(xiàn)在我可以更安心地專注于工作因為我知道當貓咪的水碗空了我的手機會第一時間告訴我。這種通過自己動手創(chuàng)造的小小確定性帶來的滿足感遠超項目本身。如果你也有類似的困擾不妨也嘗試動手做一個過程中的思考和解決問題的樂趣才是最寶貴的。