모종의 생장 상태를 일일이 눈으로 확인해야 한다면?
사업 규모를 키우고 싶지만 사람을 더 고용할 여유가 없다면?
SFAM은 육묘의 입고부터 출고까지 전 과정을 자동화하여 생산자에게 연구와 생활을 위한 시간을 돌려주는 통합 스마트팜 자동화 시스템입니다.
RFID로 모종을 인식해 디지털 트윈을 생성하고, AGV가 최적 위치로 자동 이송합니다. 센서 데이터 기반으로 온습도·조도를 자동 제어하며, 출하 시점이 되면 AGV가 자동 출고합니다.
Internal Wi-Fi를 통해 모든 디바이스가 중앙 서버(Control Hub)와 통신합니다.

SFAM Protocol(CRC16)로 데이터를 검증하며, RFID 이벤트 핸들러가 실시간 물류 흐름을 제어하는 핵심 엔진 역할을 합니다.

RFID 태그로 모종을 인식하면 디지털 트윈이 생성되고, DB에서 품종 유효성을 조회한 뒤 최적 저장 위치를 계산하여 AGV가 자동으로 배치합니다.
핵심 매커니즘: 물리적 입고 → 디지털 트윈 생성(DB 적재) → 최적 경로 및 위치 배정 → AGV 실행
sequenceDiagram
actor User as 작업자
participant In as 입고장 ESP32
participant Hub as Control Hub
participant DB as SFDB
participant AGV as 운송 로봇 AGV
participant Web as Web Dashboard
User->>In: 모종 화분 거치
In->>Hub: NFC 태그 데이터 추출
In->>Hub: 입고 요청 Tag ID
Hub->>DB: 품종 유효성 조회 seedling_varieties
DB-->>Hub: 유효성 확인
Note over Hub: Storage Optimization Logic
Hub->>DB: 가용 구역 조회 farm_nodes
DB-->>Hub: 최적 섹션 반환
Hub->>AGV: 이송 명령 하달
AGV->>AGV: 목적지로 주행 시작
Hub-->>Web: GUI 상태 업데이트영상 분석으로 출고 대상을 판정하고, AGV 상태를 모니터링하여 태스크 큐잉(Scheduling)으로 순차 배차합니다. 이송 중일 경우 예약 명령으로 대기시키고, 완료 후 섹션 비움 상태를 자동 업데이트합니다.
sequenceDiagram
actor User as 작업자
participant Web as Web Dashboard
participant Hub as Control Hub
participant DB as SFDB
participant AGV as 운송 로봇 AGV
participant Out as 출고장 ESP32
User->>Web: 출고 요청
Web->>Hub: 출고 리스트 확인
Hub->>DB: 육묘 상태 검증 seedling_status
DB-->>Hub: 상태 반환
Note over Hub: AGV 상태 확인 및 예약 로직
Hub->>AGV: 가동 상태 확인 is_moving
alt 이송 중일 경우
Hub->>AGV: 예약 명령 Task Queue
end
Hub->>AGV: 이송 명령 seedling_id from_node
AGV->>AGV: 육묘섹션 이동 및 모종 상차
AGV->>Out: 출고장으로 이동 및 하역
AGV-->>Hub: 출고 확인 Discharge_Complete
Hub->>DB: 섹션 비움 업데이트 status EMPTY
Hub-->>Web: GUI 출고 상태 업데이트 완료실시간 센서 피드백 루프와 긴급 제어권 개입 메커니즘을 구현했습니다. 센서 데이터를 스트리밍하면서 임계치 도달 시 자동으로 장치를 제어하고, 사용자가 수동 제어 모드로 전환하면 자동 모드가 일시 중단됩니다. 5분 미조작 시 자동 타임아웃으로 복귀합니다.
자동 모드: 1시간 간격, 10초 동안 급수 (설정 변경 가능)
sequenceDiagram
participant Web as Web Dashboard
participant Hub as Control Hub
participant Nurs as 육묘 섹션
participant DB as SFDB
actor User as 작업자
loop 자동 제어 루프
Nurs->>Hub: 환경 데이터 전송 Temp Humid Lux
Hub->>DB: 육묘설정 환경 확인
Note over Hub: Auto Control Logic
Hub->>Nurs: 임계치 도달 시 장치 자동 조절
end
User->>Web: 수동 제어 요청
Web->>Hub: 수동 제어 모드 전환 Manual Override
Hub->>Nurs: 특정 섹션 팬 강제 가동 명령
alt 자동 복귀 버튼 클릭
User->>Web: 자동 복귀 버튼 클릭
else 5분 미조작
Hub->>Hub: 자동 타임아웃
end
Hub-->>Web: 자동 모드 전환 알림
Hub->>Nurs: 제어권 회수 및 센서값 재동기화실시간 센서 데이터 시각화, AGV 상태 모니터링, 수동 제어 인터페이스를 Flask + Vanilla JS 기반 웹 대시보드로 구현했습니다.
AGV 위치 시각화는 초기 구현에서 현재 위치가 바뀔 때 사후 반응하는 방식이었습니다. 이를 텔레메트리의 "다음 목표 노드" 데이터를 활용한 예측형으로 개선해, AGV가 이동을 시작하는 순간 목적지까지의 경로를 미리 강조 표시합니다.
폴링 주기는 데이터 중요도에 따라 차별화해 불필요한 요청을 줄였습니다:
| 데이터 | 폴링 주기 |
|---|---|
| 로봇 상태 (위치/배터리) | 1초 |
| 카메라 프레임 | 2초 |
| 센서 데이터 | 3초 |
| 활동 로그 | 5초 |
노드 도달 시 border 플래시 애니메이션(500ms), SVG 경로 세그먼트의 .moving 클래스 토글로 이동 경로를 실시간 표시하고, Chart.js로 센서 데이터를 다축 그래프로 시각화했습니다.
| 레이어 | 기술 |
|---|---|
| 센서/하드웨어 | Arduino, ESP32, ESP32-CAM, DHT11, BH1750, RFID RC522 |
| 통신 | TCP (8000) / UDP (7070), SFAM Protocol v1.0 (CRC16) |
| 서버 | Python Flask, PyMySQL |
| UI | Flask + Vanilla JS 웹 대시보드, REST API (HTTP 5001) |
| 제어 | 이산 상태 기계 라인 트레이싱, 서보 그리퍼, 자동 급수 |
IR 어레이 센서 5개의 상태 조합을 우선순위에 따라 분기하는 이산 상태 기계로 라인 트레이싱을 구현했습니다. 연속적인 PID 오차 계산 없이도 안정적인 경로 추종이 가능하며, 센서 우선순위(끝 > 측면 > 중앙)로 급격한 커브에서도 이탈을 방지합니다.
| 센서 상태 | 동작 |
|---|---|
| S3만 감지 | 직진 |
| S2 또는 S2+S3 | 부드러운 좌회전 |
| S1 | 급격한 좌회전 |
| S4 또는 S4+S3 | 부드러운 우회전 |
| S5 | 급격한 우회전 |
| S1+S5 동시 감지 | 교차로 감지 → 명령 대기 |
교차로는 (S1==1 && S5==1) || (S2==1 && S4==1 && S3==0) 조건으로 판별하며, 이후 서버로부터 수신한 방향 명령(직진/좌/우/U턴)을 실행합니다. 후진 라인트레이싱도 동일 센서 로직에 역방향 모터 제어를 결합해 구현했습니다.
AGV와 서버 간 통신을 목적에 따라 TCP와 UDP로 분리 설계했습니다.
TCP (Port 8000) — 신뢰성이 필요한 제어/상태 데이터
AGV는 500ms 주기로 텔레메트리 패킷을 서버에 전송합니다. 서버는 이를 파싱해 DB에 로깅하고 실시간 캐시를 유지합니다.
| 텔레메트리 필드 | 내용 |
|---|---|
| 현재 노드 | AGV가 위치한 맵 노드 ID |
| 다음 목표 노드 | 이동 중인 목적지 노드 ID |
| 배터리 | 0~100% |
| 모터 PWM | 좌/우 모터 출력값 |
| 센서값 | IR 어레이 상태 |
작업 명령은 서버 → AGV 방향으로 10바이트 페이로드(작업ID, 상품ID, 출발지/목적지 노드, 수량, 우선순위)로 전송됩니다. Task Dispatcher가 3초 주기로 DB를 폴링해 대기 작업을 AGV에 자동 할당하며, 5초 heartbeat 타임아웃과 3회 재시도 메커니즘으로 연결 안정성을 확보했습니다.
UDP (Port 7070) — 실시간 영상 스트리밍
지연이 허용되지 않는 카메라 영상은 UDP로 전송합니다. TCP의 재전송 오버헤드 없이 프레임을 연속 전송하고, 서버는 이를 모종 생육 상태 판별 및 대시보드 표시에 활용합니다.
JSON 대신 1바이트 단위로 설계한 경량 바이너리 프로토콜로, CRC16-CCITT 오류 검출을 통해 저사양 MCU(ESP32)에서도 신뢰성 있는 통신을 구현했습니다.
| 순서 | 필드 | 크기 | 설명 |
|---|---|---|---|
| 1 | SOF | 1 Byte | 0xAA (패킷 시작 신호) |
| 2 | MSG_TYPE | 1 Byte | 메시지 종류 (0x24: RFID, 0x20: 센서 등) |
| 3 | SRC_ID | 1 Byte | 보내는 기기 ID |
| 4 | DST_ID | 1 Byte | 받는 기기 ID (보통 서버 0x00) |
| 5 | SEQ | 1 Byte | 패킷 순번 (누락 확인용) |
| 6 | PAYLOAD_LEN | 1 Byte | 실제 데이터(Payload)의 길이 |
| 7 | PAYLOAD | N Byte | 실제 내용 (온도값, RFID UID 등) |
| 8 | CRC16 | 2 Byte | 무결성 검사 (데이터 변조 확인용) |
- RFID Event Handler: 0x24 패킷을 통해 AGV의 픽업/안착을 실시간 판단
- Task Dispatcher: 3초 주기의 DB 폴링을 통한 지능형 배차

