본문 바로가기
기타/라즈베리파이 미니 스마트팜 만들기

라즈베리파이로 미니 스마트팜 만들기 #1 -하드웨어 세팅

by 테크앤아트 2026. 10. 2.
728x90
반응형

 

 

 


 

 

시작하며

라즈베리파이4 한 대로 루꼴라를 자동으로 키우는 미니 스마트팜을 만들고 있다. 이번 글은 그 첫 단계인 Phase 1 - 하드웨어 세팅을 마무리하며 정리한 기록이다.

야외에서 식물을 키운다면 물 주는 타이밍을 놓치거나, 더운 날 금방 꽃대가 올라와 잎이 질겨지는 일이 있을 수 있다. 그래서 실내에서 물·바람·빛을 자동으로 관리하고, 식물 상태를 숫자와 화면으로 확인할 수 있는 시스템을 직접 만들어보기로 했다.

이번 글에서는 프로젝트의 목표와 하드웨어 구성, 부품별 검증 과정과 실측값, 그리고 중간에 바뀐 설계와 삽질한 기록까지 다룬다.

 

 


 

 

프로젝트 개요와 목표

목표는 31×10cm 다이소 화분 하나에서 루꼴라를 최대한 손을 덜 타고 키우는 것이다. 급수·통풍은 파이가 알아서 하고, 조명은 스마트플러그가 시간에 맞춰 켜고 끈다. 사람은 폰이나 PC 브라우저로 상태를 지켜본다.

작물 루꼴라(Eruca sativa) 단독
화분 다이소 텃밭 세트, 31 × 10 × 8.6cm
제어 전자동. 대시보드에 제어 버튼 없음, 수동 개입은 SSH
모니터링 Flask 대시보드(CCTV + 현재값 + 건강 상태) + Grafana(그래프)
카메라 실시간 스트리밍 + 병해충·건강 상태 감지
외부 접속 Tailscale (예정)

 

루꼴라를 고른 이유는 단순하다. 파종 후 25~35일이면 베이비리프로 수확할 수 있고, 겉잎만 잘라내면 다시 자라서 오래 먹을 수 있다. 대신 십자화과라 고온·장일에서 추대가 빠르다. 이게 이 프로젝트 최대의 적이고, 온도 알림과 팬, 14시간 고정 광주기는 전부 이걸 막기 위한 장치다.

 

 


 

 

하드웨어 구성

컨트롤러는 Raspberry Pi 4 Model B 4GB 한 대다. 카메라 스트리밍, OpenCV, MQTT 브로커, 웹 서버, Grafana까지 전부 이 보드 하나에서 돌린다. OS는 Raspberry Pi OS Lite 64-bit(trixie)이고 모니터 없이 SSH로만 운영한다.

분류 부품 역할
센서 DHT22 (베어 4핀) 온습도. 10kΩ 풀업 저항 필요
센서 DFRobot SEN0193 + MCP3008 정전식 토양수분. 파이에 ADC가 없어 SPI ADC 경유
센서 BH1750 조도(lux). 조명 점등 검증용
카메라 Pi Camera Module 3 Standard + FFC 50cm 스트리밍, 건강 감지, 타임랩스
액추에이터 SZH-EK074 2채널 릴레이 CH1 펌프 / CH2 팬
액추에이터 SZH-GNP155 수중펌프 + 실리콘 호스 6/9mm 급수
액추에이터 네오틱스 60mm 5V 팬 통풍
조명 풀나옴 주광색 30cm 10W × 2 식물등
조명 TP-Link Tapo P100 조명 스케줄 (07:00~21:00)
전원 5V 2A 2구 어댑터 펌프·팬 전용 (파이와 별도)

 

부품 선택에서 신경 쓴 것

  • 토양수분 센서는 정전식. 저항식은 전극이 흙 속에서 부식돼 몇 주 만에 값이 틀어진다.
  • 카메라는 Module 3 Standard. NoIR은 초록 잎이 자주색으로 찍혀 색 기반 분석이 불가능하고, Wide는 화면 가장자리가 휜다.
  • 식물등은 주광색 백색. 흔한 적청(보라) 조명은 잎 색을 왜곡해 카메라로 건강 상태를 볼 수 없게 만든다.
  • MOSFET 대신 릴레이. 흔히 파는 IRF520 모듈은 파이의 3.3V GPIO로는 완전히 열리지 않는다.

 

