임베디드시스템설계 Project 3 — Team 12
YOLOv5 객체 탐지와 FreeRTOS 멀티태스킹을 결합한 실시간 군사용 CCTV 시스템입니다. PC에서 실행되는 딥러닝 모델이 카메라 영상을 분석하고, 탐지 결과를 FPGA와 MCU로 전달해 즉각적인 경고를 발생시킵니다.
[Arducam 카메라] → [PC: YOLOv5 탐지]
│ UART
[Zybo Z7-20 FPGA]
│ SPI
[STM32 NUCLEO-F103RB]
│
┌────────────┼────────────┐
[LED_R] [LED_Y] [BUZZER]
(근접 적군) (원거리 적군) (동물)
│
[서보모터]
| 구성 요소 | 역할 |
|---|---|
| PC (Python/YOLOv5) | 객체 탐지 및 좌표 데이터 생성 → UART 전송 |
| Zybo Z7-20 (FPGA) | UART 수신 → 데이터 가공 → SPI 전송 |
| STM32 NUCLEO-F103RB | SPI 수신 → FreeRTOS 태스크로 액추에이터 제어 |
enemy— 적군force— 아군animal— 동물fence— 철책
- 프레임워크: PyTorch + CUDA 12.6
- 학습 데이터: train 70장 / valid 10장
- 라벨링 도구: makesense.ai
- 입력 이미지 크기: 320×240 (Arducam 해상도에 맞춤)
- 평균 탐지 정확도: 0.8 ~ 0.9
python train.py --img 416 --batch 16 --epochs 100 \
--data ./custom/data.yaml \
--cfg ./models/custom_yolov5s.yaml \
--weights '' --name yolov5s_results --cache
python detect.py \
--weights runs/train/yolov5s_results/weights/best.pt \
--source custom/test/images \
--img 320 --conf 0.5 --save-txt --save-conf탐지 결과를 16바이트 바이너리로 변환해 Zybo Z7에 전송합니다.
[class_id: int 4B] [x_center: float 4B] [y_center: float 4B] [confidence: float 4B]
- SPI1: STM32와 마스터-슬레이브 통신
- UART0: USB-UART 브릿지를 통해 PC와 통신 (별도 설정 불필요)
- JE 핀 사용:
SCLK(V12),MOSI(W16),MISO(J15),SS(H15)
수신된 텍스트 데이터를 STM32에 전달할 8비트 포맷으로 변환합니다.
비트 7-6 : Reserved (0)
비트 5-4 : 상황 정보
00 = 아군 (전송 안 함)
01 = 철책 위 적군
10 = 철책 바깥 적군
11 = 동물
비트 3 : Reserved (0)
비트 2-0 : 구역 정보 (1~6, x좌표를 64 단위로 분할)
- 철책 판별:
y_center값이 110 ~ 130 범위이면 철책 위로 판정 - 구역 계산:
zone = (x_center / 64) + 1 - 전송 주기: 0.2초마다 SPI 전송
| 핀 | 기능 |
|---|---|
| PB9 | LED_R (근접 적군 감지) |
| PB10 | LED_Y (원거리 적군 감지) |
| PB8 | BUZZER (동물 감지) |
| SPI1 | Zybo Z7과 통신 (Slave) |
| TIM2_CH1 (PA0) | 서보모터 PWM 출력 |
| 태스크 | 우선순위 | 동작 |
|---|---|---|
Task_SPI |
4 (최고) | SPI 수신 → gRawData 업데이트 |
Task_EnemyClose |
3 | 근접 적군 감지 → LED_R + PWM 제어 |
Task_EnemyFar |
2 | 원거리 적군 감지 → LED_Y + PWM 제어 |
Task_Animal |
1 (최저) | 동물 감지 → BUZZER 5초 울림 |
- Mutex (
g_RawData_Mutex):gRawData공유 자원 보호 - Counting Semaphore (
xCountingSemaphore): 최대 4개 태스크 동시 실행 제어
if (xSemaphoreTake(xCountingSemaphore, portMAX_DELAY) == pdTRUE) {
if (xSemaphoreTake(g_RawData_Mutex, portMAX_DELAY) == pdTRUE) {
gRawData = rxData;
xSemaphoreGive(g_RawData_Mutex);
}
xSemaphoreGive(xCountingSemaphore);
}- 근접 적군 (info=2): 빨간 LED 점등 + 서보모터 구역 조준 → 5초 후 복귀
- 원거리 적군 (info=1): 노란 LED 점등 + 서보모터 구역 조준 → 5초 후 복귀
- 동물 (info=3): 부저 5초 울림, 다른 태스크 일시 정지
📦 military-cctv
┣ 📂 yolov5/
┃ ┣ 📜 detect.py # 객체 탐지 + UART 전송 포함
┃ ┣ 📜 train.py
┃ ┣ 📂 models/
┃ ┃ ┗ 📜 custom_yolov5s.yaml
┃ ┗ 📂 custom/
┃ ┣ 📜 data.yaml
┃ ┣ 📂 train/images/
┃ ┣ 📂 valid/images/
┃ └ 📂 test/images/
┣ 📂 zybo_z7/
┃ ┣ 📜 design.xdc # 핀 설정
┃ ┗ 📜 main.c # Vitis PS 코드
┗ 📂 stm32/
┗ 📜 main.c # FreeRTOS 태스크 코드
| 이름 | 역할 |
|---|---|
| 신상준 | STM32 FreeRTOS 태스크 설계 및 구현 |
| 이지원 | YOLOv5 모델 학습 및 UART 통신 |
| 진성미 | Zybo Z7 Vivado/Vitis 설정 및 데이터 가공 |
| 홍준호 | 시스템 통합 및 테스트 |