作者:Cheng Hsun Tseng
- 本文所有圖文來自 Cheng Hsun Tseng 的部落格
種植花花草草總讓人心曠神怡,但是否因為忙碌的生活,常常忘記澆水、施肥或是很少讓它曬曬太陽呢?是時候就是需要科技來幫忙啦!今天要教大家 DIY 做出可遠端監控的自動盆栽!是不是很心動,快來跟著一起做吧!
DIY 自動化盆栽
- 光照部份:
- 當室內光照度不夠時,自動開啟燈光。
- 可設定每日光照時間,因為植物也需要黑暗和光週期,這種效應被稱為光照週期。故該功能只在設定時段進行光照補光,其它時段則自動關閉。
- 澆水部份:
- 當土壤過於乾燥時,自動汲水澆花。
- 可設定自動澆水時間,系統只在此時段內檢查土壤溼度並決定是否澆水,其餘時段則停止自動澆水。
- 可設定每次澆水的秒數以及間隔澆水時間,避免澆過多的水。
- 遠端功能:
- 除了自動進行照光澆水,亦可透過無線的方式遠端手動開啟燈光或幫浦進行照光澆水。
- 可遠端觀看目前燈光及澆水幫浦是否開啟,以及土壤溼度、光照度、空氣溫溼度的曲線圖。
材料準備
- 選擇植物燈
植物燈主要可分兩種,一種是提供類似於太陽的光譜,另一種則提供經過調整供特定栽培植物需要的光譜。
有一點很重要必需知道的是,植物的葉綠素所吸收的光譜範圍主要有兩個:一個是在波長 650 nm ~ 660 nm 的紅光,另一個是波長 430 nm ~ 455 nm 的藍紫光,所以我們經常看到專業的植物燈多是紅藍雙色,可依不同需求有不同的紅藍燈比例。
由於植物光源這部份其知識相當廣且專業,往後可另外再開個專題來討論,在此建議您可先自行 Google 或詢問店家適合的植物燈種類。我在本範例使用的植物燈是在水族館購買,可用於水草缸或一般植物。
- 選擇抽水幫浦
給植物澆水用的幫浦直接到水族館購買沈水馬達即可,瓦數大小要視您的花盆尺寸以及水箱高低而定。您稍後看到本文後方的範例影片,會發現澆花時幫浦出水量小了點,如果您覺得出水量太小,只要加大馬達的瓦數即可。
- 其它材料及零件
- 雨淋管:馬達抽水到花盆後,我們希望它能分散流向花盆中的各區域,而非僅僅流到某個點。我的方式是使用魚缸用的出水雨淋管,原本它的用途是位於魚缸過濾系統上方將水平均分散到過濾綿上,不過用在花盆上分散澆水區域也很適合。
2. 電子零件
(1)繼電器模組:用於 Arduino 控制交流電的植物燈及沈水馬達,所以需要 兩個一路 relay,或直接用兩路的。
(2)SunplusIT RFLink-UART:一對一的無線 UART 模組,我們透過該模組來傳送開燈、澆水的 command,以及感測模組所搜集的資訊值。
(3)Arduino 開發板:搜集並回傳花盆的各種感測數值,並接收來自樹莓派的控制命令執行照光及澆水功能。使用任一版本的 Arduino 皆可,本範例是 MEGA 2560 版本。
(4)樹莓派:建議使用 Raspberry Pi 3 B+,作為本盆栽系統的控制中心,遠端接收種植的即時資訊並分析顯示,可設定照光澆水的排程及時機,下指令進行照光及澆水。
(5)土壤溼度感測器:就使用如下常見的模組。
(6)光敏電阻或光照度感測器模組:您可以使用可直接輸出 Lux 照度單位的 Lux GY-302 BH1750 光照度模組,或者較便宜簡單的光敏電阻。
(7)溫溼度模組:量測目前空氣溫溼度。使用 DHT22 或 DHT11皆可。
盆栽的安裝
Arduino 的安裝
Raspberry Pi 的安裝
樹莓派主要作為遠端監控使用,安裝上比較簡單,僅需要接上按鈕、RFLink-UART 模組及 LCD monitor。
程式說明
- Arduino
下方的程式定義了讀取 Serial 端的 function,當 Serial 端收到了下列字串,便會執行相對應的動作:
a:開燈、b:關燈、c:抽水、d:停止抽水
[learn_more caption=”參考程式碼” state=”open”]String readCommand() {
String recv = “”;
String a;
while (Serial1.available()) {a = Serial1.readString(); // read the incoming data as string
recv = recv + a;
Serial.print(a);
}
Serial.println();
return recv;
}
String cmd = readCommand();
//–> a: power on ligher, b: power off light, c: power on water, d: power off water
//Check Light command
if(cmd.indexOf(‘a’)>=0) {
digitalWrite(pinLightRelay, HIGH);
Serial.print(“Power on the Light.”);
}else if(cmd.indexOf(‘b’)>=0) {
digitalWrite(pinLightRelay, LOW);
Serial.print(“Power off the Light.”);
}
//Check Water command
if(cmd.indexOf(‘c’)>=0) {
digitalWrite(pinWaterRelay, HIGH);
Serial.print(“Power on the Water.”);
}else if(cmd.indexOf(‘d’)>=0) {
digitalWrite(pinWaterRelay, LOW);
Serial.print(“Power off the Water.”);
}
[/learn_more]
下方程式讀取按鈕值,若按下則停止目前的動作。例如,若目前在澆水則停止澆水,若目前沒有在澆水則開始澆水;植物燈也是同樣的動作。
[learn_more caption=”參考程式碼” state=”open”]if(powerLight==1) {
digitalRead(pinLightRelay) ? digitalWrite(pinLightRelay, LOW) : digitalWrite(pinLightRelay, HIGH);
}
if(powerWater==1) {
digitalRead(pinWaterRelay) ? digitalWrite(pinWaterRelay, LOW) : digitalWrite(pinWaterRelay, HIGH);
}
[/learn_more]
下方程式透過 UART 發送目前感測數值回遠端:溫溼度、土壤溼度以及光照度。其傳送格式為:[T:30.2, H:60.5, L:932, W:430],使用[及]分別代表開始及結束字元,T 為溫度、H 為溼度、L 為光照度、W 為土壤溼度。
[learn_more caption=”參考程式碼” state=”open”]Serial1.print(“[T:” + String(temp) + “:0,”);
Serial1.print(“H:” + String(hum) + “:0,”);
Serial1.print(“L:” + String(valueLight) + “:” + String(digitalRead(pinLightRelay)) + “,”);
Serial1.print(“W:” + String(valueWater) + “:” + String(digitalRead(pinWaterRelay)) + “]”);
[/learn_more]
樹莓派(Python)
樹莓派端的程式較複雜,除了要接收 Arduino 傳回的感測值,還需要將這些資訊搜集下來繪製曲線圖,另外,各種設定值及盆栽目前的植物燈及沈水馬達的電源狀態也需要顯示出來,因此,該畫面必須能即時的 update,我使用 matplotlib 來繪製曲線圖,並使用 Opencv 來顯示整體畫面。
讀取 Arduino 回傳的感測值,去掉前後的 [及] 字元。
[learn_more caption=”參考程式碼” state=”open”]def readSerial():
recv = “”
dataString = “”
count = Serial.inWaiting()
if count != 0:
try:
recv = Serial.read(count).decode(‘utf-8’)
except:
pass
if(recv == “[“):
while recv != “]”:
if Serial.inWaiting():
recv = Serial.read(count).decode(‘utf-8’)
if(recv!=”]”):
dataString += recv
time.sleep(0.1)
return dataString
[/learn_more]
使用 OpenCV 定義顯示的畫面為全螢幕。
[learn_more caption=”參考程式碼” state=”open”]
cv2.namedWindow(“Plant Image”, cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty(“Plant Image”, cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
[/learn_more]
產生四張圖表,分別 for 溫溼度、土壤溼度、光照度等。
[learn_more caption=”參考程式碼” state=”open”]figure = plot.figure(num=None, figsize=(18, 7), dpi=70, facecolor=’w’, edgecolor=’k’)
ax_t = figure.add_subplot(2,2,1)
ax_h = figure.add_subplot(2,2,2)
ax_l = figure.add_subplot(2,2,3)
ax_w = figure.add_subplot(2,2,4)
[/learn_more]
繪製曲線圖:清除畫面→設定標題→設定 Y 軸上下限→隱藏 X 軸座標值不顯示→用藍色圓點來繪製。
[learn_more caption=”參考程式碼” state=”open”]x = np.array (timeList_w )
y = np.array (wList)
ax_w.cla()
ax_w.set_title(“Water (degree)”)
ax_w.set_ylim(0, 1024)
ax_w.axes.get_xaxis().set_visible(False)
ax_w.plot ( x, y , ‘bo-‘)
[/learn_more]
將 matplotlib 產生的曲線圖轉為 OpenCV 的 Numpy 且為 BGR 格式,待會兒便可把此圖表用 OpenCV 來整合與其它資訊一起顯示。
遠端監控畫面
在設定的澆水時段內,若土壤溼度小於 threshold 值,則沈水馬達便會自動開始汲水,透過雨淋管灑水至土壤中。灑水時間視您的沈水馬達瓦數而定,若瓦數很大則灑水時間可設定短一點。植物燈也是類似的動作,當您設定好照光時段後,當該時段內光照度不足時,便會自動開啟植物燈。
(責任編輯:葉于甄)