# Raspberry Pi 연동

### **이 글에서는**&#x20;

GrowSpace UWB 개발자 태그를 Raspberry Pi 4 Model B와 연결하여, `lec`, `lep` 명령어를 통해 실시간 위치 데이터를 수신하고 파싱하는 방법을 안내합니다. Python 환경에서 시리얼 통신을 구현하고, 위치 데이터를 직접 분석하는 실습 예제를 중심으로 구성되어 있습니다.



### 준비물

* Raspberry Pi 4 Model B

<figure><img src="https://2885569511-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYKyrLLe7cm7ZOhiSB0gg%2Fuploads%2FCtEmKCkl24J63vu9rAoB%2Fimage.png?alt=media&#x26;token=550b9962-16d8-43f3-9899-c9df16b960e4" alt="" width="375"><figcaption></figcaption></figure>

* USB-C 전원 어댑터 (5V 3A 이상)
* GrowSpace UWB 개발자 태그
* 점퍼 케이블 (TX, RX, GND, 3.3V)
* Python 3.9.2 이상 (OS: Debian GNU/Linux 11 기준)
* pyserial 패키지 설치

***

### Raspberry Pi 시리얼 포트 설정

1.  터미널에 다음 명령어 입력:

    ```
    sudo raspi-config
    ```
2. 메뉴 이동:
   * Interface Options → Serial Port
   * Login shell via serial: **No**
   * Enable serial port hardware: **Yes**
3. 설정 완료 후 `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

<figure><img src="https://2885569511-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYKyrLLe7cm7ZOhiSB0gg%2Fuploads%2FV3N60aA6XEZnSwTl17rQ%2Fimage.png?alt=media&#x26;token=9da347c8-9a07-4648-8c40-79a8a946d97a" alt=""><figcaption></figcaption></figure>



#### 참고: Raspberry Pi GPIO 핀 배치도

아래는 Raspberry Pi 40핀 헤더의 전체 핀맵입니다. 다음 핀 번호를 기준으로 정확히 연결하세요:

* TX0: GPIO14 (Pin 8)
* RX0: GPIO15 (Pin 10)
* 3.3V: Pin 1
* GND: Pin 6

이 다이어그램을 참고하면 개발자 태그와의 시리얼 연결을 더욱 명확히 이해할 수 있습니다.

공식 문서에서 전체 GPIO 구성도와 회로 정보를 자세히 보고 싶다면 다음 링크를 확인해 주세요: [라즈베리 파이 공식 핀아웃 및 도면 보기](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#schematics-and-mechanical-drawings)

<figure><img src="https://2885569511-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYKyrLLe7cm7ZOhiSB0gg%2Fuploads%2Fg7tPifie5vqzDsXD3PVk%2FGroup%204485.jpg?alt=media&#x26;token=49f2bf95-2113-45c3-9bc4-395839581a7d" alt=""><figcaption></figcaption></figure>



***

### 주의사항: 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 포트)\*\*를 사용해야 합니다.

<figure><img src="https://2885569511-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYKyrLLe7cm7ZOhiSB0gg%2Fuploads%2FdkxZ6ZmjQQ6An0QKR1eb%2Fimage.png?alt=media&#x26;token=fbee9c08-1c85-4bb3-baef-f731c93830b1" alt=""><figcaption></figcaption></figure>

***

### Python 기반 시리얼 통신 코드

```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 (위치 데이터 전용)

```python
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 (거리 + 위치 정보)

```python
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}")
```

***

### 전체 수신 루프 구성 (자동 파싱)

```python
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 교차 연결 여부와 포트 활성화 상태를 꼭 다시 확인해 주세요.



