대시보드 앱 사용법 (초보자용)¶
UWB 앵커가 측정한 거리를 받아서 태그(이동 단말)의 위치를 지도 위에 그려주는 PC/모바일 앱 사용법. 처음 써보는 분도 따라 할 수 있도록 차근차근 설명한다.
| 데이터 화면 | 지도 화면 |
|---|---|
![]() |
![]() |
소스 / 다운로드: https://github.com/wshan1977/controlbit_uwb_rtos
시작하기 전에 준비할 것¶
| 준비물 | 확인 방법 |
|---|---|
| UWB 앵커 보드 (3대 이상 권장) | 천장이나 벽에 부착, 전원 ON 상태 |
| UWB 태그 (이동 단말) 1대 이상 | 앵커들 사이를 움직이는 디바이스 |
| MQTT 브로커 | 인터넷 공용 broker.hivemq.com 으로 시작해도 됨 |
| 앵커가 MQTT publish 중인지 | 앵커 설정에 같은 브로커 / topic prefix 입력되어 있어야 함 (디바이스 설정 참조) |
앵커와 대시보드는 같은 MQTT 브로커, 같은 토픽 prefix 를 봐야 한다. 앵커가
uwb/range/A0로 발행하면 대시보드는uwb/range/+를 구독해야 모든 앵커 데이터가 들어온다.
1. 앱 실행 방법 — 세 가지 중 선택¶
A. 웹 브라우저 (가장 쉬움)¶
별도 설치 없이 크롬에서 바로 실행 가능. (추후 GitHub Pages 등에 배포되면 URL 공개 예정)
B. Windows / Mac / Linux 데스크톱¶
git clone https://github.com/wshan1977/controlbit_uwb_rtos.git
cd controlbit_uwb_rtos
flutter pub get
flutter run -d windows # Windows
flutter run -d macos # Mac
flutter run -d linux # Linux
C. Android¶
Flutter SDK가 처음이면 https://docs.flutter.dev/get-started/install 의 OS별 설치 가이드를 먼저 따라 한다.
2. 첫 실행 — MQTT 브로커 연결¶
앱을 처음 켜면 연결 정보 입력 화면이 뜬다.
📷 [이미지 자리] 첫 실행 시 보이는 MQTT 연결 폼. 호스트/포트/토픽 입력란이 비어 있는 상태. 파일명:
assets/dashboard_connection_form.png
| 필드 | 공용 테스트 (HiveMQ) | 개인 Mosquitto |
|---|---|---|
| Host | broker.hivemq.com |
192.168.0.10 (예시) |
| TCP port | 1883 |
1883 |
| WebSocket port | 8884 |
9001 |
| WS path | /mqtt |
/ |
| TLS | ON | OFF |
| Topic | uwb/range/+ |
uwb/range/+ |
어느 포트를 입력해야 하나?¶
- 웹 브라우저: WebSocket port 사용 (예:
8884+ TLS ON). 브라우저 보안 정책상 raw TCP 못 씀 - 데스크톱 / 안드로이드: TCP port 사용 (예:
1883)
Topic 입력은 + 가 들어가는 게 맞나?¶
맞다. + 는 MQTT 와일드카드로 "한 단계 어떤 값이든" 의미. uwb/range/+ 로 구독하면 uwb/range/A0, uwb/range/A1, uwb/range/A2 ... 모두 들어온다.
연결 실패 시¶
- 공용 브로커는 TLS 권장 (HiveMQ는 8884 + WSS)
- 회사/공유기 방화벽에서 해당 포트 막혀 있을 수 있음
- 앵커 펌웨어의 topic prefix 와 대시보드 구독 토픽이 일치하는지 다시 확인
3. 앵커 위치 등록 — 가장 중요한 단계¶
대시보드는 각 앵커가 공간상 어디 있는지 알아야 태그 위치를 계산할 수 있다. 최소 3개의 앵커를 등록해야 위치 추정이 시작된다.
등록 절차¶
📷 [이미지 자리] 대시보드 상단의 📍 아이콘 위치를 빨간 동그라미로 표시한 캡처. 파일명:
assets/dashboard_anchor_button.png
- 화면 상단 우측 📍 (지도 핀) 아이콘 탭
- 앵커 추가 버튼
- 다음 4개 값 입력:
| 필드 | 의미 | 예시 |
|---|---|---|
src |
앵커 식별자. 앵커 펌웨어가 publish하는 src 값과 정확히 일치해야 함 | A0 |
idx |
range 배열의 인덱스 (0~7). src 끝의 숫자에서 자동 추출됨 |
0 |
X |
앵커의 X 좌표 | 0 |
Y |
앵커의 Y 좌표 | 0 |
cal |
거리 보정값 (실측 결과를 보고 -10~+10 정도 미세 조정) | 0 |
좌표 정하기 — 처음이면 이렇게¶
방의 한쪽 모서리를 원점 (0, 0) 으로 잡고, 미터 단위로 측정해서 입력한다. 또는 cm 단위도 가능 (앵커 펌웨어가 내보내는 거리값과 단위만 일치하면 됨).
3개 앵커 예:
| src | idx | X | Y |
|---|---|---|---|
A0 |
0 | 0 | 0 |
A1 |
1 | 5 | 0 |
A2 |
2 | 0 | 5 |
📷 [이미지 자리] 앵커 추가 폼에 위 표의 A0 값을 채운 화면. 파일명:
assets/dashboard_anchor_form.png단위 일치가 핵심. 앵커가 cm 단위로 거리를 보내면 X/Y도 cm로, mm면 mm로. 한쪽이 cm이고 다른 쪽이 m이면 좌표가 1만 배 이상 어긋난다.
4. 태그 위치 보기¶
Map 탭¶
- 파란 사각형: 등록한 앵커
- 하늘색 원: 측정된 태그
- 점선: 각 앵커 → 태그 거리 (활성화 시)
조작: - 마우스/손가락 드래그 → 지도 이동 (pan) - 휠/핀치 → 확대/축소 - 우상단 ✏️ 토글 → 앵커 드래그로 좌표 변경 가능 (이때 옮긴 좌표는 자동 저장)
Data 탭¶
- 앵커별 최근 측정값
- 태그별 거리 표
- 추정된 좌표
(x, y)
상단에 카운터: anchors / tags / positioned
positioned 가 0이면 위치가 계산 안 되고 있는 것. 다음 항목 확인.
5. 위치가 안 나올 때 체크리스트¶
| 증상 | 점검할 것 |
|---|---|
tags = 0 |
MQTT 구독 토픽이 잘못됨, 또는 앵커가 publish 안 함. 앵커 시리얼 로그 확인 |
tags ≥ 1 인데 positioned = 0 |
앵커가 3개 미만 등록됨, 또는 src/idx 매핑 오류, 또는 좌표 단위 불일치 |
| 위치가 계속 튀는 값 | 한 앵커의 측정이 이상치(multipath 반사 등). 자동 outlier reject가 동작하지만 한계가 있음 |
| 일정한 오프셋이 보임 | 각 앵커의 cal 값으로 보정 (실측 거리 - 표시 거리만큼) |
대시보드는 자동으로 가장 큰 거리 잔차가 중앙값의 3배를 넘으면 그 앵커를 outlier로 빼고 다시 계산한다. 즉 한두 개 앵커가 잠깐 튀어도 나머지로 위치를 잡는다.
6. 자주 받는 질문¶
Q. 앵커는 몇 개 필요한가? A. 최소 3개. 4개 이상이면 outlier 자동 제거가 더 잘 동작해서 안정적이다. 6~8개면 매우 안정적.
Q. 태그는 몇 개까지 동시에?
A. 펌웨어 빌드 시 UWB_TAG_COUNT 매크로 (기본 64). 대시보드 측 제한은 없다.
Q. 1차원/3차원 측위도 되는가? A. 현재는 X/Y 평면 (2D) 만 지원. Z 좌표는 입력해도 무시.
Q. 좌표 단위는 m인가 cm인가? A. 어느 쪽이든 가능. 앵커 펌웨어가 내보내는 거리값과 좌표 입력의 단위만 일치시키면 된다. 거리 알고리즘은 단위에 무관.
Q. 데이터는 저장되는가? A. 앵커 좌표 / 보정값 / MQTT 설정은 SharedPreferences에 자동 저장됨. 다음 실행 시 그대로 사용.
7. 다음 단계¶
- 앵커의 MQTT/Wi-Fi/OTA 설정 → 상세 설정
- DIP 스위치로 Anchor 번호/모드 결정 → DIP 스위치 안내
- 대시보드 소스 / 이슈: https://github.com/wshan1977/controlbit_uwb_rtos

