ESP32 + 개발자 태그 Q1 연동 및 위치 데이터 수신

본 가이드는 GrowSpace UWB 개발자 태그를 Arduino ESP32 보드와 연결하여,
leclep 명령어를 통해 실시간 위치 데이터를 수신하고 파싱하는 실습 과정을 설명합니다.

ESP32는 UNO와 달리 다중 하드웨어 시리얼을 지원하고, 소형 보드로 확장성이 뛰어나
경량 테스트 환경 구성에 적합합니다.

준비물

시리얼 통신을 시작하기 위해 다음과 같은 준비물이 필요합니다:

  • 아두이노 ESP32 보드 (예: DevKitC)
  • GrowSpace 개발자 태그
  • Arduino IDE
  • 점퍼 케이블 (TX, RX, GND, 3.3V)

Arduino IDE 설치 및 ESP32 보드 설정

  1. Arduino IDE 설치
    공식 다운로드 페이지에서 운영체제에 맞는 설치 파일 다운로드
    ※ 본 가이드는 Windows 기준 MSI Installer 사용
  2. ESP32 보드 설치 및 추가
  • IDE 실행 후 File > Preferences 메뉴 진입
  • Additional Board Manager URLs 입력란에 다음 주소 추가:
  • 설치 완료 후 Tools > Board > ESP32 Dev Module 선택
  • Tools > Port에서 자동 인식된 포트 선택
이 이미지는 대체 속성이 비어있습니다. 그 파일 이름은 image-13.png입니다

시리얼 연결 구성

GrowSpace 개발자 태그는 좌우 양측 커넥터가 있으며,
본 실습에서는 3.3V 기반 좌측 커넥터를 기준으로 연결합니다.

개발자 태그 핀ESP32 보드 핀
TXGPIO 16 (RX2)
RXGPIO 17 (TX2)
3.3V3.3V
GNDGND

주의: TX ↔ RX는 반드시 교차 연결해야 합니다.
예: 태그의 TX → ESP32의 RX / 태그의 RX → ESP32의 TX

아래는 ESP32 DevKit의 핀맵입니다. TX2/RX2의 위치를 확인하고 정확히 연결해 주세요:

시리얼 중계 예제 코드

시리얼 연결이 완료되면, 아래 코드로 USB ↔ 개발자 태그 간 시리얼 중계가 정상 작동하는지 확인할 수 있습니다.

#define SERIAL2_RX 16  // GPIO16
#define SERIAL2_TX 17  // GPIO17

String inputFromSerial = "";
String inputFromSerial2 = "";

void setup() {
  Serial.begin(115200);  // USB Serial
  Serial2.begin(115200, SERIAL_8N1, SERIAL2_RX, SERIAL2_TX);  // 외부 장치 UART

  Serial.println("ESP32 Serial <-> Serial2 중계 시작 (\\n 기준 누적, \\r 추가)");
}

void loop() {
  // 1. Serial 입력 → Serial2로 전송
  while (Serial.available()) {
    char ch = (char)Serial.read();
    
    if (ch != '\n') {
      inputFromSerial += ch;
    }

    if (ch == '\n') {
      Serial2.print(inputFromSerial);   // 원문 전송
      Serial2.print('\r');              // CR 추가
      //Serial.print("[Serial → Serial2] 전송: ");
      //Serial.print(inputFromSerial);
      inputFromSerial = "";  // 버퍼 초기화
    }
  }

  // 2. Serial2 입력 → Serial로 출력
  while (Serial2.available()) {
    char ch = (char)Serial2.read();
    inputFromSerial2 += ch;

    if (ch == '\n') {
      Serial.print("[Serial2 → Serial] 수신: ");
      Serial.print(inputFromSerial2);
      inputFromSerial2 = "";  // 버퍼 초기화
    }
  }
}
  • 시리얼 모니터 설정: 115200bps, 줄바꿈(Newline) 옵션 활성화
  • 예: si 명령어 입력 시 태그의 시스템 정보가 반환되어야 정상 연결
이 이미지는 대체 속성이 비어있습니다. 그 파일 이름은 image-16.png입니다

개발자 태그를 활용한 현재 태그 위치 받아서 파싱

이제 단순 응답 확인을 넘어서, 실제 위치 정보 데이터를 파싱해보겠습니다.

