GreenPiThumb: A Raspberry Pi Gardening Bot

Michael Lynch

GreenPiThumb: 라즈베리 파이 가드닝 봇

원문은 Michael Lynch님이 에 게재했습니다. 이 블로그 구독하기

소개

이것은 GreenPiThumb의 이야기다. 집안 화분에 자동으로 물을 주는 가드닝 봇이지만, 때로는 식물을 죽이기도 한다.

GreenPiThumb 전체 시스템

이야기는 약 1년 전으로 거슬러 올라간다. 갑자기 식물 하나를 키워보고 싶다는 생각이 들었다. 식물이 있으면 보기에도 좋고, 꼭 필요한 산소도 공급해주며, 손님들에게는 살아있는 무언가를 돌볼 줄 아는 책임감 있는 어른이라는 인상을 줄 수 있을 것 같았다.

하지만 나는 정원사가 아니라 프로그래머다. 식물을 키우려면 매주 몇 번씩 물을 주고 상태를 확인해야 한다. 그럴 바엔 차라리 수백 시간을 들여 그 일을 대신해 줄 로봇을 만드는 게 훨씬 쉽겠다고 생각했다. 식물이 80년만 살아준다면 이득인 셈이다.

왜 GreenPiThumb인가?

내가 맡는 대부분의 소프트웨어 프로젝트가 그렇듯, GreenPiThumb의 가장 큰 동기는 새로운 기술을 배우는 것이었다. 이전에 만든 앱인 ProsperBot은 Go, Ansible, Redis를 익히기 위해 만들었다. GreenPiThumb은 프론트엔드 개발, 특히 JavaScript와 AngularJS를 배울 기회로 보였다.

친구 Jeet은 막 프로그래밍을 배우기 시작한 참이었다. 그래서 GreenPiThumb을 함께 해보지 않겠냐고 물었다. 코드 리뷰, 단위 테스트, 지속적 통합 같은 건강한 소프트웨어 엔지니어링 관행을 배우기에 좋은 기회가 될 것 같았다. Jeet도 흔쾌히 승낙했고, 우리는 두세 달이면 끝날 거라 생각했던 여정을 시작했다.

라즈베리 파이로 구동

Raspberry Pi는 취미 활동가들을 위해 만들어진 작고 저렴한 컴퓨터다. 사람들은 라즈베리 파이를 이용해 미래적인 스마트 미러를 만들고, 오래된 비디오 게임을 구동하고, 전기 스케이트보드를 운전하기도 한다.

라즈베리 파이

나는 지난 몇 년간 라즈베리 파이를 가지고 놀아왔지만, 소프트웨어 쪽 사람이라 저렴한 장난감 서버 외에는 써본 적이 없었다. 대부분의 애호가 커뮤니티에서 라즈베리 파이가 끌리는 이유는 일반 전자기기와 얼마나 잘 연동되는가에 있다.

사용 가능한 센서와 연동 가이드가 워낙 많으니, 라즈베리 파이는 GreenPiThumb에 안성맞춤이었다. 라즈베리 파이를 쓰면 하드웨어 기능을 배우는 도전도 되고, 마침내 그 “GPIO 핀”이 도대체 뭔지 알아낼 수 있을 것 같았다.

MOSFET으로 브레드보드가 녹아내리는 모습

라즈베리 파이와 정체불명의 GPIO 핀

왜 또 다른 라즈베리 파이 가드닝 봇을 만들었나?

라즈베리 파이 기반 가드닝 봇을 만들겠다는 생각을 한 것이 우리가 처음은 절대 아니었다. 우리보다 앞서 나온 멋진 프로젝트로는 PiPlanterPlant Friends가 있었고, 그 외에도 여러 프로젝트가 있었다.

우리가 직접 만들기로 한 이유는 두 가지였다. 직접 만드는 게 재미있다는 것, 그리고 우리 봇의 소프트웨어를 최우선으로 다루고 싶었다는 것.

