본 가이드는 GrowSpace UWB 개발자 태그를 Raspberry Pi 4 Model B와 연결하여,lec
, lep
명령어 기반으로 실시간 위치 데이터를 수신 및 파싱하는 실습 방법을 안내합니다.
Python 환경에서 시리얼 통신을 구현하고, 수신된 데이터를 분석 및 출력하는 방법까지 다룹니다.
준비물
- Raspberry Pi 4 Model B

- USB-C 전원 어댑터 (5V 3A 이상)
- GrowSpace UWB 개발자 태그
- 점퍼 케이블 (TX, RX, GND, 3.3V)
- Python 3.9.2 이상
- pyserial 패키지
사전 설정 환경
OS: Debian GNU/Linux 11 (bullseye)
Python 버전: 3.9.2
필수 패키지: pyserial
UART 포트 활성화
- 터미널에서 다음 명령어 입력:
sudo raspi-config
- 메뉴 이동:
Interface Options → Serial Port
- Login shell via serial: No
- Enable serial port hardware: Yes
- 설정 완료 다시 터미널로 이동
- 터미널에 ‘sudo reboot’ 입력하여 라즈베리파이 리부팅
시리얼 핀 연결
GrowSpace 개발자 태그는 3.3V 전압 기준 좌측 커넥터를 통해 Raspberry Pi의 Serial0 포트와 연결합니다.
이 포트는 3.3V 레벨의 UART 통신을 지원합니다.
개발자 태그 핀 | 라즈베리파이 핀 번호 | GPIO 번호 |
---|---|---|
TX | 10번 (RXD) | GPIO15 |
RX | 8번 (TXD) | GPIO14 |
3.3V | 1번 | – |
GND | 6번 | – |

주의: TX ↔ RX는 반드시 교차 연결해야 합니다.
태그의 TX → Pi의 RX / 태그의 RX → Pi의 TX
📌참고용: 라즈베리파이 GPIO 핀 배치도
아래는 Raspberry Pi 40핀 헤더의 전체 핀맵입니다.
TX0 (GPIO14, Pin 8), RX0 (GPIO15, Pin 10), 3.3V (Pin 1), GND (Pin 6)의 위치를 꼭 확인해 주세요!
이 다이어그램을 참고해 개발자 태그와의 시리얼 연결을 정확하게 구성하시면 됩니다.

GrowSpace 개발자 태그의 시리얼 포트 구분
GrowSpace GrowSpace 개발자 태그에는 두 개의 시리얼 통신 포트가 있으며, 단순히 핀 구성만 다른 것이 아니라 TX/RX 신호의 전압 레벨이 다릅니다.
- 포트 1: TX, RX, 3.3V, GND → 3.3V 레벨 통신용 (좌측 커넥터)
- 포트 2: TX, RX, 5V, GND → 5V 레벨 통신용 (우측 커넥터)
이 실습에서는 Raspberry Pi의 UART는 3.3V 레벨이기 때문에, 반드시 3.3V 포트(포트 1) 를 사용해야 합니다.
5V 포트를 잘못 연결할 경우, Raspberry Pi의 GPIO가 손상될 수 있으니 주의해 주세요

시리얼 통신 테스트 코드 (Python)
import serial
import threading
uwb = serial.Serial('/dev/serial0', baudrate=115200, timeout=0.5)
def read_from_uwb():
while True:
if uwb.in_waiting:
data = uwb.readline().decode(errors='ignore').strip()
if data:
print(f"[UWB 응답] {data}")
def write_to_uwb():
while True:
try:
cmd = input(">>> ")
if cmd.strip():
uwb.write((cmd + '\r').encode())
except KeyboardInterrupt:
print("\n종료합니다.")
break
if __name__ == "__main__":
print("UWB 시리얼 중계 시작 (/dev/serial0)")
threading.Thread(target=read_from_uwb, daemon=True).start()
write_to_uwb()
위 코드는 main() 함수에서 두 개의 스레드를 동시에 실행합니다:
- read_from_uwb()는 개발자 태그(UWB 모듈)로부터 들어오는 데이터를 실시간으로 읽어 콘솔에 출력합니다.
- write_to_uwb()는 사용자가 입력한 명령어를 시리얼로 태그에 전송합니다. (전송 시 ‘\r’ 캐리지리턴을 자동으로 붙여줍니다.)

그리고 si 명령어를 직접 입력하면 UWB 태그에서 응답이 출력되며, 통신이 성공적으로 이루어졌다는 것을 확인할 수 있습니다.
위치 데이터 파싱 예제 (lec / lep)
lep
위치 정보 파싱
def parse_lep(line):
print("\n[LEP 위치 결과]")
parts = line.strip().split(',')
if len(parts) >= 5:
print(f"X: {parts[1]}")
print(f"Y: {parts[2]}")
print(f"Z: {parts[3]}")
print(f"품질(QF): {parts[4]}")
else:
print("→ 잘못된 LEP 형식입니다.")
lec
거리 + 위치 정보 파싱
def parse_lec(line):
print("\n[LEC 거리 + 위치 결과]")
try:
pos_idx = line.index("POS,")
dist_part = line[:pos_idx].strip()
pos_part = line[pos_idx:].strip()
anchors = []
tokens = dist_part.split(',')
i = 2
while i < len(tokens):
if tokens[i].startswith("AN"):
anchor_id = tokens[i+1]
x = float(tokens[i+2])
y = float(tokens[i+3])
z = float(tokens[i+4])
d = float(tokens[i+5])
anchors.append((anchor_id, x, y, z, d))
i += 6
else:
i += 1
for idx, (aid, x, y, z, d) in enumerate(anchors):
print(f"AN{idx} (ID {aid}): x={x}, y={y}, z={z}, 거리={d}m")
parse_lep(pos_part)
except Exception as e:
print(f"lec 파싱 실패: {e}")
전체 수신 루프 구성
input_buffer = ""
def read_from_uwb():
global input_buffer
while True:
if uwb.in_waiting:
data = uwb.read().decode(errors='ignore')
if data == '\n':
line = input_buffer.strip()
if line.startswith("POS,"):
parse_lep(line)
elif line.startswith("DIST,"):
parse_lec(line)
else:
print(f"[기타 응답] {line}")
input_buffer = ""
else:
input_buffer += data
- 실행 결과


결론
본 실습을 통해 Raspberry Pi에서 GrowSpace UWB 태그의 실시간 위치 데이터를 수신하고,
Python 코드로 분석하여 출력하는 전체 과정을 다루었습니다.
- Raspberry Pi의 Serial0 포트를 통해 안정적인 시리얼 통신 가능
- Python 기반 파싱 로직으로 데이터 분석/활용의 확장성 확보
- RTLS 실험용 테스트베드로 활용 가능
여러분도 이 방법을 따라 하여 효율적인 위치 추적 시스템을 구현해 보세요!
궁금한 점이 있거나 문제가 발생하면 언제든지 문의주세요! 😊