lec는 거리 + 위치 데이터를, lep는 위치만을 반환하는 명령어인데요,

이를 아두이노 코드로 분석해 화면에 보기 좋게 출력하는 함수입니다.

#define SERIAL2_RX 16  // GPIO16
#define SERIAL2_TX 17  // GPIO17

String inputFromSerial = "";
String inputFromSerial2 = "";

void setup() {
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, SERIAL2_RX, SERIAL2_TX);
  Serial.println("ESP32 Serial <-> Serial2 중계 (\\n 기준, \\r 추가, lep/lec 파싱)");
}

void loop() {
  // Serial 입력 → Serial2로 전송
  while (Serial.available()) {
    char ch = (char)Serial.read();
    if (ch != '\n') {
      inputFromSerial += ch;
    }

    if (ch == '\n') {
      Serial2.print(inputFromSerial);
      Serial2.print('\r');  // CR 추가
      inputFromSerial = "";
    }
  }

lep 명령어 응답 파싱 – 위치(XYZ) 정보

// ✅ LEP 결과 파서: POS,x,y,z,qf
void parseLEP(String line) {
  Serial.println("[LEP 위치 결과]");
  int idx = 0;
  String parts[5];

  while (line.length() > 0 && idx < 5) {
    int comma = line.indexOf(',');
    if (comma == -1) {
      parts[idx++] = line;
      break;
    } else {
      parts[idx++] = line.substring(0, comma);
      line = line.substring(comma + 1);
    }
  }

  Serial.print("X: "); Serial.println(parts[1]);
  Serial.print("Y: "); Serial.println(parts[2]);
  Serial.print("Z: "); Serial.println(parts[3]);
  Serial.print("품질(QF): "); Serial.println(parts[4]);
  Serial.println();
  • 출력 예시
이 이미지는 대체 속성이 비어있습니다. 그 파일 이름은 image-17.png입니다

lec 명령어 응답 파싱 – 거리 + 위치 정보

// ✅ LEC 결과 파서: DIST,...ANn,...POS,...
void parseLEC(String line) {
  Serial.println("[LEC 거리 + 위치 결과]");

  int posIndex = line.indexOf("POS,");
  if (posIndex == -1) {
    Serial.println("→ POS 정보 없음");
    return;
  }

  String distPart = line.substring(0, posIndex - 1);
  String posPart = line.substring(posIndex);

  // Anchor 정보 파싱
  int anchorIdx = 0;
  int anStart = 0;
  while ((anStart = distPart.indexOf("AN", anStart)) != -1) {
    int idStart = anStart + 2;
    int idEnd = distPart.indexOf(",", idStart);
    String id = distPart.substring(idStart, idEnd);

    int valStart = idEnd + 1;
    float x = distPart.substring(valStart, distPart.indexOf(",", valStart)).toFloat();
    valStart = distPart.indexOf(",", valStart) + 1;
    float y = distPart.substring(valStart, distPart.indexOf(",", valStart)).toFloat();
    valStart = distPart.indexOf(",", valStart) + 1;
    float z = distPart.substring(valStart, distPart.indexOf(",", valStart)).toFloat();
    valStart = distPart.indexOf(",", valStart) + 1;
    float d = distPart.substring(valStart, distPart.indexOf(",", valStart)).toFloat();

    Serial.print("AN"); Serial.print(anchorIdx++); Serial.print(" (ID "); Serial.print(id); Serial.print("): ");
    Serial.print("x="); Serial.print(x); Serial.print(", y="); Serial.print(y); Serial.print(", z="); Serial.print(z);
    Serial.print(" → 거리: "); Serial.print(d); Serial.println("m");

    anStart = valStart;
  }

  // 위치 정보 파싱
  Serial.println("▶ 태그 위치:");
  parseLEP(posPart);  // 재사용
}
  • 출력 예시

결론

본 가이드를 통해 GrowSpace UWB 개발자 태그와 ESP32 보드를 연결하고,
lec/lep 명령어 기반 위치 데이터를 수신 및 파싱하는 실습을 수행하였습니다.

ESP32의 장점을 활용하면 간편한 테스트베드 구축과 실내 위치 측위 기능 확인이 용이합니다.

혹시 위 과정 중 막히는 부분이 있다면 문의주세요. 감사합니다!

목차