대부분의 라즈베리 파이 프로젝트는 전자공학에는 능하지만 전문적인 소프트웨어 경험이 없는 애호가들이 만든다. 우리는 그 반대가 되고 싶었다. 소프트웨어는 훌륭하지만, 하드웨어는 간신히 동작하고 때로는 너무 뜨거워져 브레드보드가 녹아내리는 쪽으로.

GPIO 핀

불이 날 뻔했던 초기 프로토타입

GreenPiThumb의 코드는 오픈소스이며 다음과 같은 특징을 갖췄다:

  • 전체 단위 테스트
  • 코드 커버리지 추적
  • 지속적 통합
  • 디버그 로깅
  • 철저한 문서화 – README와 코드 주석 모두
  • 스타일 가이드의 일관된 준수
  • 설치 도구

하드웨어 구조

GreenPiThumb 배선도

GreenPiThumb 배선도 (다운로드 가능한 파일)

라즈베리 파이는 디지털 신호만 읽을 수 있어서 아날로그 센서를 직접 읽지 못한다. 우리는 MCP3008 아날로그-디지털 변환기를 사용해 아날로그 토양 수분 센서와 조도 센서의 값을 디지털로 변환한다.

DHT11 센서는 공기의 온도와 습도를 감지한다. 디지털 신호를 출력하므로 라즈베리 파이에 바로 연결할 수 있다.

마지막으로 12V 워터 펌프가 있는데, 라즈베리 파이는 5V만 출력할 수 있으므로 12V 전원 어댑터를 펌프에 MOSFET과 직렬로 연결한다. 라즈베리 파이는 MOSFET을 디지털 스위치로 사용해 펌프를 끄거나 켤 때 회로를 끊거나 연결한다.

소프트웨어 구조

GreenPiThumb 소프트웨어 아키텍처

GreenPiThumb 소프트웨어 아키텍처

GreenPiThumb 백엔드

백엔드는 GreenPiThumb의 핵심 작업을 담당한다. 다음을 책임지는 Python 앱이다:

  • 물리 센서 관리 (토양 수분, 온도 등)
  • 워터 펌프 켜고 끄기
  • 데이터베이스에 이벤트와 센서 측정값 기록

GreenPiThumb 웹 API

웹 API는 GreenPiThumb의 상태와 이력에 대한 정보를 제공하는 HTTP 인터페이스다. GreenPiThumb 데이터베이스를 얇게 감싼 래퍼로, 모든 것을 JSON으로 변환해 웹 애플리케이션이 이해하기 쉽게 만든다.

GreenPiThumb 웹 대시보드

웹 대시보드는 GreenPiThumb의 현재 상태를 보여주고 시간에 따른 센서 측정값 그래프를 생성한다.

GPIO 핀

우리의 라즈베리 파이로는 인터넷에 공개된 웹 서버 역할을 감당하기에 역부족이지만, 로컬 대시보드와 동일한 정적 미러를 준비했다:

배포

GreenPiThumb을 라즈베리 파이 장치에 배포하기 위해 오픈소스 IT 자동화 도구인 Ansible을 사용한다.

우리는 GreenPiThumb에 필요한 모든 소프트웨어를 배포하기 위해 맞춤형 GreenPiThumb Ansible 설정(Ansible 용어로는 “role”)을 만들었다. 이 Ansible role은 GreenPiThumb의 백엔드와 프론트엔드 코드, 그리고 GreenPiThumb이 의존하는 서드파티 소프트웨어 구성 요소를 다운로드하고 설치한다.

몇 가지 명령어만으로 새 라즈베리 파이 장치에서 이 도구를 사용해 몇 분 안에 GreenPiThumb 소프트웨어 전체를 실행할 수 있다.

가는 길의 난관

GreenPiThumb은 완성까지 1년 넘게 걸렸다. 몇 주씩 진행을 멈추게 한 난관들 때문에 예상보다 훨씬 오래 걸렸다. 아래에서 가장 흥미로웠던 장애물 몇 가지를 소개한다.

물 분배

