---
title: "xtrsdr"
url: "https://maker.wiznet.io/TheoIm/projects/xtrsdr/"
markdown_url: "https://maker.wiznet.io/TheoIm/projects/xtrsdr/md"
type: "UCC: User Created Content"
author: "XTR1984"
author_url: "https://github.com/XTR1984/xtrsdr"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "XTR1984"
original_url: "https://github.com/XTR1984/xtrsdr"
published: "2026-06-24"
language: "ko"
hardware: ["WIZnet W5500"]
likes: 0
views: 174
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# xtrsdr

> 이 프로젝트는 ESP32-S2에 RTL-SDR USB 동글을 직접 연결하고, 수신한 IQ 샘플을 rtl_tcp 형식으로 네트워크에 내보내는 실험형 SDR 수신기입니다.

Original author: XTR1984 (source: https://github.com/XTR1984/xtrsdr)

## Components

- **WIZnet W5500** x 1 ([docs](https://docs.wiznet.io/Product/Chip/Ethernet/W5500))

WIZnet parts: W5500 ([Datasheet](https://docs.wiznet.io/Product/Chip/Ethernet/W5500/datasheet?utm_source=maker&utm_medium=project&utm_campaign=w5500), [product hub](https://maker.wiznet.io/products/w5500/))

## Article

## 어떤 문제를 풀려고 했나?

RTL-SDR은 일반적으로 PC나 Raspberry Pi 같은 Linux 기반 시스템에서 사용됩니다. 이 프로젝트는 그 구성을 MCU 수준까지 축소해 ESP32-S2 하나로 RTL-SDR을 제어하고, 네트워크를 통해 원격 SDR 서버처럼 동작할 수 있는지 검증합니다.

설계 관점에서 해결해야 할 과제는 세 가지입니다.

1. ESP32-S2가 USB Host로 RTL2832U + R820T2 기반 RTL-SDR 동글을 제어해야 합니다.

2. 연속적으로 들어오는 IQ 샘플을 MCU 내부에서 버퍼링해야 합니다.

3. 기존 SDR 프로그램과의 호환성을 위해 `rtl_tcp` 프로토콜을 유지해야 합니다.

그래서 프로젝트는 새로운 프로토콜을 정의하지 않고 `rtl_tcp` 서버 구조를 그대로 구현했습니다. 덕분에 GQRX, SDRSharp, SDR++와 같은 기존 SDR 클라이언트를 수정 없이 사용할 수 있습니다.

---

## 왜 Ethernet 경로가 필요했나?

SDR IQ 데이터는 센서처럼 간헐적으로 전송되는 데이터가 아니라 지속적으로 발생하는 스트림입니다. Wi-Fi도 사용할 수 있지만, SDR 수신기 주변에서 무선 송신이 동시에 이루어질 경우 지연 변화나 RF 간섭 가능성을 함께 고려해야 합니다.

저장소에는 Wi-Fi 기반 구현과 W5500 Ethernet 기반 구현이 함께 존재합니다. README에서도 Wi-Fi 기반 스트리밍 안정성을 확보하는 과정이 쉽지 않았다는 취지의 설명이 포함되어 있습니다.

이러한 배경에서 Ethernet 구현은 단순히 "Wi-Fi 대신 Ethernet"이 아니라, SDR 스트림을 보다 안정적으로 전달하기 위한 별도의 네트워크 경로를 구성하려는 설계 선택으로 볼 수 있습니다.

```plaintext
RTL-SDR USB Dongle
        │
        │ USB Host
        ▼
ESP32-S2
        │
        │ SPI
        ▼
WIZnet W5500 Ethernet Module
        │
        │ TCP / Ethernet
        ▼
GQRX / SDRSharp / SDR++ (rtl_tcp Clients)
```

---

## 왜 W5500인가?

이 프로젝트에서 W5500은 단순히 인터넷 연결을 제공하는 Ethernet 칩이 아닙니다.

ESP32-S2가 USB를 통해 수집한 IQ 데이터를 SDR 분석 프로그램으로 전달하는 **유선 네트워크 인터페이스** 역할을 수행합니다.

프로젝트에서 W5500을 선택한 이유는 다음과 같습니다.

- Wi-Fi 송신 없이 SDR IQ 데이터를 TCP로 전달할 수 있습니다.

- ESP-IDF Ethernet 드라이버를 통해 SPI Ethernet 인터페이스를 쉽게 구성할 수 있습니다.

- 애플리케이션은 일반 BSD Socket API를 그대로 사용할 수 있습니다.

- SDR 클라이언트에서는 일반적인 `rtl_tcp` 서버와 동일하게 인식됩니다.

즉, W5500은 MCU 기반 SDR 서버를 외부 분석 환경과 연결하는 네트워크 링크 역할을 담당합니다.

---

## 소스코드에서 확인되는 W5500 사용

대표 구현은 `esp32s2/rtl_tcp_eth/w5500_macraw`입니다.

반면 `w5500_hwsockets`는 WIZnet ioLibrary 기반 하드웨어 소켓을 직접 사용하는 실험 코드이며, 현재 저장소 상태에서는 대표 구현으로 보기 어렵습니다.

`eth_config.h`에서는 W5500 사용 여부와 실제 SPI 핀 구성이 정의되어 있습니다.

```plaintext
#define CONFIG_EXAMPLE_USE_W5500 1

#define CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO 13
#define CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO 11
#define CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO 12
#define CONFIG_EXAMPLE_ETH_SPI_CS0_GPIO 10
#define CONFIG_EXAMPLE_ETH_SPI_INT0_GPIO 4

#define CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ 40
```

`sdkconfig.esp32s2`에서도 W5500 Ethernet 드라이버가 활성화되어 있습니다.

```plaintext
CONFIG_ETH_SPI_ETHERNET_W5500=y
```

초기화 과정에서는 ESP-IDF Ethernet Framework가 W5500용 MAC과 PHY를 생성합니다.

```plaintext
eth_w5500_config_t w5500_config =
    ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);

esp_eth_mac_t *mac =
    esp_eth_mac_new_w5500(&w5500_config, &mac_config);

esp_eth_phy_t *phy =
    esp_eth_phy_new_w5500(&phy_config);
```

이 코드로 W5500이 실제 Ethernet 인터페이스 생성 과정에 사용된다는 것을 확인할 수 있습니다.

---

## rtl_tcp 호환성은 어떻게 유지했나?

애플리케이션은 새로운 프로토콜을 정의하지 않고 기존 `rtl_tcp` 서버와 동일한 동작을 구현합니다.

```plaintext
#define DEFAULT_PORT_STR "1234"
#define DEFAULT_SAMPLE_RATE_HZ 240000
```

실행 과정에서는 기본 수신 설정도 다시 지정됩니다.

```plaintext
frequency = 102400000;
gain = 100;
samp_rate = 240000;
```

TCP 서버 역시 일반적인 BSD Socket API 형태입니다.

```plaintext
listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

bind(listensocket,
     (struct sockaddr *)&destAddr,
     sizeof(destAddr));

listen(listensocket, 1);

s = accept(listensocket,
           (struct sockaddr *)&remote,
           &rlen);
```

클라이언트가 접속하면 `RTL0` 매직 문자열과 튜너 정보를 먼저 전송하고, 이후 RTL-SDR 비동기 콜백에서 수집한 IQ 버퍼를 동일한 TCP 연결을 통해 지속적으로 전송합니다.

```plaintext
memcpy(&dongle_info.magic, "RTL0", 4);

send(s,
     (const char *)&dongle_info,
     sizeof(dongle_info),
     0);

bytessent =
    send(s,
         &curelem->data[index],
         bytesleft,
         0);
```

이 설계 덕분에 SDR++나 GQRX는 별도 수정 없이 ESP32-S2를 일반적인 `rtl_tcp` 서버처럼 사용할 수 있습니다.

---

## W5500 하드웨어 소켓을 직접 사용하는 구조일까?

흥미로운 점은 대표 구현이 **WIZnet ioLibrary의 하드웨어 소켓 API를 직접 사용하는 구조가 아니라는 점**입니다.

`w5500_macraw`는 ESP-IDF Ethernet 드라이버를 통해 W5500을 하나의 Ethernet 인터페이스로 등록하고, 애플리케이션은 **lwIP가 제공하는 BSD Socket API**를 그대로 사용합니다.

즉, 애플리케이션은 일반적인 TCP 서버를 구현하는 것과 거의 동일한 방식으로 작성되어 있으며, W5500은 ESP-IDF 네트워크 계층 아래에서 SPI Ethernet 인터페이스 역할을 수행합니다.

반대로 저장소에 함께 포함된 `w5500_hwsockets`는 WIZnet ioLibrary 기반 하드웨어 소켓을 직접 사용하는 별도 실험으로 보이지만, 현재 저장소 상태에서는 대표 구현보다는 실험 코드에 가까운 것으로 판단됩니다.

---

**유사 프로젝트 사례**

| 프로젝트 | 비슷한 이유 | 차이점 |
| --- | --- | --- |
| **How to Integrate WIZnet W5500 SPI Ethernet on ESP-IDF for ESP32?** | ESP-IDF 환경에서 W5500을 SPI Ethernet 인터페이스로 붙이고 lwIP 기반 네트워크를 구성하는 방식이 동일합니다. 이 프로젝트 역시 ESP-IDF Ethernet Driver를 통해 W5500을 사용한다는 점에서 구현 구조가 매우 유사합니다. | 해당 프로젝트는 Ethernet 드라이버를 컴포넌트화한 라이브러리이며, RTL-SDR이나 `rtl_tcp` 스트리밍 같은 응용 계층은 포함하지 않습니다. |
| **MicroPython-ESP32-W5500 (Wiznet)** | ESP32와 W5500을 SPI로 연결하고 Ethernet 인터페이스를 구성하는 예제로, 핀맵과 네트워크 초기화 과정을 확인할 수 있습니다. ESP32 기반 Ethernet 활용 사례라는 점에서 참고하기 좋습니다. | MicroPython 환경에서 DHCP·DNS·HTTP를 다루는 예제이며, SDR 데이터 스트리밍이나 USB Host 기능은 포함하지 않습니다. |
| **ESP32 S3 이더넷 설계 (W5500)** | ESP32 계열 MCU에서 W5500을 선택한 이유와 SPI Ethernet 하드웨어 설계, RJ45 회로 구성 등을 다룹니다. ESP32 기반 W5500 시스템을 설계한다는 점에서 하드웨어 관점의 연관성이 높습니다. | PCB 설계와 Ethernet 회로 설계가 중심이며, 본 프로젝트처럼 `rtl_tcp` 서버나 RTL-SDR 처리는 다루지 않습니다. |

#### 이 프로젝트와의 공통점

세 프로젝트 모두 **ESP32 계열 MCU와 W5500을 SPI Ethernet 인터페이스로 사용하는 구조**라는 공통점이 있습니다. 반면 이번 RTL-SDR 프로젝트는 그 위에 **USB Host 기반 RTL-SDR 제어와 **`**rtl_tcp**`** 호환 IQ 스트리밍**을 결합했다는 점에서 응용 범위가 한 단계 확장된 사례라고 볼 수 있습니다.

---

## 어떤 점이 흥미로운가?

첫째, USB Host와 RTL-SDR 포팅을 ESP32-S2 하나로 통합했다는 점입니다. 일반적으로 PC나 Linux SBC가 수행하던 역할 일부를 MCU 환경으로 옮기려는 시도입니다.

둘째, 기존 `rtl_tcp` 생태계를 그대로 활용했습니다. 새로운 클라이언트를 만드는 대신 기존 SDR 프로그램과의 호환성을 유지함으로써 실험 결과를 쉽게 검증할 수 있도록 했습니다.

셋째, W5500을 연속적인 SDR IQ 스트리밍에 적용했습니다. 일반적인 센서 데이터 전송과 달리 지속적인 데이터 흐름을 Ethernet으로 전달하는 응용 사례라는 점에서 의미가 있습니다.

넷째, 동일한 프로젝트 안에서 Wi-Fi와 Ethernet 구현을 함께 제공해 두 방식의 특성을 비교할 수 있도록 구성했습니다.

---

## 현재 상태는 어떨까?

이 프로젝트는 완성된 제품보다는 실험적인 포팅 프로젝트로 보는 것이 적절합니다.

확인되는 한계는 다음과 같습니다.

- README 일부는 문자 인코딩 문제로 읽기 어려운 부분이 있습니다.

- 빌드 및 배선 절차가 충분히 문서화되어 있지 않습니다.

- `w5500_hwsockets`는 미완성 코드가 남아 있습니다.

- 장시간 동작이나 처리량에 대한 성능 검증 자료는 추가 확인이 필요합니다.

그럼에도 ESP32-S2 USB Host와 W5500 Ethernet을 결합해 MCU 기반 SDR 서버를 구현하려는 접근 자체는 충분히 기술적인 의미가 있습니다.

---

## 결론

이 프로젝트의 핵심은 W5500 자체보다 **ESP32-S2 USB Host와 RTL-SDR 포팅을 기존 **`**rtl_tcp**`** 생태계에 연결했다는 점**에 있습니다.

W5500은 그 사이에서 실시간 IQ 스트림을 전달하는 유선 네트워크 인터페이스 역할을 수행하며, MCU 기반 SDR 서버 구현 가능성을 탐색하는 중요한 구성 요소입니다.

문서화와 안정성은 아직 실험 단계이지만, 기존 PC 중심의 RTL-SDR 활용 범위를 소형 MCU 플랫폼으로 확장하려는 시도라는 점에서 기술적으로 의미 있는 프로젝트입니다.

---

## Verified Technical Facts

| 항목 | 확인 내용 |
| --- | --- |
| 대표 Ethernet 구현 | `esp32s2/rtl_tcp_eth/w5500_macraw` |
| 실험 구현 | `w5500_hwsockets` (ioLibrary 기반) |
| Ethernet Driver | ESP-IDF W5500 MAC/PHY Driver |
| SPI Pin Map | MISO 13 / MOSI 11 / SCLK 12 / CS 10 / INT 4 |
| SPI Clock | 40 MHz |
| TCP Port | 1234 (`rtl_tcp`) |
| Default Sample Rate | 240 kS/s |
| Compatible Clients | GQRX, SDRSharp, SDR++ |

---

## FAQ

#### Q1. Why use W5500 instead of Wi-Fi for this RTL-SDR project?

**A.** 이 프로젝트는 연속적인 IQ 샘플을 `rtl_tcp` 형식으로 전송합니다. 저장소에도 Wi-Fi와 Ethernet 구현이 함께 존재하지만, Ethernet 버전은 SDR 스트림을 보다 안정적으로 전달하기 위한 실험으로 구성되어 있습니다. W5500은 ESP32-S2와 SPI로 연결되어 유선 네트워크 인터페이스를 제공하며, SDR 클라이언트에서는 일반적인 `rtl_tcp` 서버처럼 사용할 수 있습니다.

---

#### Q2. Does this project use W5500 hardware sockets directly?

**A.** 대표 구현인 `w5500_macraw`는 WIZnet ioLibrary의 하드웨어 소켓 API를 직접 사용하는 구조가 아닙니다. 대신 ESP-IDF Ethernet Driver를 통해 W5500을 네트워크 인터페이스로 등록하고, 애플리케이션은 lwIP의 BSD Socket API를 사용합니다. 저장소에는 `w5500_hwsockets` 실험도 포함되어 있지만 현재 대표 구현은 `w5500_macraw`입니다.

---

#### Q3. What role does W5500 play in this project?

**A.** W5500은 USB로 수집한 RTL-SDR IQ 데이터를 PC나 스마트폰으로 전달하는 Ethernet 인터페이스 역할을 합니다. ESP32-S2는 USB Host와 SDR 처리를 담당하고, W5500은 실시간 IQ 스트림을 `rtl_tcp` 호환 TCP 연결을 통해 외부 SDR 프로그램으로 전달합니다.

---

#### Q4. Which SDR applications can connect to this server?

**A.** 프로젝트는 `rtl_tcp` 프로토콜을 유지하기 때문에 GQRX, SDRSharp, SDR++와 같이 `rtl_tcp`를 지원하는 SDR 클라이언트를 그대로 사용할 수 있습니다. 별도의 전용 프로그램 없이 기존 SDR 생태계를 그대로 활용할 수 있는 것이 특징입니다.

---

#### Q5. Can beginners reproduce this project?

**A.** 이 프로젝트는 완성된 튜토리얼보다는 실험적인 포팅 프로젝트에 가깝습니다. ESP-IDF, USB Host, SPI Ethernet, RTL-SDR에 대한 기본 이해가 필요하며, 저장소에서도 빌드 절차와 일부 구현은 추가 보완이 필요한 상태입니다.

---

> **Note:** 이 문서는 저장소의 README뿐 아니라 `eth_config.h`, `ethernet_init.c`, `main.cpp`, `sdkconfig.esp32s2`의 구현 내용을 함께 확인하여 작성했습니다.

---

Source: https://maker.wiznet.io/TheoIm/projects/xtrsdr/