- 효율성 극대화: 오버헤드가 큰 JSON을 과감히 버리고, 1바이트 단위로 설계한 SFAM Protocol(Binary) 도입
- 최적화 성과: 저사양 MCU(ESP32)의 통신 부하를 획기적으로 줄여 실시간 정밀 제어 성공
calc_crc16함수 구현을 통해 데이터 노이즈를 100% 감지 및 차단- 완벽한 코드보다 실패(에러)에 대비한 코드의 중요성을 체감하며 시스템 안정성 확보
- 효율성: 최소한의 크기로 최대한의 정보를 전달하는 Struct 구조체 활용
- 신뢰성: "깨진 데이터를 읽는 것보다 안 읽는 것이 안전하다"는 통신 대원칙 수립
- 엄격한 약속: SOF(0xAA)부터 ETX까지 이어지는 우리만의 통신 언어(Protocol) 정의
| 이름 | 역할 |
|---|---|
| 이건희 (팀장) | 전체 공정 및 스프린트 관리, 육묘장 HW 아키텍처 설계, DB 모델링 및 정규화 |
| 최민성 | AGV↔서버 통신 개발, AGV 컴포넌트 개발, 관리자 GUI 구현, AGV 라인트레이싱 구현, Git 형상 관리 |
| 김무성 | 메인 서버 백엔드 로직 설계, GUI-Server 데이터 연동 및 시스템 통합 관리 |
| 김진우 | AGV 핵심 부품 기술 조사 및 성능 고도화, 전체 시스템 맵핑 및 시연 영상 제작 |
| 이지수 | 관리자 전용 Monitoring GUI 설계, 실시간 생육 데이터 시각화 인터페이스 구현 |
| 유정학 | Jira/Confluence 협업 환경 구축, 프로젝트 기술 문서화 및 프리젠테이션 전략 총괄 |