다른 라즈베리 파이 가드닝 프로젝트들은 흙에 물을 어떻게 퍼뜨리는지 이야기하지 않는데, 우리가 아직도 방법을 찾지 못했으니 아쉬운 일이다.

처음으로 화분에 물을 펌핑했을 때, 튜브가 한 곳으로만 가는 작은 물줄기를 만들어 그 부분만 흠뻑 젖고 나머지 흙은 마른 채로 남았다. 고무 튜브를 화분 안쪽 벽을 따라 감고 구멍을 뚫는 방법을 고려했지만, 흙 중앙까지 물이 충분히 갈지 확신이 서지 않았다. 샤워 헤드를 써보기도 했지만, 튜브에 물이 새지 않게 고정하면서 물줄기 방향을 제어하는 방법을 찾지 못했다.

결국 우리는 “뿌리고 기도하기(spray and pray)” 방식을 택했다. 아파트 안을 둘러보다가 문제를 해결할 만한 물건을 즉흥적으로 집어 들고 나온 해결책이었다. 작은 주방용 고무장갑의 손가락 하나를 잘라 물 튜브에 고무줄을 두 겹으로 단단히 묶어 고정하고, 바느질 바늘과 손톱깎이로 장갑에 구멍을 잔뜩 뚫었다.

펌프를 켜자 잘라낸 장갑 손가락이 즉시 튜브에서 튕겨 나가 아파트 벽 사방에 물을 뿌렸다. 다시 고정했는데, 이번에는 고무줄이 앞으로 밀리지 않도록 바로 앞에 옷핀을 꽂았다.

물 분사기 (정면)물 분사기 (측면)

물 분사기로 변신한 주방 장갑

가장 우아한 해결책은 아니지만, 대체로 잘 작동한다.

원예는 쉬울 줄 알았다

GreenPiThumb에서 가장 큰 도전은 전자공학일 거라 생각했다. 원예는 그리 어렵지 않아 보였다. 특히 강낭콩은 기본적인 원예 기술만 있으면 키울 수 있는 튼튼한 식물로 자주 소개된다.

알고 보니 우리에게는 기본적인 원예 기술조차 없었다. GreenPiThumb은 실내 정원을 가꾸는 인간의 역할을 자동화하려는 것이지만, 뭔가를 자동화하려면 인간이 무엇이 ‘올바른’ 상태인지 알아야 한다. 우리 스스로 얼마나 물을 줘야 하는지 전혀 몰랐기 때문에 GreenPiThumb이 물을 너무 많이 주는지 너무 적게 주는지 판단하기 어려웠다. 그렇게 우리는 의도치 않게 이런 원예 스너프 필름을 만들게 됐다:

수분 측정이 뭐 그리 어렵겠어?

우리를 가장 괴롭힌 문제는 흙이었다.

GreenPiThumb을 만들기 시작할 때 우리는 물을 주는 날에는 토양 수분이 올라가고, 주지 않는 날에는 내려갈 거라 예상했다. GreenPiThumb의 역할은 측정값이 특정 임계값 아래로 떨어질 때마다 물을 추가해 적절한 수분 수준을 유지하는 단순한 일이 될 터였다.

아래에서는 비싸고 복잡한 모델링 소프트웨어를 사용해 우리가 예상했던 GreenPiThumb의 토양 수분 패턴을 시각화했다:

토양 수분 패턴

상상 속 토양 수분 패턴

엉뚱한 측정값

흙은 우리에게 협조하지 않았다. 초기 빌드에서 토양 수분 측정값은 95%에서 100% 사이를 오가다가 서서히 약 99.5%로 수렴했다. 토양 센서를 꺼내 여러 매질에 대고 테스트했다. 공기, 물, 젖은 종이 타월, 손, 완전히 마른 흙. 이 모든 경우에는 그럴듯한 값이 나왔지만, 조금이라도 수분이 있는 흙에서는 센서 값이 거의 100%까지 치솟았다.

토양 수분 수치

토양 수분 측정값, 기존 수분 센서

