Files
Radick/README.md
dami 1a47837a2c
Some checks failed
build / host-tests (push) Has been cancelled
build / esp-idf (push) Has been cancelled
Add prebuilt firmware package
2026-07-21 08:45:33 +00:00

196 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Radick (라자지)
Radick은 Ai-Thinker RD-03D V1 24 GHz 레이더와 Elecrow 7인치 CrowPanel 하나로 동작하는 독립형 다중 목표 레이더입니다. 원본 [Arduino-ESP32-Radarproject](https://github.com/Stevee87/Arduino-ESP32-Radarproject)의 레이더 표현과 거리 기반 경고음을 유지하면서, XIAO·Arduino GIGA·Wi-Fi·UDP를 모두 제거했습니다. 펌웨어는 Arduino 계층 없이 ESP-IDF 5.3과 LVGL 8로 작성되어 레이더 UART부터 화면까지 한 ESP32-S3 안에서 처리합니다.
> [!IMPORTANT]
> 이 프로젝트는 **Basic CrowPanel 7.0 V3.0 (`DIS08070H`, ESP32-S3 N4R8)** 및 **RD-03D V1 (`S5KM312CL`, 15 × 44 mm)** 전용입니다. CrowPanel V1/V2와 RD-03D V2는 핀 및 프로토콜이 달라 지원하지 않습니다.
## 필요한 하드웨어
- Elecrow Basic CrowPanel 7.0-inch HMI ESP32 Display V3.0
- Ai-Thinker RD-03D V1 레이더 모듈
- 보호회로가 있는 1셀 Li-ion/LiPo 배터리(공칭 3.7 V, 최대 4.2 V)
- 출력 리플 100 mV 이하의 5 V 승압 모듈(연속 200 mA 이상, 500 mA급 권장)
- 5 V 레이더 전원 스위치와 승압 모듈 제조사가 권장하는 입·출력 캐패시터
- 경고음을 사용할 경우 J5 `SPK`에 맞는 스피커
배터리는 CrowPanel의 J1에 직접 연결할 수 있지만, RD-03D의 동작 전압은 4.55.5 V입니다. 따라서 레이더 VCC에는 배터리나 3V3 핀을 직접 연결하지 말고 반드시 별도 5 V 승압 출력을 사용해야 합니다. MCU/디스플레이는 CrowPanel 한 장뿐이지만, 이 승압 전원부는 생략할 수 없는 최소 부품입니다.
## 배선
| RD-03D V1 | CrowPanel V3 / 전원 | 설명 |
|---|---|---|
| `VCC` | 5 V 승압 모듈 `OUT+` | **J10의 3V3 또는 배터리에 직접 연결 금지** |
| `GND` | 공통 GND(J7 pin 4 등) | CrowPanel·승압 모듈·레이더의 GND를 공통 연결 |
| `TX` | J7 `GPIO_D` pin 1, GPIO38 | ESP32-S3 UART1 RX |
| `RX` | J10 `UART` pin 2, GPIO43 | ESP32-S3 UART1 TX |
배터리 전원은 아래처럼 분기합니다.
```text
보호형 1S 배터리 ──> CrowPanel J1 BAT+/GND
└─────────> 5 V 저리플 승압 ──> RD-03D VCC/GND
RD-03D TX ─────────> J7 pin 1 / GPIO38
RD-03D RX <───────── J10 pin 2 / GPIO43
```
J10 pin 1(GPIO44)은 온보드 CH340C의 TX 출력과 같은 네트이므로 레이더 TX를 연결하면 출력끼리 충돌할 수 있습니다. 이 때문에 레이더 수신과 송신을 서로 다른 커넥터로 나눈 것입니다. GPIO43은 CH340C RX와 레이더 RX라는 두 입력으로만 연결되어 안전하게 플래싱 경로를 유지합니다. 다만 부트 ROM의 송신도 레이더 RX에 들어가므로 **플래싱 중에는 레이더 5 V 전원을 끄는 것을 권장**합니다.
RD-03D V1의 1.25 mm 4핀 커넥터는 데이터시트 기준 pin 1 `5V`, pin 2 `GND`, pin 3 `TX`, pin 4 `RX`입니다. 모듈 방향에 따라 좌우가 뒤집혀 보일 수 있으므로 실크와 pin 1 표시를 반드시 확인하십시오.
J1 커넥터의 pin 1은 `BAT+`, pin 2는 `GND`입니다. 커넥터 규격만 믿지 말고 실제 배터리 극성을 멀티미터로 확인하십시오. CrowPanel에는 MCU가 읽을 수 있는 배터리 전압/잔량 회로가 없어 UI에 근거 없는 배터리 퍼센트를 표시하지 않습니다. 자세한 전체 핀맵과 전원 주의사항은 [하드웨어 문서](docs/HARDWARE.md)를 참고하십시오.
## 동작 방식
- UART1, 256000 baud, 8N1로 RD-03D의 30바이트 프레임을 직접 수신
- 스트림 노이즈·분할 프레임·손상 프레임 이후 자동 재동기화
- 최대 세 목표를 전역 최근접 매칭과 이동 예측으로 추적해 슬롯 순서가 바뀌어도 ID 유지
- 위치/속도 EMA로 화면 떨림 완화
- 원본의 1 m 강제 병합과 2초 정지 고스트 로직을 제거해 가까운 두 사람을 별도 목표로 유지하고 잔상을 빠르게 제거
- 08 m를 근거리 중심 비선형 스케일로 그려 작은 화면 이동도 알아보기 쉽게 표시
- 가장 가까운 목표의 거리에 따라 온보드 NS4168 스피커의 핑 주기와 음높이를 변경
- 터치로 음소거와 밝기를 조절하고, 60초 동안 터치와 목표가 없으면 자동 감광
- 마지막 정상 프레임으로부터 1.5초가 지나면 명확한 `RADAR OFFLINE` 상태 표시
레이더 명령 전송은 앱 부팅 후 공식 멀티 타깃 명령 `0x90`만 사용합니다. 기본 단일 타깃 스트림이 이미 출력되는 경우도 놓치지 않도록 5초 간격으로 총 세 번만 멱등 전송하며 UART와 UI 태스크를 막지 않습니다. 센서 전원이 꺼졌다가 정상 프레임이 다시 들어오면 같은 제한된 설정 절차를 한 번 재수행합니다.
## 빌드와 설치
직접 빌드하지 않고 바로 플래싱하려면 저장소의 [사전 빌드 펌웨어](firmware/)를 사용하십시오. 앱·부트로더·파티션 테이블과 Linux/macOS 및 Windows용 플래시 스크립트가 함께 들어 있습니다.
권장 환경은 ESP-IDF **v5.3.4**입니다. 다른 ESP-IDF 버전은 RGB LCD와 I2S API 차이 때문에 빌드 결과가 달라질 수 있습니다.
### 1. 플래싱 준비
1. RD-03D에 공급하는 외부 5 V 승압 전원을 끄거나 레이더 VCC를 분리합니다. UART 선은 그대로 두어도 됩니다.
2. 데이터 통신이 가능한 USB-C 케이블로 CrowPanel의 CH340C 프로그래밍 포트를 PC에 연결합니다. 첫 플래싱은 배터리를 분리하고 USB 전원만 사용하는 것을 권장합니다.
3. 새로 생긴 시리얼 포트를 확인합니다.
Linux에서는 보통 `/dev/ttyUSB0`입니다.
```bash
ls -l /dev/serial/by-id/ 2>/dev/null
ls /dev/ttyUSB* 2>/dev/null
```
Windows에서는 장치 관리자의 `포트(COM 및 LPT)`에서 `COM5` 같은 이름을 확인합니다. macOS에서는 `/dev/cu.usbserial-*` 또는 `/dev/cu.wchusbserial*` 형태입니다. 아래 명령의 `/dev/ttyUSB0`을 확인한 포트로 바꾸십시오.
### 2. ESP-IDF로 빌드하고 바로 올리기
ESP-IDF v5.3.4 환경을 활성화한 뒤 저장소 루트에서 실행합니다. `set-target`은 최초 한 번만 필요합니다.
```bash
. "$IDF_PATH/export.sh"
idf.py set-target esp32s3
idf.py -p /dev/ttyUSB0 build flash
```
Windows의 ESP-IDF PowerShell에서는 환경이 이미 활성화되므로 저장소로 이동한 뒤 `idf.py set-target esp32s3``idf.py -p COM5 build flash`를 실행하면 됩니다.
첫 빌드에서 Component Manager가 LVGL 8.3.11을 받습니다. 성공하면 다음 세 파일이 생성되고 ESP-IDF가 올바른 오프셋에 모두 기록합니다.
| 파일 | Flash 오프셋 |
|---|---:|
| `build/bootloader/bootloader.bin` | `0x0` |
| `build/partition_table/partition-table.bin` | `0x8000` |
| `build/radick.bin` | `0x10000` |
애플리케이션 UART 콘솔은 레이더 핀과의 간섭을 피하려고 꺼 두었습니다. 따라서 `idf.py monitor`에 런타임 로그가 표시되지 않는 것은 정상이며, 플래싱 성공 메시지와 실제 화면으로 동작을 확인합니다.
### 3. 생성된 바이너리를 esptool로 다시 올리기
이미 한 번 빌드했다면 다시 컴파일하지 않고 아래 명령으로 세 바이너리를 직접 기록할 수 있습니다. `radick.bin` 하나만 기록하면 부트로더나 파티션 테이블이 없는 보드에서는 부팅되지 않을 수 있으므로 세 파일을 모두 지정합니다.
```bash
python3 -m esptool \
--chip esp32s3 \
--port /dev/ttyUSB0 \
--baud 460800 \
--before default_reset \
--after hard_reset \
write_flash \
--flash_mode dio \
--flash_freq 80m \
--flash_size 4MB \
0x0 build/bootloader/bootloader.bin \
0x8000 build/partition_table/partition-table.bin \
0x10000 build/radick.bin
```
`esptool`이 없다면 ESP-IDF 환경을 활성화하거나 별도 Python 환경에 `python3 -m pip install esptool==4.9.0`으로 설치할 수 있습니다.
### 4. Docker로 빌드하기
로컬 ESP-IDF 설치 없이 Docker로 빌드할 수도 있습니다.
```bash
docker run --rm \
-v "$PWD:/project" -w /project \
espressif/idf:v5.3.4 \
idf.py -B build-docker build
```
Linux에서는 시리얼 장치를 컨테이너에 전달해 빌드와 플래시를 한 번에 할 수도 있습니다.
```bash
docker run --rm \
--device=/dev/ttyUSB0 \
-v "$PWD:/project" -w /project \
espressif/idf:v5.3.4 \
idf.py -B build-docker -p /dev/ttyUSB0 build flash
```
Windows/macOS Docker Desktop은 USB 직렬 장치 전달이 복잡하므로 네이티브 ESP-IDF 또는 `esptool` 사용을 권장합니다.
### 5. 연결 문제 해결
- `Connecting...`에서 멈추면 `BOOT`을 누른 상태로 `RESET`을 짧게 누르고, `BOOT`을 놓은 뒤 플래시 명령을 다시 실행합니다.
- Linux에서 `Permission denied`가 나오면 `sudo usermod -aG dialout "$USER"`를 실행하고 로그아웃한 뒤 다시 로그인합니다.
- 포트가 보이지 않으면 충전 전용이 아닌 데이터 USB 케이블인지 확인하고 다른 USB 포트에 연결합니다.
- 직렬 모니터나 다른 프로그램이 포트를 잡고 있으면 종료한 후 다시 시도합니다.
- 설정까지 완전히 초기화해야 할 때만 `idf.py -p /dev/ttyUSB0 erase-flash`를 실행한 후 다시 플래싱합니다. 이 작업은 저장된 밝기와 음소거 설정도 삭제합니다.
- 플래싱이 끝나면 RD-03D의 외부 5 V 전원을 켜고 CrowPanel을 한 번 리셋합니다.
## 호스트 테스트
레이더 프로토콜과 추적기는 ESP32 의존성 없이 테스트할 수 있습니다.
```bash
cmake -S tests -B build-host
cmake --build build-host --parallel
ctest --test-dir build-host --output-on-failure
```
테스트는 sign-magnitude 디코딩, 모든 청크 분할 위치, 노이즈/손상/바이트 유실 후 복구, 연속 프레임, 슬롯 재정렬, 근접 목표 비병합, 누락/재획득, 서로 교차하는 두 목표의 ID 유지를 포함합니다.
## 구조
```text
main/
├── board.* RGB LCD, GT911/PCA9557, LVGL, 백라이트
├── radar_protocol.* RD-03D 스트림 파서
├── target_tracker.* 안정 ID, 예측, EMA, 만료 처리
├── radar_service.* UART 태스크와 thread-safe 화면 스냅샷
├── audio_service.* I2S 거리 경고음
├── ui.* 800×480 단순 레이더 UI
├── app_settings.* NVS 밝기/음소거 저장
└── app_main.c 서비스 연결, 자동 감광, LVGL 루프
```
## 실기 확인 항목
전체 소프트웨어 빌드와 호스트 테스트 외에, 조립 후 다음 항목은 실제 하드웨어에서 확인해야 합니다.
- 승압 출력이 레이더 연결 상태에서도 5 V 근처로 안정적인지
- GT911 터치 방향과 RGB 패널 색/플리커
- 안테나 방향 기준 좌우 좌표가 화면과 일치하는지
- 스피커 임피던스에 맞춘 실제 음량과 전원 노이즈
- 배터리 구동 시간과 충전 중 발열
레이더 사양은 Ai-Thinker의 [RD-03D V1 문서](https://docs.ai-thinker.com/en/Rd-03D_V1/), 디스플레이 핀은 Elecrow의 [CrowPanel 7-inch 저장소](https://github.com/Elecrow-RD/CrowPanel-7.0-HMI-ESP32-Display-800x480)와 V3 회로도를 기준으로 했습니다.
## License
[WTFPL v2](LICENSE)