GreenPiThumb: A Raspberry Pi Gardening Bot

Michael Lynch

GreenPiThumb:用 Raspberry Pi 打造的園藝機器人

原文由 Michael Lynch 發布,訂閱此部落格

前言

這是 GreenPiThumb 的故事:一個會自動幫室內植物澆水的園藝機器人,但有時也會把植物弄死。

GreenPiThumb 系統全貌

故事要從大約一年前說起,那時我突然很想養一盆室內植物。擺一盆植物看起來不錯,能提供我急需的氧氣,還能讓來訪的客人覺得我是個負責任的大人,有能力照顧一個生命。

但我是個程式設計師,不是園丁。如果養了植物,我每週就得澆水好幾次、檢查它的健康狀況。我覺得,與其那樣,不如花個幾百小時打造一個機器人來幫我做還比較輕鬆。要是這盆植物能活到八十歲,那我還算有點賺到。

為什麼要做 GreenPiThumb?

跟我接過的大多數軟體專案一樣,做 GreenPiThumb 的主要動機是想學新技術。之前我為了自學 Go、Ansible 和 Redis 而寫了 ProsperBot。而 GreenPiThumb 則是我學習前端開發,特別是 JavaScript 與 AngularJS 的機會。

我的朋友 Jeet 剛開始學寫程式,所以我問他有沒有興趣一起合作 GreenPiThumb。這對他來說似乎是個學習良好軟體工程實務的好機會,像是程式碼審查、單元測試和持續整合。Jeet 答應了,於是我們就踏上了這段原本以為只要兩、三個月就能完成的旅程。

由 Raspberry Pi 驅動

Raspberry Pi 是一款為自造者打造的小型、平價電腦。大家用它來打造充滿未來感的智慧鏡重溫老電玩遊戲,還有人拿來驅動電動滑板

Raspberry Pi

過去幾年我一直在玩 Raspberry Pi,但我畢竟是做軟體的,從來沒把它當成便宜的玩具伺服器以外的用途。對大多數玩家社群來說,Raspberry Pi 最大的魅力在於它能很好地與各種消費性電子產品整合。

以它豐富的感測器與整合教學資源來看,Raspberry Pi 自然是 GreenPiThumb 的不二之選。我也想說,藉由使用 Raspberry Pi,可以挑戰自己去了解它的硬體能力,終於搞懂那些「GPIO 接腳」到底是做什麼的。

MOSFET 熔化麵包板

Raspberry Pi 與它神祕的 GPIO 接腳

為什麼還要再做一個 Raspberry Pi 園藝機器人?

我們當然不是第一批想到要用 Raspberry Pi 做園藝機器人的人。在我們之前,就有兩個很酷的專案,分別是 PiPlanterPlant Friends,當然還有其他幾個類似的作品。

我們決定自己做一個,原因有二:自己動手做東西很有趣,而且我們希望這個機器人的軟體是被當作一等大事來對待。

大多數 Raspberry Pi 專案都是由很懂電子、但缺乏專業軟體經驗的愛好者打造的。我們想反其道而行——軟體很強,但硬體勉強能動,有時還會熱到把麵包板都熔掉。

GPIO 接腳

一個早期的原型,很可能有「快要起火」的問題

GreenPiThumb 的程式碼是開源的,特色包括:

  • 完整的單元測試
  • 程式碼覆蓋率追蹤
  • 持續整合
  • 除錯日誌
  • 詳盡的文件——包含 README 與程式碼註解
  • 嚴格遵循程式碼風格指南
  • 安裝工具

硬體架構

GreenPiThumb 接線圖