처음에는 Dickson Chow의 Plant Friends 토양 프로브를 썼지만, SparkFun 토양 센서로 교체했다. 새 센서는 축축한 흙에서 82%를 기록했고, 물을 준 직후에는 85%로 뛰어올랐다. 하지만 몇 시간 안에 다시 82%로 내려가 며칠 동안 그대로 유지됐다. 센서는 3시간 전에 물을 준 흙과 5일 동안 물을 주지 않은 흙을 구분하지 못하는 듯했다.

토양 수분 수치

토양 수분 측정값, SparkFun 수분 센서

흙이 고장 난 것 같다

Miracle-Gro 흙

아마 흙 탓일지도 몰랐다. 우리가 쓴 분갈이용 흙은 Miracle-Gro의 “물을 주기 쉬운 포뮬러”를 내세운 기성 혼합토였다. 좀 의심스럽지 않은가? 분명 절대 마르지 않는 사악한 유전자 조작 흙이었다. 그래서 우리 불쌍한 토양 센서가 그렇게 혼란스러웠던 것이다.

장난치지 않는 흙이 필요했기에 우리는 유기농 분갈이용 흙을 하나 샀다. 테스트로 플라스틱 컵에 유기농 흙을 채우고 물을 준 뒤 바닥에 구멍을 뚫어 물이 빠지게 한 다음, GreenPiThumb 화분의 흙 상태와 맞추기 위해 3일간 그대로 두었다. 3일이 지난 뒤 두 종류의 흙에서 센서를 테스트했다.

결과는 완전히 같은 값이었다. 둘 다 82%. 그러니 흙 탓은 할 수 없었다…

포기하기

더 이상 아이디어가 떠오르지 않아 GreenPiThumb에 영감을 준 프로젝트들을 다시 살펴봤다. 그들은 이 문제를 어떻게 해결했을까?

Plant Friends는 아예 물을 펌핑하지 않는다. PiPlanter는 토양 수분을 측정하지만 수분 수치와 관계없이 정해진 일정에 따라 물을 준다. 구글 검색으로 토양 수분에만 의존해 물을 준다고 주장하는 라즈베리 파이 가드닝 프로젝트 몇 개를 찾았지만, 어느 것도 소스 코드를 공개하거나 결과 데이터를 공유하지 않았다. 따라서 우리는 수분 수치에 기반한 물 주기는 불가능하며, 물리적 세계의 피할 수 없는 한계 속에서 GreenPiThumb이 할 수 있는 최선을 다하고 있다고 가정하는 것이 타당하다고 느꼈다.

우리는 결국 하이브리드 시스템으로 전환하기로 했다. 이제 GreenPiThumb은 흙이 너무 건조해지거나 마지막으로 물을 준 지 7일이 지났을 때 식물에 물을 준다.

완성된 모습

아래는 완성된 GreenPiThumb의 사진들이다:

GreenPiThumb 전체 시스템GreenPiThumb 전체 시스템
GreenPiThumb 전자 장치GreenPiThumb 펌프GreenPiThumb 물탱크

타임랩스가 이 과정 중 가장 재미있는 부분이었다. 이 영상은 첫 번째 강낭콩 배치(R.I.P.)의 모습이다. 식물이 머리 위 근접 앵글을 얼마나 빨리 벗어나 자라는지 미처 깨닫지 못했다. 결국 식물의 전체 생장 주기를 더 잘 담을 수 있는 더 큰 플렉시블 마운트로 바꿨지만, 원래 설정으로도 생장 초반 며칠간의 훌륭한 타임랩스를 담을 수 있었다:

두 번째 배치에서는 생장 기간 내내 카메라를 정확히 같은 위치에 고정했다. 지금까지의 두 번째 배치 진행 상황은 다음과 같다:

배운 점

보이는 것만큼 단순한 건 없다

두세 달이면 끝나는 간단한 프로젝트가 될 줄 알았지만, 보이는 것만큼 단순한 것은 하나도 없었기 때문에 완성까지 1년 넘게 걸렸다.

이 교훈은 탁월한 소프트웨어 에세이스트인 Joel Spolsky에게서 오래전에 배운 것이며, 앞으로도 수많은 소프트웨어 프로젝트에서 계속 배우게 될 교훈일 것이다.

