Chapter: 7b (Week 9) Duration: 4 hr Substrate: ANTSDR E200 (mandatory; see lab-server scheduling for remote students) Points: 10
Overview
Use the ANTSDR E200 in full-duplex mode to simultaneously transmit and receive IQ at different frequencies. Build a complete gr-iio GNU Radio pipeline from scratch. This lab requires physical or lab-server access to the ANTSDR E200.
Remote students without direct E200 access: Contact the instructor to schedule lab-server E200 time. The lab server exposes the E200 via the IIO network context at ip:<server-address>. Connect your GNU Radio instance to ip:<server> instead of ip:192.168.1.10.
Part 1: ANTSDR E200 Smoke Test (30 min)
Verify the E200 is reachable and functional:
# Network connectivity
ping -c 3 192.168.1.10
# IIO device discovery
iio_info -u "ip:192.168.1.10"
# Expect: iio:device0 = ad9361-phy; iio:device1 = cf-ad9361-lpc (RX DMA); iio:device2 = cf-ad9361-dds-core-lpc (TX)
# Read AD9361 hardware parameters
iio_attr -u "ip:192.168.1.10" -c ad9361-phy voltage0 sampling_frequency
# Returns current sample rate
# Set RX frequency to 433.92 MHz via CLI
iio_attr -u "ip:192.168.1.10" -c ad9361-phy altvoltage0 frequency 433920000
Part 2: RX-Only Flowgraph (45 min)
Build a simple receive-only flowgraph using the PlutoSDR Source block (gr-iio):
[PlutoSDR Source]
URI: ip:192.168.1.10
Frequency: 433.92e6
Sample Rate: 2e6
RF Bandwidth: 2e6
Buffer size: 32768
Gain: Manual, 40 dB
|
[DC Blocker] (length=32)
|
[Low Pass Filter]
(cutoff=200e3, transition=50e3, sample_rate=2e6)
|
[QT GUI Frequency Sink]
(center_freq=433.92e6, bandwidth=2e6, ref=-60, y_per_div=10)
|
[QT GUI Waterfall Sink]
(center_freq=433.92e6, bandwidth=2e6)
Run the flowgraph. You should see the 433 MHz ISM band in the spectrum and waterfall displays. Tune to any active signal you can see.
Capture 10 seconds to file:
Add a File Sink block after the LPF. Record antsdr-rx-433.iq (10 seconds at 2 MSPS = 80 MB as complex64).
Part 3: TX-Only Flowgraph (45 min)
RF-shielded enclosure required. Do not operate transmit flowgraph without the Faraday cage.
Build a transmit-only flowgraph:
[Signal Source]
Waveform: Sine
Frequency: 100e3 (100 kHz offset from TX centre)
Amplitude: 0.5
|
[Multiply Const] (0.5)
|
[PlutoSDR Sink]
URI: ip:192.168.1.10
Frequency: 433.5e6 (500 kHz offset from 433.92 MHz; stay within ISM band)
Sample Rate: 1e6
RF Bandwidth: 1e6
Attenuation: 60 dB (low power; in shielded enclosure)
Buffer size: 32768
Verify: on a separate receive flowgraph (RTL-SDR or second ANTSDR E200 context), confirm the tone is visible at 433.5 + 0.1 = 433.6 MHz.
Part 4: Full-Duplex Loopback (60 min)
Connect TX output to RX input via a short coaxial cable + 30 dB attenuator (or use the RF shielded test enclosure's TX/RX ports). Run TX and RX simultaneously in one flowgraph:
[Signal Source (100kHz sine)] → [PlutoSDR Sink] (TX @ 433.5 MHz, atten=40 dB)
[PlutoSDR Source] (RX @ 433.5 MHz, gain=30 dB, SR=2 MSPS) → [DC Blocker] → [Low Pass Filter] → [QT GUI Frequency Sink]
The same GNU Radio flow graph can connect to both TX and RX contexts of the same E200. Both PlutoSDR Source and PlutoSDR Sink use ip:192.168.1.10.
Observation: You should see your transmitted CW tone at +100 kHz in the RX spectrum display. The loopback path through the cable + attenuator confirms TX and RX are both functional.
Measure TX-to-RX isolation: Vary the TX attenuation (PlutoSDR Sink attenuation parameter) in steps (30/40/50/60 dB). For each, record the received tone amplitude from the QT GUI Frequency Sink. Plot: TX attenuation vs. RX signal level.
# Expected relationship: RX_level(dBm) = TX_power(dBm) - cable_attenuation(dB) - TX_atten_setting(dB) + RX_gain(dB)
# Solve for cable_attenuation from your measurements
Part 5: Custom OOK Transmitter (30 min)
Replace the CW Signal Source with an OOK modulated signal:
[Bernoulli Binary Source] → [Repeat (8 samples/bit)] → [Float to Complex]
|
[PlutoSDR Sink] (TX @ 433.5 MHz)
On the RX side, add: Low Pass Filter → Complex to Real → Binary Slicer → File Sink (rx_bits.bin).
Verify that transmitted bits are recovered correctly:
import numpy as np
# tx_bits and rx_bits should match (after accounting for delay)
tx_bits = np.fromfile("tx_bits.bin", dtype=np.float32)
rx_bits = np.fromfile("rx_bits.bin", dtype=np.float32)
delay = 20 # samples; adjust
match_rate = (tx_bits[delay:len(rx_bits)+delay] == rx_bits[:len(tx_bits)-delay]).mean()
print(f"Loopback bit accuracy: {match_rate*100:.1f}%")
# Expect > 95% for clean loopback
Deliverables
- ANTSDR E200 smoke test output (
iio_infooutput, first 10 lines) - RX flowgraph screenshot + spectrum screenshot showing an ISM-band signal
- TX flowgraph screenshot
- Full-duplex loopback: TX attenuation sweep measurements table + brief analysis
- OOK loopback bit accuracy output from Python verification
Grading (10 points)
| Item | Points |
|---|---|
| Smoke test output verifying E200 connectivity | 1 |
| RX flowgraph screenshot + visible signal in spectrum | 2 |
| TX flowgraph screenshot | 1.5 |
| TX attenuation sweep measurements (4+ data points) | 2.5 |
| OOK loopback bit accuracy ≥90% | 3 |