새싹인삼 스마트 재배기

BLE 기반 자동 관수 · 자동 조명 · 실시간 모니터링

(주)더바이오그룹 — 더 좋은 농장 프로젝트

App React Native BLE Arduino Uno ATmega328P GPIO 2CH Relay Active-LOW 12V Motor + LED
BLE 4.0
무선 통신
DHT22
온습도 센서
2채널
릴레이 제어
3화면
모바일 앱
456줄
펌웨어 코드
21MB
Android APK
⚙ Arduino Uno ⚛ React Native ♲ BLE 4.0 { } JSON Protocol ☊ EEPROM ☉ DHT22

시스템 구성도

Arduino Uno 기반 BLE 무선 제어 스마트 재배기

React Native 스마트폰 제어 HC-05 BLE Module 9600 baud DHT22 온습도 센서 Pin D2 | ±0.5°C DS1302 RTC Real-Time Clock D11 / D12 / D13 Arduino Uno ATmega328P 5V / 16MHz / EEPROM 2CH 릴레이 Active-LOW D8(CH1) / D9(CH2) 관수 펌프 Motor (CH1) LED 조명 Grow Light (CH2) BLE D6/D7 SoftSerial D2 D11-D13 D8/D9 LEGEND 센서 연결 BLE 통신 릴레이 출력 무선 (BLE)

BLE 통신

HC-05 블루투스 모듈, SoftwareSerial(D6/D7), 9600baud JSON 프로토콜

HC-05 9600 baud

환경 센서

DHT22 온도(±0.5°C) 및 습도(±2%RH) 실시간 측정, D2 연결

DHT22 온습도

타이머 제어

DS1302 RTC 모듈, 관수/조명 자동 on/off, EEPROM 설정 유지

DS1302 RTC 자동 스케줄

릴레이 출력

2채널 릴레이, CH1=D8 모터, CH2=D9 조명, Active-LOW 방식

2채널 Active-LOW

하드웨어 구성

Arduino Uno 핀 배치 및 주변기기 연결

부품 핀 번호 기능 방향 비고
HC-05 RX D6 BLE 수신 Arduino→BLE SoftwareSerial
HC-05 TX D7 BLE 송신 BLE→Arduino SoftwareSerial
DHT22 D2 온습도 센서 Input OneWire 데이터
DS1302 SCK D13 RTC 클럭 Output Serial Clock
DS1302 IO D12 RTC 데이터 I/O Bidirectional
DS1302 RST D11 RTC 리셋 Output Chip Enable
릴레이 CH1 D8 모터(관수) Output Active-LOW
릴레이 CH2 D9 조명(LED) Output Active-LOW

Active-LOW 릴레이 동작 원리