전자공학: 기초부터 시작하기

아두이노 스타터 키트

GreenPiThumb을 시작할 당시 전자공학에 대한 나의 유일한 지식은 고등학교 물리 시간의 희미한 기억뿐이었다. Arduino 스타터 키트를 사서 튜토리얼을 따라 하며 전자공학의 기초를 다졌다.

튜토리얼은 꽤 재미있고 유용했다. 쉬운 것부터 시작해 점진적으로 더 고급 주제로 나아가도록 잘 구성돼 있었다. 전자공학에 관심 있는 초보자라면 누구에게나 이 키트를 추천한다.

하드웨어는 개별적으로 테스트하라

함께 소프트웨어 프로젝트를 해본 몇몇 사람들은 내 코딩 스타일을 “지나치게 꼼꼼하다”거나 “지나치게 깐깐하다”고 묘사했다. 나는 내 코딩 스타일을 “엄격하다”고 생각하는 편이다. 우리는 GreenPiThumb의 소프트웨어 부분을 먼저 구현하면서 각 소프트웨어 구성 요소를 엄격하게 동료 검토하고 하나씩 테스트했다.

하드웨어에 있어서는 전혀 엄격하지 않았다. 다소 무모하고 웃을 정도로 순진했다고 해도 과언이 아니다. 원래 하드웨어 구성 요소를 테스트하는 방식은 GreenPiThumb 소프트웨어의 기본 버전을 작성한 뒤, 테스트 보드에 모든 센서를 연결하고 실행해 어떤 결과가 나오는지 보는 것이었다.

아무것도 나오지 않았다. 하드웨어를 테스트하는 끔찍한 전략이었기 때문이다. 시스템의 모든 전자 부품은 부품 자체가 불량이거나 잘못 설치되어 고장 날 가능성이 있다. 모든 것을 한 번에 연결하니 어떤 부품이 고장 났는지 알 방법이 없었다.

시간이 지나면서 우리는 센서를 개별적으로 테스트하는 법을 배웠다. 각 하드웨어 구성 요소마다 독립적인 진단 스크립트를 만들었다. 이제 하드웨어를 조금이라도 수정할 때마다 가장 먼저 하는 일은 진단 스크립트를 실행해 정상적인 값이 나오는지 확인하는 것이다. 새로운 하드웨어가 작동하지 않을 때는 멀티미터로 체계적으로 근본 원인을 찾는다. 멀티미터를 훨씬 더 일찍 샀어야 했다. 가격은 13달러에 불과했지만, 수많은 시간의 좌절과 머리를 싸매는 일을 덜어줬을 것이다.

소스 코드

부품 목록

아래 표는 GreenPiThumb을 만드는 데 사용한 장비들이다. 우리 모델을 쉽게 따라 할 수 있도록 정확한 부품을 공유하지만, 이 중 다수는 기능적으로 동일한 다른 범용 부품으로 교체해도 된다.

GreenPiThumb 필수 부품

공통 전자 부품

아래 항목들은 여러 프로젝트에 사용할 수 있는 일반적인 전자 도구와 부품들이다. 우리는 전자 장비가 하나도 없어서 구매한 것들이며, 완전성을 위해 포함한다:

원예 용품

선택 부품

감사의 말

이 프로젝트를 도와준 분들께 큰 감사를 전한다:

  • Devon Bray, 그의 프로젝트인 PiPlanter 2는 GreenPiThumb의 하드웨어 측면에 큰 영감을 주었다.
  • Dickson Chow, 그의 프로젝트인 Plant Friends는 유용한 하드웨어 참고 자료가 되어 주었고, 프로젝트 전반에 걸쳐 많은 격려를 보내주었다.
  • Nicole Michaelis, 시간을 내어 이 글의 편집을 도와주었다.
  • 배선 문제로 막혔을 때 도움을 준 /r/raspberry_pi 레딧 커뮤니티(도움 받은 글).

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.

댓글