조명을 파이에서 뺀 이유

처음엔 파이가 릴레이로 조명까지 제어하려 했다. 그런데 220V를 직접 만지는 건 위험하고, 파이가 죽으면 조명도 같이 멈춘다. 그래서 조명은 Tapo 스마트플러그의 앱 스케줄에 전부 맡겼다. 파이는 BH1750으로 "지금 켜져 있어야 하는데 실제로 켜졌는가"만 검증한다. 전구 고장, 플러그 오프라인, 앱 스케줄 실수를 이 검증 하나로 잡을 수 있다.

 

전원 설계

원칙은 파이 어댑터는 파이 전용이다. 펌프와 팬은 별도 5V 어댑터에서 전원을 받고, 파이는 릴레이로 스위칭 신호만 보낸다. 콘센트는 세 구로 나눴다.

1 Tapo → 식물등 2개 앱 스케줄로 on/off
2 5V 2구 어댑터 → 펌프 + 팬 항상 켜짐
3 파이 어댑터 (5V 3A) 항상 켜짐

*부하 어댑터의 (−) 선은 파이 GND(20번 핀)와 반드시 공통으로 묶는다.

 

GPIO 핀맵

헤더를 세 구역으로 나눠 배선 다발이 엉키지 않게 했다. 센서 세 개는 전부 3.3V이고, 브레드보드 레일에는 5V를 절대 끌어오지 않는다. 5V를 쓰는 건 릴레이 코일뿐이다.

구역 부품 파이 핀
A — 파이 직결 센서 BH1750 SDA / SCL 3 / 5 (I2C)
A — 파이 직결 센서 DHT22 DATA 7 (GPIO4)
B — 릴레이 신호 VCC / GND 2 (5V) / 6
B — 릴레이 신호 IN1 펌프 / IN2 팬 11 (GPIO17) / 13 (GPIO27)
C — SPI + 브레드보드 MCP3008 DIN / DOUT / CLK / CS 19 / 21 / 23 / 24
C — SPI + 브레드보드 3.3V 레일 / GND 레일 1 / 9
공통 접지 부하 어댑터 (−) 20

 

 


 

 

시스템 구성

파이 한 대가 센서를 읽고, 릴레이로 펌프와 팬을 돌리고, 웹 화면까지 직접 띄운다. 조명만 Tapo가 따로 돌고, 파이는 빛으로 점등 여부만 확인한다.

점선은 전기적으로 연결되지 않은 경로다. Claude 비전 분석만 인터넷이 필요하고, 인터넷이 끊겨도 나머지는 전부 그대로 돈다.

 

데이터 흐름

센서는 1분마다 읽어 MQTT로 발행하고, SQLite에는 10분 평균만 저장한다. 대신 급수 직후, 알림 전후, 팬 가동 중처럼 중요한 순간은 1분 간격으로 촘촘히 남긴다. SD카드 쓰기를 줄이면서도 필요한 데이터는 놓치지 않으려는 절충이다.

MQTT 토픽 내용 주기
farm/telemetry 온도, 습도, 토양수분, 조도 1분
farm/health 황화 비율, 갈색 반점, 잎 구멍 수, AI 분석 요약 1시간
farm/status 조명·펌프·팬 상태, 파종 일차, 수확 카운트다운 변경 시
farm/alert 고온, 건조, 조명 이상, 병해 위험 등 발생 시
farm/event 수확 기록 (SSH로 수동 발행) 발생 시

 

건강 감지 3단계