GPIO 출력 릴레이 상태 회로 부하
HIGH (1) 열림 (OFF) 개방 정지
LOW (0) 닫힘 (ON) 통전 구동
릴레이는 Active-LOW 방식. HIGH=OFF, LOW=ON. setup()에서 반드시 HIGH 초기화 → 전원 인가 오작동 방지.
void setup() { pinMode(8, OUTPUT); // Motor Relay pinMode(9, OUTPUT); // Light Relay digitalWrite(8, HIGH); // OFF (Active-LOW) digitalWrite(9, HIGH); // OFF (Active-LOW) btSerial.begin(9600); // HC-05 BLE dht.begin(); // DHT22 센서 EEPROM_READ(); // 저장된 설정 복구 }

전원부

Arduino Uno 보드 자체 전원: USB 또는 DC 5V
릴레이 구동 및 부하 전원: 외부 DC 12V 어댑터
릴레이 NO/COM 단자를 통해 12V 부하(모터, LED)에 전원 공급
Arduino GND와 12V GND 공통 접지 필수
Arduino 5V 외부 12V

통신부

HC-05 모듈: BLE 4.0 무선 통신
SoftwareSerial 라이브러리: D6(RX), D7(TX)
통신 속도: 9600 baud (HC-05 기본값)
데이터 포맷: JSON UTF-8 직렬 통신
BLE 4.0 JSON

회로 블록 다이어그램

핀 연결 및 전원 분배 상세 블록도

LEGEND 센서 신호선 BLE 통신선 릴레이 제어선 부하 출력선 무선 BLE 전원부 USB / DC 5V Arduino 보드 전원 DC 12V 어댑터 릴레이 구동 전원 Arduino Uno ATmega328P | 5V / 16MHz EEPROM 16B SoftwareSerial D2 D6 D7 D8 D9 D11 D12 D13 DHT22 온도 / 습도 VCC · DATA · GND DS1302 RTC SCK · IO · RST CR2032 배터리 HC-05 BLE SoftwareSerial 9600 baud / BLE 4.0 React Native 스마트폰 앱 2CH 릴레이 모듈 IN1(D8) · IN2(D9) · VCC · GND NO/COM/NC × 2 | Active-LOW 관수 펌프 DC 모터 / 12V LED 성장 조명 Grow Light / 12V 5V → VIN 12V D2 D11 RST D12 IO D13 SCK D6→RX D7←TX BLE D8 CH1 D9 CH2 CH1 NO/COM CH2 NO/COM

BLE 통신 프로토콜

JSON 기반 양방향 BLE 4.0 통신 — 5개 메시지 타입

Service UUID
FFE0
Characteristic UUID
FFE1
메시지 종결자
__FIN__
Baud Rate
9600
App BLE Arduino Response App request serial process notify BLE notify callback

SENSOR_STATUS

매 3초 폴링 READ

앱에서 3초 간격으로 디바이스 상태를 폴링합니다. 온습도 센서값, 모터/조명 설정값, 현재 동작 상태를 일괄 반환합니다.

Request
{"type":"SENSOR_STATUS","values":[0,0]}
Response 필드 명세
필드 타입 예시 설명
TYPE string "SENSOR_STATUS" 메시지 타입 식별자
DEVICE_NAME string "TBF_02" 디바이스 식별자 (BLE 광고명)
TEMP float 25.5 현재 온도 (°C) — DHT22 센서
HUM float 50.0 현재 습도 (%) — DHT22 센서
MOTOR_INTERVAL_IN_SEC int 40 모터 1회 가동 시간 (초)
MOTOR_TIME_MAX_TICK int 1800 모터 전체 주기 (초) — 30분 배수
LIGHT_RUN_INTERVAL int 3600 조명 점등 시간 (초) — 1시간 단위
LIGHT_STOP_INTERVAL int 3600 조명 소등 시간 (초) — 1시간 단위
MOTOR_STATUS int 1 / 0 모터 현재 상태 — 1=ON, 0=OFF
LIGHT_STATUS int 1 / 0 조명 현재 상태 — 1=ON, 0=OFF
Response 예시
{"TYPE":"SENSOR_STATUS", "DEVICE_NAME":"TBF_02", "TEMP":25.5,"HUM":50, "MOTOR_INTERVAL_IN_SEC":40, "MOTOR_TIME_MAX_TICK":1800, "LIGHT_RUN_INTERVAL":3600, "LIGHT_STOP_INTERVAL":3600, "MOTOR_STATUS":1, "LIGHT_STATUS":0}__FIN__

SET_MOTOR

운영 모드 WRITE

모터의 가동 시간과 전체 주기를 설정합니다. 설정값은 EEPROM에 즉시 저장되어 전원 복구 후에도 유지됩니다.

Request
{"type":"SET_MOTOR","values":[intervalSec, cycleSec]}
제약조건 cycleSec % 1800 === 0 — 30분 단위 필수
파라미터 범위 단위 설명
values[0] 10 ~ 120 1회 가동 시간
values[1] 1800 × N 전체 주기 (30분 배수)
Response
{"TYPE":"SET_MOTOR","RESULT":"1"}__FIN__
💾
EEPROM 즉시 저장 — 설정값이 비휘발성 메모리에 기록되어 정전 또는 리셋 후 자동 복원됩니다.

SET_LIGHT

운영 모드 WRITE

조명(LED)의 점등/소등 주기를 설정합니다. 특수값 -1로 상시 ON 또는 상시 OFF를 지정할 수 있습니다.

Request
{"type":"SET_LIGHT","values":[runSec, stopSec]}
제약조건 값 % 3600 === 0 — 1시간 단위 필수 (특수값 제외)
특수값 (Special Values)
runSec = -1
상시 ON (24시간)
stopSec = -1
상시 OFF
파라미터 범위 단위 설명
values[0] 3600 ~ 43200 or -1 점등 시간 (1~12시간)
values[1] 3600 ~ 43200 or -1 소등 시간 (1~12시간)
Response
{"TYPE":"SET_LIGHT","RESULT":"1"}__FIN__

TEST_MOTOR

테스트 DEBUG

장비 점검용 단시간 모터 테스트 명령입니다. 운영 설정에 영향을 주지 않습니다.

Request
{"type":"TEST_MOTOR","values":[3,6]}
3
가동 시간
6
전체 주기
Response
{"TYPE":"TEST_MOTOR","RESULT":"1"}__FIN__
🔧 장비 점검용 단시간 테스트. 3초 가동3초 정지를 반복합니다. EEPROM 설정값은 변경되지 않습니다.

TEST_LIGHT

테스트 DEBUG

LED 동작 확인용 테스트 명령입니다. 운영 설정에 영향을 주지 않습니다.

Request
{"type":"TEST_LIGHT","values":[3,3]}
3
점등 시간
3
소등 시간
Response
{"TYPE":"TEST_LIGHT","RESULT":"1"}__FIN__
💡 LED 동작 확인용. 3초 점등 / 3초 소등을 반복합니다. EEPROM 설정값은 변경되지 않습니다.

에러 처리 및 연결 관리

3-Strike Auto Disconnect Policy

JSON 파싱 실패 시 오류 카운터가 증가합니다. 3회 연속 실패 시 자동으로 BLE 연결을 해제(disconnect)합니다. 정상 메시지를 수신하면 카운터는 즉시 0으로 리셋됩니다.

1
Strike 1
2
Strike 2
3
Strike 3
💀
Auto Disconnect
__FIN__ 메시지 종결자

모든 BLE 메시지는 __FIN__ 종결자로 끝납니다. BLE 4.0의 20바이트 MTU 제한으로 인해 하나의 JSON 메시지가 여러 패킷으로 분할 전송됩니다. 수신 측에서는 __FIN__이 감지될 때까지 내부 버퍼에 데이터를 누적한 뒤, 종결자를 제거하고 완성된 JSON 문자열을 파싱합니다.

{"TYPE":"SEN
+
SOR_STATUS"
+
,"TEMP":25.5
+
...}
+
__FIN__
JSON.parse()
메시지 타입 방향 카테고리 EEPROM 저장 설명
SENSOR_STATUS READ 폴링 전체 상태 조회 (3초 주기)
SET_MOTOR WRITE 운영 O 모터 가동/주기 설정
SET_LIGHT WRITE 운영 O 조명 점등/소등 주기 설정
TEST_MOTOR WRITE 테스트 모터 단시간 점검 (3초/6초)
TEST_LIGHT WRITE 테스트 LED 단시간 점검 (3초/3초)

데이터 흐름

앱 ↔ BLE ↔ Arduino ↔ 센서/릴레이 간 통신 흐름

React Native App Android / iOS SENSOR_STATUS SET_MOTOR SET_LIGHT BLE 4.0 FFE0 / FFE1 9600 baud Arduino MCU ATmega328P parseJSON() processCommand() updateRelays() DHT22 + RTC sensor data 2CH 릴레이 Motor + LED request response read GPIO Request (App→MCU) Response (MCU→App) Hardware Control 3회 실패 시 자동 연결 해제

통신 시퀀스 SENSOR_STATUS 예시

App BLE Arduino Sensors 1 {"type":"SENSOR_STATUS","values":[0,0]} 2 Serial forward 3 DHT22.read() / RTC.read() 4 JSON response 5 Notify (FFE1) 6 UI 업데이트

모바일 앱 화면 구성

React Native 기반 크로스플랫폼 앱 (Android / iOS)

React Native 0.61.5 react-native-ble-manager 7.1.1 react-navigation 1.0.0 APK 21MB

블루투스 연결 자동 스캔

TBF Scanner
TBF_01
-45 dBm
연결
TBF_02
-62 dBm
연결
검색된 디바이스 없음
스캔 시작
BLE 4.0 자동 스캔 (5초 타임아웃)
신호 강도(RSSI) 실시간 표시
TBF_ prefix 디바이스 자동 필터링
연결/해제 원터치 제어

메인 대시보드

TBF_02
연결됨
온도
25.5
°C
습도
50
%
모터 구동중
30분에 40초씩 구동
조명 정지
24시간 구동 / 0시간 정지
3초 간격 자동 센서 폴링
모터/조명 실시간 상태 표시
설정 화면 원터치 이동
연결 상태 실시간 모니터링

설정 화면

모터 설정
자동
테스트
가동 시간
10s
15s
20s
30s
40s
1m
반복 주기
30분
1시간
2시간
저장
취소
모터/조명 독립 설정
자동/테스트 모드 전환
BLE 명령 즉시 전송
EEPROM 영구 저장

타이머 제어 로직

모터(관수)와 조명(LED)의 독립적 자동 스케줄링

모터 (관수 펌프)
30분 주기 타임라인 ON 40초 가동 29분 20초 대기 0s 1800s cycle repeat 다음 주기 (자동 반복)
타이머 의사코드
// 매 1초 실행
MOTOR_TIME_TICK++
if (TICK < MOTOR_INTERVAL(40s)):  MOTOR = ON
if (TICK >= MOTOR_INTERVAL):       MOTOR = OFF
if (TICK >= MOTOR_MAX(1800s)):    TICK = 0  // 리셋
40초
가동 시간
29분20초
대기 시간
30분
전체 주기
조명 (LED 성장등)
조명 주기 (ON/OFF 설정 가능) ON OFF RUN_INTERVAL STOP_INTERVAL cycle repeat 0s RUN+STOP 다음 주기 (자동 반복)
타이머 의사코드
// 매 1초 실행
LIGHT_TIME_TICK++
if (TICK < RUN_INTERVAL):              LIGHT = ON
if (TICK >= RUN && < RUN+STOP):  LIGHT = OFF
if (TICK >= RUN+STOP):              TICK = 0  // 리셋

// 수동 모드 (-1)
RUN  = -1:  상시 ON (24시간)
STOP = -1:  상시 OFF
자동 모드 1~12시간 단위 ON/OFF 자동 전환
수동 모드 상시 ON 또는 상시 OFF 고정
테스트 모드 3초 점등 / 소등 반복
듀티 사이클 비교
Motor 40s / 1800s = 2.2% 2.2% Light (auto) RUN = STOP = 50% typical 50% Light (ON) 상시 ON = 100% 100% Light (OFF) 상시 OFF = 0% 0%

EEPROM 메모리 맵

전원 차단 시에도 설정값 유지 (4 × float, 16 bytes)

인덱스 주소 변수명 타입 기본값 설명
0 0x00-0x03 MOTOR_TIME_MAX_TICK float 1800 (30분) 모터 전체 주기
1 0x04-0x07 MOTOR_INTERVAL_IN_SEC float 40 모터 가동 시간
2 0x08-0x0B LIGHT_RUN_INTERVAL float 60 조명 점등 시간
3 0x0C-0x0F LIGHT_STOP_INTERVAL float 60 조명 소등 시간
EEPROM.get() / EEPROM.put() 사용. float형 4바이트씩 저장. BLE로 설정 변경 시 즉시 EEPROM에 기록하여 전원 복구 후에도 마지막 설정 유지.
0x00 - 0x03 MOTOR_MAX (1800) 0x04 - 0x07 MOTOR_INT (40) 0x08 - 0x0B LIGHT_RUN (60) 0x0C - 0x0F LIGHT_STOP (60) Total: 16 bytes (4 × float32)
EEPROM 읽기 (부팅 시)
EEPROM_READ()
void EEPROM_READ() {
    EEPROM.get(0,  MOTOR_TIME_MAX_TICK);
    EEPROM.get(4,  MOTOR_INTERVAL_IN_SEC);
    EEPROM.get(8,  LIGHT_RUN_INTERVAL);
    EEPROM.get(12, LIGHT_STOP_INTERVAL);
}
EEPROM 쓰기 (BLE 설정 변경 시)
EEPROM_WRITE()
void EEPROM_WRITE() {
    EEPROM.put(0,  MOTOR_TIME_MAX_TICK);
    EEPROM.put(4,  MOTOR_INTERVAL_IN_SEC);
    EEPROM.put(8,  LIGHT_RUN_INTERVAL);
    EEPROM.put(12, LIGHT_STOP_INTERVAL);
}

펌웨어 상태 머신

Arduino 메인 루프 기반 상태 전이

INIT (초기화) IDLE (대기) BLE_RECEIVE SENSOR_READ TIMER_TICK RELAY_UPDATE BLE_SEND setup 완료 BLE 수신 1초 경과 SENSOR_STATUS SET_MOTOR/LIGHT 응답 전송 ON/OFF 전환 완료 완료
상태 트리거 동작 다음 상태
INIT 전원 ON setup(), EEPROM 읽기, 핀 초기화 IDLE
IDLE - 메인 루프 대기 BLE_RECEIVE or TIMER_TICK
BLE_RECEIVE btSerial.available() JSON 파싱, 명령 분류 SENSOR_READ or RELAY_UPDATE
SENSOR_READ SENSOR_STATUS 명령 DHT22, RTC 데이터 읽기 BLE_SEND
TIMER_TICK millis() >= 1000 MOTOR/LIGHT_TICK 증가 RELAY_UPDATE
RELAY_UPDATE 타이머 or BLE 명령 digitalWrite() 릴레이 제어 IDLE
BLE_SEND 응답 준비 완료 JSON 직렬화, btSerial.print() IDLE
loop() 메인 루프
Arduino loop()
void loop() {
    // 1. BLE 수신 체크
    if (btSerial.available()) {
        parseJSON(received);
        processCommand(type, values);
    }

    // 2. 1초 타이머
    if (millis() - lastTick >= 1000) {
        lastTick = millis();
        MOTOR_TIME_TICK++;
        LIGHT_TIME_TICK++;
        updateRelays();
    }
}

부품 목록 (BOM)

프로토타입 1대 기준 필요 부품

# 부품명 모델/사양 수량 역할 비고
1 메인보드 Arduino Uno (ATmega328P) 1 중앙 제어 16MHz, 32KB Flash
2 BLE 모듈 HC-05 / HC-06 1 무선 통신 (9600baud) BLE 4.0
3 온습도 센서 DHT22 (AM2302) 1 온도/습도 측정 ±0.5°C, ±2%RH
4 RTC 모듈 DS1302 1 실시간 시계 CR2032 배터리
5 릴레이 모듈 5V 2채널 (Active-LOW) 1 모터/조명 스위칭 NO/COM/NC
6 관수 펌프 DC 12V 미니 워터펌프 1 양액 공급 30분 주기
7 LED 성장등 12V LED 바 다수 광합성 조명 적색+청색
8 전원 공급 5V (Arduino) + 12V (릴레이) 1 이중 전원 DC 어댑터
9 점퍼 와이어 M-M, M-F 세트 1 배선 듀폰 커넥터
10 브레드보드/PCB 400홀 또는 커스텀 PCB 1 회로 구성 양산 시 PCB
양산 시 Arduino Uno → ATmega328P 단독 PCB 전환으로 단가 절감 가능

프로젝트 완성도

완료 항목
Arduino 펌웨어 (456줄, 프로덕션 레디)
BLE JSON 통신 프로토콜
모터/조명 자동 타이머 (EEPROM 저장)
DHT22 온습도 센서 연동
React Native 앱 (3화면)
Android APK 빌드 (21MB)
테스트 모드 (모터/조명 개별)
수동/자동 모드 전환
🚀 향후 계획
iOS 앱스토어 빌드 및 배포
WiFi 모듈 추가 (원격 모니터링)
다중 재배기 관리 (10대+)
클라우드 데이터 로깅
DHT22 실측값 연동 (현재 테스트값)
OTA 펌웨어 업데이트
전력 소비 최적화

개발 진행률

펌웨어
완료 100%
모바일 앱
Android 완료 90%
하드웨어
프로토타입 85%
인프라
계획중 40%
456줄
펌웨어
3개
앱 화면
5종
BLE 명령
21MB
APK 크기

기술 스택

🔧 하드웨어
MCU Arduino Uno (ATmega328P, 16MHz)
BLE HC-05 Bluetooth 4.0
ENV DHT22 (±0.5°C, ±2% RH)
RTC DS1302 Real-Time Clock
PWR 5V 2CH Relay Module
📱 모바일 앱
FW React Native 0.61.5
BLE react-native-ble-manager 7.1.1
NAV react-navigation 1.0.0
UI react-native-elements 1.2.7
OS Android 5.0+ / iOS 10+
📡 통신/프로토콜
RF BLE 4.0 (FFE0/FFE1)
FMT JSON 메시지 포맷
SER SoftwareSerial (9600baud)
EOF __FIN__ 종결자 프로토콜
ERR 3-strike 연결 해제 정책

프로젝트 정보

프로젝트명 새싹인삼 스마트 재배기
의뢰처 (주)더바이오그룹 — 더 좋은 농장
개발 기간 2020.02 ~ 2020.06
개발 범위 하드웨어 설계 + 펌웨어 + 모바일 앱
디바이스 ID TBF_02
현장 전라북도 전주시
재배 품목 새싹인삼 (스프라우트)
재배 방식 LED 실내 다단 수경재배
관수 방식 자동 타이머 양액 공급
조명 방식 자동 타이머 LED 성장등

개발 타임라인

2020.02
프로젝트 착수
요구사항 분석
2020.03
하드웨어 설계
회로 구성
2020.04
펌웨어 개발
BLE 프로토콜
2020.05
모바일 앱 개발
현장 테스트
2020.06
APK 빌드
납품 완료