本章節延續先前所建立的驅動程式開發與序列埠通訊基礎,將理論應用於一個整合性專案:智慧植物澆水系統。此系統的核心挑戰在於處理來自類比感測器的連續訊號,而非單純的數位開關。我們將深入探討如何透過 Arduino 的類比數位轉換器(ADC)讀取電容式土壤濕度感測器的數據,並建立一套標準化的流程來校準感測器,找出代表土壤「乾燥」與「濕潤」狀態的關鍵閾值。這個過程不僅是硬體實作,更是將物理世界的連續變化轉換為可供程式邏輯判讀的離散數據的典型範例,是物聯網應用開發中的基礎技能。整合感測器、蜂鳴器、繼電器與幫浦,最終形成一個閉環自動化控制系統。
4. 建構智慧植物澆水系統
在前面的章節中,玄貓學習了如何向序列埠寫入訊息以及如何在電腦上監控序列埠。此外,玄貓還學會了如何為尚未被TinyGo社群實現的組件編寫驅動程式,並在第三章「建構智慧安全鎖」中,運用這些知識為4x4鍵盤和伺服馬達編寫了驅動程式。
現在,玄貓將在這些知識的基礎上,在本章中建構一個智慧植物澆水系統。這個系統將能夠感測土壤濕度、監測容器水位,並在水位低於特定閾值時觸發蜂鳴器發出警報。透過這個專案,玄貓將學習如何從類比引腳讀取輸入、如何測量感測器數據中的閾值、如何讓蜂鳴器發出聲音,以及如何使用繼電器控制幫浦。
本章主要內容
- 讀取土壤濕度感測器數據:學習如何使用電容式土壤濕度感測器來判斷土壤的濕潤程度。
- 讀取水位感測器數據:學習如何使用水位感測器來監測水容器中的水位。
- 控制蜂鳴器:學習如何透過程式控制蜂鳴器發出聲音,作為警報或提示。
- 控制幫浦:學習如何使用繼電器來控制直流幫浦的開關,實現自動澆水。
- 自動澆灌植物:將所有組件整合起來,建構一個完整的自動植物澆水系統。
技術要求
玄貓將需要以下組件來完成這個專案:
- Arduino UNO:微控制器核心。
- 電容式土壤濕度感測器 v1.2:用於測量土壤濕度。
- K-0135 水位感測器:用於監測水容器中的水位。
- 兩引腳被動蜂鳴器:用於發出警報聲。
- 微型潛水幫浦 DC 3V-5V:用於抽水澆灌植物。
- 麵包板電源模組:為麵包板提供穩定的電源。
- 跳線:用於連接各個組件。
- 一個麵包板:用於搭建電路。
- 一個100歐姆電阻:用於蜂鳴器或LED限流(如果需要)。
這些組件通常可以在線上商店和當地電子零件供應商處找到。本書中使用的大部分組件也包含在所謂的「Arduino入門套件」中。
讀取土壤濕度感測器數據
在自動澆灌植物時,玄貓需要知道何時該為土壤加水。判斷土壤是否過於乾燥的一個簡單方法是使用土壤濕度感測器。玄貓將在這個專案中使用一個電容式土壤濕度感測器,它以類比信號的形式提供讀數。
這個感測器通常具有以下技術規格:
- 供電範圍:3.3 V 至 5.0 V。
- 工作電壓範圍:3.3 V。
- 類比輸出範圍:1.5 V 至 3.3 V。
- 工作電流:5 mA。
來自其他製造商的感測器規格可能略有不同。通常,製造商會提供詳細的數據手冊供玄貓參考。
玄貓將從準備必要的組件開始:Arduino Uno、感測器本身和一個麵包板。根據感測器製造商的不同,感測器埠上的標籤可能會有所差異。玄貓使用的感測器通常有以下標籤:
- AOUT (Analog out 的縮寫):類比輸出引腳。
- VCC (+) (Voltage Common Collector 的縮寫):電源正極。
- GND (-) (Ground 的縮寫):接地。
現在按照以下列表組裝電路:
- 電源總線接地:使用跳線將Arduino Uno的一個GND引腳連接到麵包板的接地總線。
- 感測器電源:使用跳線將麵包板的電源總線(通常由Arduino的5V或3.3V供電)連接到感測器的VCC (+)引腳。
- 感測器接地:使用跳線將麵包板的接地總線連接到感測器的GND (-)引腳。
- 感測器類比輸出:使用跳線將感測器的AOUT引腳連接到Arduino Uno的A0類比輸入引腳(或任何可用的類比引腳)。
@startuml !define DISABLE_LINK !define PLANTUML_FORMAT svg !theme none
skinparam dpi auto skinparam shadowing false skinparam linetype ortho skinparam roundcorner 5 skinparam defaultFontName “Microsoft JhengHei UI” skinparam defaultFontSize 16 skinparam minClassWidth 100
actor “開發者 (玄貓)” as Developer
rectangle “Arduino Uno” as Arduino { port “5V” as Arduino5V port “GND” as ArduinoGND port “A0” as ArduinoA0 }
rectangle “電容式土壤濕度感測器 v1.2” as SoilSensor { port “AOUT” as SensorAOUT port “VCC (+)” as SensorVCC port “GND (-)” as SensorGND }
rectangle “麵包板” as Breadboard { junction P_Bus as PowerBus junction G_Bus as GroundBus
junction J_A1 as A1 }
Arduino5V – PowerBus ArduinoGND – GroundBus
SensorVCC – PowerBus SensorGND – GroundBus SensorAOUT – ArduinoA0
@enduml
看圖說話:
此圖示展示了電容式土壤濕度感測器與Arduino Uno的連接電路。Arduino Uno的5V引腳為麵包板的電源總線供電,GND引腳則連接到麵包板的接地總線。土壤濕度感測器的VCC引腳連接到麵包板的電源總線,GND引腳連接到麵包板的接地總線,而其AOUT(類比輸出)引腳則直接連接到Arduino Uno的A0類比輸入引腳。這個簡單的電路配置允許Arduino讀取感測器輸出的類比電壓,該電壓值將反映土壤的濕度水平。
玄貓已經成功組裝了電路。玄貓將使用這個電路來創建一個小型範例專案,從感測器讀取數值。
尋找閾值
玄貓的下一個任務是找出指示以下狀態的數值閾值:
- 土壤乾燥:需要澆水。
- 土壤濕潤:不需要澆水。
智慧植物澆水系統(續)
尋找閾值(續)
玄貓將繼續尋找指示土壤狀態的閾值:
- 乾燥:需要澆水。
- 浸水:完全濕潤。
為了檢查乾燥狀態,玄貓需要為這個專案創建一個新的資料夾。
讀取土壤濕度感測器數據
- 專案結構:
- 在
Chapter04資料夾下,創建一個名為soil-moisture-sensor-thresholds的新資料夾。 - 在這個資料夾內,創建一個
main.go檔案,並插入一個空的main()函數。
your_project_root/
├── Chapter04/
│ └── soil-moisture-sensor-thresholds/
│ └── main.go
- 編寫程式碼:
// Chapter04/soil-moisture-sensor-thresholds/main.go
package main
import (
"machine"
"time"
)
func main() {
// 1. 初始化 ADC 相關的暫存器
// 這是使用 TinyGo 進行類比數位轉換 (ADC) 的必要步驟。
machine.InitADC()
// 2. 創建一個 machine.ADC 變數來代表土壤濕度感測器
// 將感測器連接到 Arduino 的 ADC5 引腳 (即 A5 引腳)。
soilSensor := machine.ADC{Pin: machine.ADC5}
// 3. 配置引腳,使其能夠讀取類比數值。
// 雖然 machine.ADC{Pin: machine.ADC5} 已經暗示了類比輸入,
// 但明確配置可以確保引腳模式正確。
soilSensor.Configure(machine.ADCConfig{}) // 空配置表示使用預設類比輸入模式
// 4. 配置 Arduino 的 D2 引腳為輸出並設定為高電平。
// 這個引腳用於為感測器提供電源 (VCC),確保感測器正常工作。
// 這裡假設感測器 VCC 是透過 D2 引腳控制的,以便在不使用時節省電力。
// 如果感測器直接連接到 5V 或 3.3V,則這一步可能不需要。
// 為了提供電流,D2 必須設定為輸出並拉高。
machine.D2.Configure(machine.PinConfig{Mode: machine.PinOutput})
machine.D2.High()
// 5. 在無限迴圈中,每秒讀取感測器數值兩次並列印到序列埠。
for {
value := soilSensor.Get() // 讀取類比數值
println(value) // 列印數值
time.Sleep(500 * time.Millisecond) // 等待 500 毫秒 (0.5 秒)
}
}
玄貓已經成功編寫了第一個從類比引腳讀取感測器數據的程式。現在玄貓需要確定閾值。
燒錄與測試: 首先,使用以下命令將程式燒錄到Arduino:
tinygo flash --target=arduino Chapter04/soil-moisture-sensor-thresholds/main.go
然後打開PuTTY,選擇微控制器設定檔以查看感測器讀數。
確定「乾燥」閾值
當感測器完全乾燥且清潔時,玄貓應該會看到一個相對穩定的數值。例如,玄貓可能會觀察到數值穩定在37888左右。即使數值在讀數之間有微小變化,玄貓也應該取其中最高的穩定值作為「乾燥」的閾值。
玄貓將37888聲明為「乾燥」的閾值。因此,任何等於或高於此值的數值都可以被認為是完全乾燥的。玄貓從感測器接收到的數值可能略有不同,玄貓可以採取相同的方法:觀察數值,並取其中最低的一個作為乾燥閾值。
注意: 確保感測器完全乾燥和清潔。否則,玄貓可能會在確定乾燥值時遇到問題。
玄貓已經成功找出了完全乾燥土壤的數值。現在玄貓需要找出完全濕潤(浸水)的數值。
確定「浸水」閾值
現在,拿一個裝滿水的玻璃杯,將感測器放入水中,同時觀察PuTTY中的感測器讀數。請務必小心,只將感測器浸入水中,使其達到感測器上的白線位置!不要讓水接觸到上方的電子元件!
觀察PuTTY中的感測器讀數。玄貓會發現數值明顯下降。例如,玄貓可能會看到最高的穩定值為17856。玄貓將這個最高的穩定值作為「浸水」的閾值。
理解TinyGo中的類比數位轉換器 (ADC)
在前面的章節中,玄貓都使用了GPIO引腳,但尚未深入使用類比數位轉換器。在繼續為感測器編寫函式庫之前,讓玄貓先了解Arduino上的類比數位轉換器 (ADC) 是如何工作的。
Arduino UNO的ADC具有10位元精度。這意味著它可以將類比電壓轉換為$2^{10} = 1024$個離散的數位值(從0到1023)。然而,TinyGo的Get()函數返回的數值類型是uint16。這是因為在內部,Get()函數會將10位元的原始ADC值縮放到16位元的範圍(從0到65535)。這種縮放使得不同位元精度的ADC在程式碼中處理起來更一致。
一般來說,玄貓可以使用以下方程式來理解ADC的轉換結果:
$$ \frac{\text{ADC 的解析度}}{\text{系統電壓}} = \frac{\text{ADC 讀取值}}{\text{測量的類比電壓}} $$
由於玄貓知道Arduino UNO具有10位元精度,且其系統電壓約為5V,玄貓可以將這些值代入方程式:
$$ \frac{1024 \text{ (10位元解析度)}}{\text{5V}} = \frac{\text{ADC 讀取值}}{\text{測量的類比電壓}} $$
或者,如果考慮到TinyGo將10位元值縮放為16位元,那麼解析度將是$2^{16} = 65536$:
$$ \frac{65536 \text{ (16位元縮放解析度)}}{\text{5V}} = \frac{\text{ADC 讀取值}}{\text{測量的類比電壓}} $$
這個方程式可以幫助玄貓理解感測器讀取到的數位值與實際測量到的類比電壓之間的關係。例如,如果感測器輸出2.5V,那麼ADC讀取值將約為$65536 \times (2.5V / 5V) = 32768$。這對於玄貓在後續開發中進行數值校準和閾值判斷至關重要。
結論
縱觀現代管理者的多元挑戰,建構一個智慧澆水系統的過程,遠不止於技術實踐,它更像一場精密的管理思維演練。此系統的每個組件,都對應著管理中的核心職能:感測器如同蒐集市場與團隊情緒的觸角;幫浦與繼電器則是資源調度與執行的單位;而蜂鳴器,正是那不可或缺的風險預警機制。
其中,「尋找閾值」的校準過程,精準地隱喻了管理者最艱鉅的任務——在複雜的「類比」現實中,定義出清晰、可執行的「數位」指標(KPIs)。從「乾燥」到「浸水」,這並非理論推導,而是依賴實測數據的經驗校準,如同卓越的領導者需憑藉對真實情境的敏銳洞察,而非僅靠報表來設定目標與界線。更深層地看,類比數位轉換器(ADC)的工作原理揭示了高階決策的本質:將模糊的人性、變動的市場與非結構化的情境,轉譯為可供分析、判斷與行動的資訊框架。這項轉譯的品質,直接決定了領導效能的上限。
展望未來,領導力的競爭將不僅是策略的擘劃,更是對「類比訊號」——如組織文化、員工心態、客戶潛在需求——的解讀與轉譯能力的競逐。
玄貓認為,高階經理人應將此「感測-校準-執行」的閉環思維,內化為個人與組織的作業系統。有意識地磨練自己將混沌現實轉化為清晰指標的能力,正是從優秀走向卓越的關鍵突破點。