카메라로 병해충을 잡아내는 방법은 세 단계로 나눴다. 루꼴라 병해충 학습 데이터셋이 사실상 없어서 직접 모델을 학습시키는 건 현실적이지 않았다.

  1. 환경 기반 위험 경보 - 습도 85% 이상에 18~22°C가 몇 시간 이어지면 노균병 위험을 알린다. 카메라 없이, 증상이 보이기 전에 경고할 수 있어 실전에서 가장 쓸모 있다.
  2. OpenCV 지표 - 1시간마다 잎의 노란 비율, 갈색 반점 비율, 잎에 난 구멍 수를 센다. 병명은 몰라도 "뭔가 변했다"는 건 싸게 잡아낸다. 구멍 수는 루꼴라의 단골 해충인 벼룩잎벌레의 신호다.
  3. Claude 비전 분석 - 하루 한 번, 또는 2단계에서 이상이 잡히면 사진을 Claude API로 보내 문제 유형, 확신도, 권장 조치를 받는다. 병명 판정은 이 단계가 맡는다.

한계도 분명하다. 위에서만 찍으니 진딧물이나 노균병 곰팡이가 생기는 잎 뒷면은 볼 수 없다. 그래서 결과는 확진이 아니라 "직접 확인해 보라"는 신호로 쓴다.

 

 


 

 

현재까지의 진행 기록 (Phase1 완료)

원칙은 하나였다. 부품 하나 배선 → 단독 스크립트로 검증 → 실측값 기록 → 다음 부품. 한꺼번에 다 꽂고 안 되면 원인을 찾을 수가 없다. 결과적으로 온습도(DHT22)를 빼고 전부 통과했다. DHT22는 베어 4핀 모듈이라 풀업 저항이 필요한데, 아직 저항을 사지 않아 다음 단계로 넘겼다.

 

파이 기본 세팅

OS를 굽고 SSH로 붙은 뒤 I2C·SPI를 켜고, SD카드 수명을 위한 설정 세 가지를 넣었다. 스왑을 압축 메모리에 두는 zram, /var/log를 RAM에 올리는 log2ram, 시스템 로그 상한을 거는 journald 50MB 제한이다. 파이는 24시간 돌아가는데 SD카드는 쓰기에 약하다.

Wi-Fi 절전도 꺼야 했다. 기본값으로 두면 파이가 유휴 시 무선칩을 재워서 SSH가 수시로 끊긴다. systemd 서비스로 부팅 때마다 절전을 끄게 등록했다.

 

조명과 조도

식물등은 위 선반 밑면에 매달았고, 조사 거리는 24cm다. 화분 아래 5.3cm 박스를 받치면 18.7cm가 된다.

배치 조사 거리 화분 중앙 lux DLI (14시간)
박스 없음 24.0cm 8,900 6.4
박스 받침 (채택) 18.7cm 12,350 8.9

 

루꼴라 목표 DLI가 8~12라 박스를 받쳤다. 다만 잎이 8~10cm를 넘으면 조명과 너무 가까워지니 그때 박스를 뺀다.

BH1750은 화분 가운데가 아니라 왼쪽 끝에 달았다. 가운데에 두면 잎이 자라면서 센서를 덮는다. 이 위치에서 조명 ON은 약 6,150 lux, OFF는 방불 수준인 약 200 lux다. 30배 차이라 점등 판정 기준을 1,000 lux로 잡았다.

 

토양수분

SEN0193은 아날로그 출력이라 MCP3008(10비트 ADC)을 거쳐 SPI로 읽는다. 공기 중(건조)과 물컵(포화)에서 값을 재 환산식을 만들었다.

  • 건조 811 / 포화 448 → soil_% = (811 − raw) / 363 × 100
  • 급수 기준 40% ≈ raw 666
  • 마른 배양토에 꽂았을 때 raw 약 782

포화값 448은 물 기준이라 흙에서는 이만큼 내려가지 않는다. 실제 흙 기준 재보정은 빈 흙 리허설 때 한다.

 

릴레이·펌프·팬

릴레이 모듈은 Active LOW였다. 신호를 LOW로 줘야 붙는다. gpiozero에서 active_high=False로 쓰면 된다.

펌프 유량은 예상과 완전히 달랐다. 카탈로그는 시간당 80~120L인데, 다공 호스를 물리니 초당 약 1ml였다. 카탈로그의 3% 수준이다. 처음엔 호스 구멍에서 물이 아예 안 나왔는데, 펌프 압력으로는 작은 구멍의 표면장력을 못 이겨서였다. 구멍을 1mm 이상으로 넓혀 해결했다.