GreenPiThumb 接線圖(可下載檔案

Raspberry Pi 讀取的是數位訊號,所以無法直接讀取類比感測器。我們使用 MCP3008 類比數位轉換器來將類比的土壤濕度感測器與光感測器的訊號轉成數位讀值。

DHT11 感測器負責偵測空氣中的溫度和濕度。它輸出的是數位訊號,所以可以直接接到 Raspberry Pi 上。

最後是 12V 抽水馬達,但 Raspberry Pi 只能輸出 5V,所以我們將 12V 電源轉接器MOSFET 串聯後接到馬達上。Raspberry Pi 把 MOSFET 當作數位開關,需要關閉或啟動馬達時,就切斷或接通電路。

軟體架構

GreenPiThumb 軟體架構

GreenPiThumb 軟體架構

GreenPiThumb 後端

後端負責 GreenPiThumb 的核心工作。這是一個 Python 應用程式,主要負責:

  • 管理實體感測器(土壤濕度、溫度等)
  • 控制抽水馬達的開關
  • 將事件與感測器讀值記錄到資料庫中

GreenPiThumb 網頁 API

網頁 API 是一個 HTTP 介面,用來提供 GreenPiThumb 的狀態與歷史資訊。它是包在資料庫外的一層薄薄的封裝,會把所有資料轉成 JSON,讓網頁應用程式更容易讀取。

GreenPiThumb 網頁儀表板

網頁儀表板會顯示 GreenPiThumb 的即時狀態,並將感測器讀值隨時間的變化繪製成圖表。

GPIO 接腳

我們的 Raspberry Pi 還不太能勝任對外開放的網頁伺服器,不過這裡有一個與我們本地端完全相同的 GreenPiThumb 儀表板靜態鏡像:

部署

為了將 GreenPiThumb 部署到 Raspberry Pi 裝置上,我們使用了 Ansible 這套開源的 IT 自動化工具。

我們為 GreenPiThumb 需要的所有軟體,建立了一個客製化的 GreenPiThumb Ansible 設定(以 Ansible 的術語來說就是「role」)。這個 Ansible role 會下載並安裝 GreenPiThumb 的後端與前端程式碼,以及它所依賴的第三方軟體元件。

只要幾個指令,就能在一台全新的 Raspberry Pi 裝置上使用這個工具,並在幾分鐘內讓 GreenPiThumb 的所有軟體順利跑起來。

一路上的坑坑疤疤

GreenPiThumb 花了一年多才完成,遠比預期久得多,因為中途遇到了好幾個讓進度一卡就是數週的難關。下面我會描述幾個比較有趣的障礙。

澆水的難題

其他 Raspberry Pi 園藝專案都沒有提到他們怎麼把水均勻灑在土壤上,這有點可惜,因為到現在我們也還沒完全搞定這個問題。

第一次把水抽進花盆時,水管把細細的水流集中衝向同一個點,結果那一小塊完全浸濕,其他土壤卻還是乾的。我們曾考慮把橡膠管沿著花盆內壁繞一圈並在管子上戳洞,但不確定這樣能不能讓中間的土壤也喝到水。也試過接蓮蓬頭,但一直想不出怎麼把它牢牢又不漏水地固定在水管上,同時還能控制水流方向。

最後我們採取了「亂噴亂灑」的做法。這是個在公寓裡東張西望、隨手抓東西來試著解決問題而誕生的解法。我們把小小的廚房手套剪下一根手指,用緊緊纏了兩圈的橡皮筋固定在水管上,再用縫衣針和指甲剪在手套上戳出好多小洞。

一打開馬達,手套那截斷指立刻從水管上噴飛,水灑得整面牆都是。我們重新裝回去,這次在橡皮筋前面插了一根安全別針,這樣它就不會往前滑掉了。

灑水器(正面)灑水器(側面)

變身灑水器的廚房手套

這不是最優雅的解法,但大致上還堪用。

原本以為園藝才是最簡單的部分

原本以為 GreenPiThumb 最大的挑戰會是電子部分,園藝應該不難。尤其是四季豆,常常被形容為生命力強韌、只要有基本園藝技巧就能種好的植物。

結果證明,我們連基本的園藝技巧都沒有。GreenPiThumb 的本意是要自動化照顧室內花園中需要人力的部分,但要自動化任何事情,人得先知道什麼叫「正確」。我們根本不知道該澆多少水,所以很難判斷 GreenPiThumb 是澆太多還是太少。結果一不小心就拍出了這部園藝版的虐殺影片:

量個濕度能有多難?

最讓我們頭痛的問題,竟然是土。

一開始打造 GreenPiThumb 時,我們預期土壤濕度會在澆水的日子上升,沒澆水的日子下降。GreenPiThumb 的工作就很單純:只要讀值低於某個門檻,就補水來維持正確的濕度。

下面,我們用了昂貴又複雜的建模軟體,來視覺化我們原本預期 GreenPiThumb 會看到的土壤濕度變化:

土壤濕度變化

想像中的土壤濕度變化

錯誤的讀值

土壤就是不肯配合我們。在最初的版本中,土壤濕度讀值在 95% 到 100% 之間擺盪,然後慢慢收斂到約 99.5%。我們把土壤感測器拔出來,拿去測各種介質:空氣、水、濕紙巾、我們的手、完全乾燥的土。這些測試看起來讀值都還算合理,但只要是有點濕氣的土壤,感測器的讀值就會直接飆到接近 100%。

土壤濕度

土壤濕度讀值,原始濕度感測器

我們一開始用的是 Dickson Chow 的 Plant Friends 土壤探針,後來換成了 SparkFun 土壤感測器。新感測器在潮濕土壤中讀到 82%,澆完水後會立刻跳到 85%。但幾個小時內,它又會掉回 82%,然後好幾天都維持在那裡。這個感測器似乎無法分辨三小時前剛澆過水的土,和已經五天沒澆水的土。

土壤濕度

土壤濕度讀值,SparkFun 濕度感測器

我覺得我的土壞掉了

Miracle-Gro 土壤

也許是土的問題。我們用的盆栽土是 Miracle-Gro 的這款預拌混合土,主打「好澆水配方」。有點可疑,對吧?顯然這就是那種邪惡的、基因改造過、永遠不會乾的土。難怪我們可憐的土壤感測器會這麼困惑。

我們需要不會跟我們玩把戲的土,所以買了這款有機盆栽土。為了測試,我們在一個塑膠杯裡裝滿有機土、加水、在底部戳洞讓它排水,然後靜置三天,讓它模擬 GreenPiThumb 花盆裡的土壤狀態。三天後,我們在兩種土裡都測試了感測器。

結果讀值完全一樣:兩種都是 82%。所以,也不能怪土……

放棄

黔驢技窮之後,我們回頭去看那些啟發 GreenPiThumb 的專案。他們是怎麼解決這個問題的?

Plant Friends 根本沒有抽水功能。PiPlanter 雖然會量土壤濕度,但澆水是照固定時程,不管濕度多少都會澆。用 Google 找了一下,確實有幾個 Raspberry Pi 園藝專案聲稱他們完全依據土壤濕度來澆水,但沒有一個有公開原始碼或分享成果數據。因此,我們覺得可以合理地假設,單靠濕度來澆水是不可能的,而在物理世界某些不可違的限制下,GreenPiThumb 已經盡力做到最好了

最後我們決定改用混合式系統。現在的 GreenPiThumb 會在土壤太乾距離上次澆水已過七天時,才幫植物澆水。

最終成品

以下是我們完成的 GreenPiThumb 實體照片:

GreenPiThumb 系統全貌GreenPiThumb 系統全貌
GreenPiThumb 電子零件GreenPiThumb 馬達GreenPiThumb 儲水槽

縮時攝影是整個過程中最有趣的部分。這段是我們第一批四季豆的縮時(R.I.P.)。我們沒想到植物會這麼快就長到超出近距離俯視的角度。後來我們換成了更大、更可彎折的支架,可以用更好的角度拍完整個生長週期,但原本的設定還是捕捉到了最初幾天很棒的生長縮時:

第二批我們就讓相機在整個生長過程中保持完全相同的位置。以下是第二批到目前為止的生長紀錄:

經驗與收穫

沒有什麼事像看起來那麼簡單

我原本以為這會是個兩三個月就能搞定的單純專案,結果卻花了一年多才完成,因為沒有什麼事是像看起來那麼簡單的。

這是我很久以前就從傑出的軟體隨筆作家 Joel Spolsky 那裡學到的一課,而且我預期在未來許多軟體專案中,還會一再學到同樣的教訓。

電子學:從基礎開始

Arduino 入門套件

在開始 GreenPiThumb 時,我對電子學的唯一認識,只剩下高中物理課的模糊記憶。我買了 Arduino 入門套件,照著教學一步步建立電子學的基礎。

這些教學出乎意料地有趣又實用。它們從簡單的內容開始,再循序漸進地帶到更進階的主題。我會推薦這個套件給任何對電子學有興趣的初學者。

單獨測試硬體

曾跟我合作過軟體專案的人,有的會形容我在寫程式時「龜毛」或「過於吹毛求疵」。我比較喜歡把自己的編碼風格稱為「嚴謹」。我們先實作 GreenPiThumb 的軟體部分,一個元件一個元件地嚴格進行同儕審查與測試。

輪到硬體時,我們就完全不嚴謹了。甚至可以說有點草率、天真得可笑。我們原本測試硬體元件的流程是:先寫一個陽春版的 GreenPiThumb 軟體,把所有感測器都接上測試板,跑起來看看會產生什麼結果。

結果什麼都沒有。它什麼都沒產生。因為那是個糟透了的硬體測試策略。系統裡的每個電子元件都有可能故障,可能是元件本身瑕疵,也可能是安裝錯誤。一次把所有東西都接起來,我們根本無從判斷是哪個環節出了問題。

久而久之,我們學會了單獨測試每個感測器。我們為每個硬體元件建立了獨立的診斷腳本。現在每次調整硬體,第一件事就是跑一遍診斷腳本,確認讀值是否合理。當新的硬體零件無法運作時,我們會用三用電表有系統地找出根本原因。我們早該更早買三用電表的。它只要 13 美元,卻能幫我們省下無數小時的挫折與搔頭苦思。

原始碼

零件清單

下表列出我們打造 GreenPiThumb 所使用的器材。我們分享確切的零件型號,是為了讓你更容易照著做,但其中許多都是通用的零件,你完全可以用功能相同的替代品。

GreenPiThumb 必備零件

通用電子零件

以下項目是許多專案都會用到的通用電子工具與零件。我們當時完全沒有任何電子設備,所以才全都買齊,為求完整也一併列出:

園藝用品

選配零件

致謝

特別感謝以下幫助我們完成這個專案的人:

  • Devon Bray,他的專案 PiPlanter 2 對 GreenPiThumb 的硬體部分帶來很大的啟發。
  • Dickson Chow,他的專案 Plant Friends 提供了很實用的硬體參考,並在整個專案過程中給了我們許多鼓勵。
  • Nicole Michaelis,她自願花時間幫忙編修這篇文章。
  • /r/raspberry_pi Reddit 社群,因為他們的幫忙,讓我們在被接線問題卡住時得以解決。

本文章由 muse-spark-1.2-contributor 進行翻譯

留言