Raspberry Pi 연동
이 글에서는
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 이상 (OS: Debian GNU/Linux 11 기준)
pyserial 패키지 설치
Raspberry Pi 시리얼 포트 설정
터미널에 다음 명령어 입력:
sudo raspi-config
메뉴 이동:
Interface Options → Serial Port
Login shell via serial: No
Enable serial port hardware: Yes
설정 완료 후
sudo reboot
명령어로 재부팅
시리얼 핀 연결 (UART)
GrowSpace 개발자 태그의 3.3V 커넥터(좌측) 기준으로 다음과 같이 연결합니다:
개발자 태그 핀
라즈베리파이 핀 번호
GPIO 번호
TX
10번 (RXD)
GPIO15
RX
8번 (TXD)
GPIO14
3.3V
1번
-
GND
6번
-
⚠️ 반드시 TX ↔ RX 교차 연결을 확인해 주세요. 태그의 TX → Pi의 RX, 태그의 RX → Pi의 TX

참고: Raspberry Pi GPIO 핀 배치도
아래는 Raspberry Pi 40핀 헤더의 전체 핀맵입니다. 다음 핀 번호를 기준으로 정확히 연결하세요:
TX0: GPIO14 (Pin 8)
RX0: GPIO15 (Pin 10)
3.3V: Pin 1
GND: Pin 6
이 다이어그램을 참고하면 개발자 태그와의 시리얼 연결을 더욱 명확히 이해할 수 있습니다.
공식 문서에서 전체 GPIO 구성도와 회로 정보를 자세히 보고 싶다면 다음 링크를 확인해 주세요: 라즈베리 파이 공식 핀아웃 및 도면 보기

주의사항: GrowSpace 태그의 시리얼 포트 구분
GrowSpace 개발자 태그에는 좌우 측에 각각 다른 전압 레벨의 시리얼 포트가 존재합니다. 단순한 핀 위치 차이가 아니라, 전기적으로 완전히 다른 레벨이므로 반드시 구분하여 사용해야 합니다.
포트 1 (좌측 커넥터)
구성: TX, RX, 3.3V, GND
동작 전압: 3.3V 레벨
사용 용도: Raspberry Pi, ESP32 등 3.3V 기반 장치와 연결 시 사용
포트 2 (우측 커넥터)
구성: TX, RX, 5V, GND
동작 전압: 5V 레벨
사용 용도: Arduino UNO 등 5V 기반 장치와 연결 시 사용
반드시 확인하세요
Raspberry Pi의 GPIO는 3.3V 전압만 허용합니다.
5V 포트(우측 커넥터)를 잘못 연결하면 라즈베리파이의 UART 회로가 손상될 수 있습니다.
본 매뉴얼에서는 반드시 **좌측 커넥터(3.3V 포트)**를 사용해야 합니다.

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()
read_from_uwb()
는 실시간 수신 데이터를 출력write_to_uwb()
는 명령어를 입력 받아 전송 (\r
포함)
예: si
명령어 입력 시, 장치 정보가 출력되면 통신 성공
위치 데이터 파싱 예제 (lep
, lec
명령어)
lep
, lec
명령어)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
POS,
로 시작하면 LEP 파싱DIST,
로 시작하면 LEC 파싱기타 응답도 모두 출력
마무리
이 매뉴얼에서는 Raspberry Pi 환경에서 GrowSpace 개발자 태그와 시리얼 통신을 구성하고, Python을 통해 lep
, lec
명령어 기반의 위치 데이터를 실시간으로 수신 및 파싱하는 과정을 소개했습니다.
이 과정을 통해:
Raspberry Pi의
/dev/serial0
포트를 활용한 안정적인 통신 구성Python 기반 파싱 로직으로 실시간 위치 정보 확인 가능
RTLS 실험 및 프로토타이핑 테스트베드로 확장 가능
실습 중 문제가 발생할 경우, TX/RX 교차 연결 여부와 포트 활성화 상태를 꼭 다시 확인해 주세요.
Last updated