항목 처음 설계 실측 반영
1회 급수 3초 60초 (약 60ml)
1회 최대 작동 (failsafe) 5초 90초
재가동 대기 30초 180초
하루 최대 횟수 — 4회 (240ml 상한)

물탱크는 화분보다 낮은 바닥에 둬서 펌프를 끈 뒤 물이 계속 빨려 나오는 사이펀 현상을 막았다. 실제로 정지되는 걸 확인해서 체크밸브는 빼기로 했다.

 

카메라

동봉된 15cm 리본은 짧아서 50cm FFC로 바꿨다. 화분 정면 위에 거치해 화분이 화면 가로로 꽉 차는 구도를 잡았다.

LED 조명 아래서 찍으니 사진에 가로 줄무늬가 생겼다. 한국 전기는 60Hz라 LED가 초당 120번 깜빡이는데, 노출이 1.3ms로 짧아 깜빡임이 그대로 찍힌 것이다. --flicker-period 8333us로 노출을 깜빡임 주기(8.33ms)의 정수배에 맞추니 줄무늬가 사라졌다.

 

스모크 테스트

마지막으로 펌프와 팬을 돌리면서 센서값이 흔들리는지 봤다. 모터와 센서가 접지를 공유하고 있어서, 모터 노이즈가 센서로 새면 값이 튄다.

구간 토양수분 raw 조도 lux
대기 781~783 6,081~6,225
팬 가동 781~782 6,087~6,252
펌프 가동 781~783 6,076~6,231

토양수분이 ±1 안에서 그대로였다. 조도의 3% 출렁임은 대기 상태에서도 똑같아서 모터 영향이 아니다. 통과.

 

 


 

 

중간에 바뀐 설계

설계서는 이번 단계를 거치며 v9까지 왔다. 직접 만져보면서 처음 계획이 맞지 않는 부분이 계속 드러났고, 그때마다 과감하게 뺐다.

 

Unity 디지털 트윈 → 웹 대시보드

처음엔 Unity로 화분을 3D로 재현하는 디지털 트윈을 만들 생각이었다. 그런데 식물 상태를 확인하는 데 3D가 꼭 필요한가를 따져보니 답이 아니었다. 카메라 실시간 화면과 숫자, 그래프면 충분했다. Flask 대시보드 + Grafana로 바꾸면서 작업량이 크게 줄었다. 제어 버튼도 없앴다. 사람이 끼어들 일이 없게 만드는 게 목표니까.

 

잎 면적 측정 → 건강 상태 감지

원래 카메라의 핵심 용도는 잎 면적으로 성장 곡선을 그리는 것이었다. ArUco 마커로 픽셀을 ㎠로 환산하고, 렌즈 초점도 고정할 계획이었다.

그런데 야외에서 루꼴라를 키워본 경험을 떠올려 보니, 2~3주면 잎이 화분을 덮어버린다. 그 뒤로는 면적이 더 늘지 않으니 곡선이 평평해진다. 겉잎을 잘라 먹는 수확 방식까지 섞이면 해석이 더 어려워진다. 그래서 면적 측정을 통째로 빼고, ArUco와 초점 고정도 같이 뺐다. 카메라는 실시간 스트리밍과 병해충·건강 상태 감지에 쓰기로 했다.

 

카메라 사선 위 → 정면 위

잎을 입체적으로 보려고 사선 45°로 거치할 계획이었는데, 사각형 카메라 모듈을 비스듬히 고정하기가 생각보다 어려웠다. 정면 위로 바꾸니 화분이 화면에 가로로 꽉 차고, 이미지 회전 처리도 필요 없어졌다.

 

급수 호스 뒤쪽 → 가운데

다공 호스를 화분 뒤쪽 가장자리에 붙일 계획이었지만, 화분 가운데를 지나게 하고 그 양옆으로 씨앗을 두 줄 뿌리기로 바꿨다. 양쪽 줄에 물이 고르게 간다. 토양수분 센서는 호스 구멍 바로 아래를 피해 한쪽 줄 근처에 꽂았다. 바로 밑에 꽂으면 급수 직후 값만 튀어서 판단이 왜곡된다.

 

 


 

 

잘 안됐던 부분 기록

scp가 10KB/s — Wi-Fi 문제인 줄 알았다

카메라로 찍은 사진을 윈도우로 옮기는데 scp 속도가 10KB/s였다. 340KB 사진 한 장에 30초. 이 속도면 영상 스트리밍은 불가능하니 Wi-Fi부터 의심했다.

신호 세기는 −40dBm으로 아주 좋았고, SD카드 읽기도 45MB/s로 정상이었다. 마지막으로 파이에서 python3 -m http.server를 띄우고 같은 파일을 HTTP로 받아보니 **3.35MB/s(약 27Mbps)**가 나왔다. 병목은 Wi-Fi가 아니라 scp 자체였다. 이후로 파일은 HTTP로 받는다. 덕분에 스트리밍 해상도 근거도 생겼다. 27Mbps면 1280×720 / 10fps MJPEG도 여유가 있다.

 

파이가 네트워크에서 사라졌다

이번 단계에서 가장 오래 붙잡은 문제다. 카메라 위치를 조정하던 중 갑자기 SSH가 끊기더니, 파이가 공유기 목록에서 사라졌다.

모니터가 없으니 판단 근거는 파이의 초록 LED 하나뿐이었다. 그걸 보고 추측을 거듭했다. SD카드 불량을 의심해 OS를 다시 굽고, 다른 SD카드로도 구워보고, 공유기를 재부팅하고, 주변 부품을 전부 뽑아봤다. bootfs에 wpa_supplicant.conf를 넣는 옛날 방식도 시도했는데, 지금 OS(trixie)는 NetworkManager를 써서 그 파일을 아예 무시한다. 몇 시간을 썼지만 원인은 하나도 좁혀지지 않았다.

결국 micro HDMI 케이블을 사서 모니터에 연결했다. 파이 4는 일반 HDMI가 아니라 micro HDMI라 케이블이 따로 필요하다. 화면을 보자마자 상황이 정리됐다.

  • 부팅은 완전히 정상이었다. 로그인 프롬프트까지 떴다.
  • 화면에 My IP address is 127.0.1.1. 자기 자신 주소뿐이다. Wi-Fi만 안 붙은 상태였다.
  • nmcli device wifi list로 보니 공유기도 잘 잡혔다. 첫 스캔엔 5GHz만 보였는데, 다시 스캔하니 2.4GHz도 다 보였다.

그 자리에서 nmcli로 5GHz에 연결하니 바로 붙었다. 그리고 OS 설치 도구(Imager)가 만든 2.4GHz 프로필의 자동 연결을 꺼서 두 프로필이 충돌하지 않게 했다. 이참에 공유기에서 파이 IP를 고정했다. 매번 바뀌는 IP를 찾는 것도 시간 낭비였다.

[교훈: 헤드리스 장애는 추측하지 말고 HDMI부터 연결한다.] LED 깜빡임으로 몇 시간 헤맨 것을 화면 한 번이 5분 만에 풀었다.

 

 


 

 

정리와 다음 단계

Phase 1을 마치며 남은 건 이렇다. 센서·펌프·팬·카메라가 전부 수동 스크립트로 동작하고, 급수량·조도·토양수분 기준값이 실측으로 채워졌다. 배양토도 미리 채워 뒀다. 온습도 센서만 저항이 오면 끼우면 된다.

다음은 Phase 2 - 파이 소프트웨어다.

  1. 프로젝트 골격과 config.yaml — 이번에 잰 값들을 설정 파일로 옮긴다
  2. 센서 루프와 MQTT 발행
  3. 조건부 급수와 failsafe — 하루 두 번 흙을 검사해 마를 때만 물을 준다
  4. 팬 온도 제어, 조명 점등 검증, 알림
  5. 카메라 스트리밍과 건강 지표 분석, Claude 비전 분석
  6. SQLite 로깅, systemd 등록, 24시간 무인 테스트

소프트웨어가 완성되면 대시보드를 붙이고, 빈 흙으로 며칠 리허설을 돌린 뒤에야 씨앗을 뿌린다. 루꼴라 첫 수확까지는 아직 멀었다.

 

 


 

 

 

728x90
반응형