A spectrum analyzer and waterfall display for the Elad FDM-DUO transceiver.
- Introduction
- Requirements
- Installation
- Getting Started
- Understanding the Display
- Controls
- Raspberry Pi Mode
- Reconnection Behavior
- Troubleshooting
Elad Spectrum provides a real-time spectrum analyzer and waterfall display for your Elad FDM-DUO Software Defined Radio. It shows:
- Spectrum Display: Real-time signal strength across 192 kHz bandwidth
- Waterfall Display: Signal history over time with color-coded intensity
- Radio Status: Current frequency, mode, filter bandwidth, and VFO
- Filter Visualization: Bandwidth lines showing your receiver's passband
The application connects to your FDM-DUO via USB for spectrum data and serial port for radio control information.
- Elad FDM-DUO transceiver
- USB connection to computer
- Serial port connection (typically
/dev/ttyUSB0)
Debian/Ubuntu:
sudo apt install libgtk-4-1 libusb-1.0-0 libfftw3-3For Raspberry Pi (optional encoder support):
sudo apt install libgpiod2You need access to USB and serial devices:
# Add yourself to the dialout group (for serial port)
sudo usermod -a -G dialout $USER
# Create udev rule for FDM-DUO USB access (optional)
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1721", ATTR{idProduct}=="061a", MODE="0666"' | \
sudo tee /etc/udev/rules.d/99-elad-fdm-duo.rules
sudo udevadm control --reload-rules
# Log out and back in for group changes to take effect# Install build dependencies
sudo apt install libgtk-4-dev libusb-1.0-0-dev libfftw3-dev meson ninja-build
# Build
meson setup build
meson compile -C build
# Run
./build/elad-spectrum- Connect your FDM-DUO to your computer via USB
- Turn on the FDM-DUO
- Run the application:
./build/elad-spectrum
| Option | Description |
|---|---|
-f, --fullscreen |
Start in fullscreen mode |
-p, --pi |
Raspberry Pi mode (800x480, dark theme, encoder support) |
-h, --help |
Show help message |
# Normal windowed mode (1024x768)
./build/elad-spectrum
# Fullscreen
./build/elad-spectrum -f
# Raspberry Pi with 5" LCD
./build/elad-spectrum -p -fβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β VFO A β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β 14.200000 MHz USB 2.4k β β
β β +0 ββ¬ββββββββββββββββββββββ¬ββββββββββββββββββββββ¬ββ β β
β β β β β β β
β β-30 ββ€ β±β² β±β² ββ±β² β β β
β β β β± β² β± β² β±β β² β β β
β β-60 ββ€ β± β²β± β²β± β β² β±β² β β β
β β β β± β β² β± β² β β β
β β-90 ββ€ β± β β²β± β² β β β
β β βββββ±ββββββββββββββββββββββββββββββββ²ββββββ β β
β β-120ββ΄βββββββββββββββββββββ΄ββββββββββββββββββββββ΄ββ β β
β β 14.100 14.150 14.200 14.250 14.300 β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β LOCAL 14:32:15 UTC 12:32:15 β β
β β 0s βββββββββββββββββββββββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββ β β
β β 5s βββββββββββββββββββββββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββ β β
β β 10sβββββββββββββββββββββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β β Ref [-30] Rng [120] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Green circle (β): Connected and receiving data
- Gray circle (β): Disconnected or not streaming
- Red circle (β): Error state
| Element | Description |
|---|---|
| Frame label | Shows current VFO (VFO A or VFO B) |
| Overlay text | Frequency, mode, and filter bandwidth (cyan) |
| Cyan trace | Real-time signal strength |
| Red vertical line | Tuned frequency marker |
| Left axis | Signal strength in dB |
| Bottom axis | Frequency in MHz |
| Grid | 10x10 reference grid |
| Element | Description |
|---|---|
| Time labels | Time since signal was received (left side) |
| LOCAL/UTC | Current time display (top corners) |
| Colors | Signal strength: black (weak) β blue β cyan β green β yellow β red (strong) |
| Red dashed lines | Filter bandwidth edges |
| Orange dashed lines | CW resonator filter (100 Hz modes) |
The dashed vertical lines on the waterfall show your filter passband:
| Mode | Line Display |
|---|---|
| USB | Single line at upper filter edge |
| LSB | Single line at lower filter edge |
| CW, AM, FM | Two symmetric lines around center |
| Data modes (D300, D600, D1k) | Two lines centered at +1500 Hz offset |
| CW Resonator (100&1-4) | Orange lines, 100 Hz bandwidth |
The waterfall uses this color gradient for signal strength:
Weak Strong
β β
βΌ βΌ
Black β Blue β Cyan β Green β Yellow β Red
| Control | Function |
|---|---|
| Ref spinner | Reference level (top of display) in dB |
| Rng spinner | Dynamic range (display span) in dB |
Typical Settings:
- Strong signals: Ref = -20 dB, Range = 80 dB
- Weak signals: Ref = -40 dB, Range = 100 dB
- Very weak signals: Ref = -50 dB, Range = 120 dB
Your display settings are automatically saved:
- Auto-save: 3 seconds after any change
- On exit: When you close the window
- Location:
~/.config/elad-spectrum/settings.conf
Saved settings include:
- Spectrum reference and range
- Waterfall reference and range
- Zoom level and pan offset (Pi mode)
Pi mode (-p flag) is optimized for embedded displays like the official 5" LCD.
- Window size: 800x480 pixels
- Dark theme (black background)
- Compact control bar showing all parameters:
β SP.REF -30 SP.RNG 120 WF.REF -30 WF.RNG 120 SPAN 192 OFS +0
Pi mode supports two rotary encoders for hands-free control.
| Encoder | Function | GPIO Pin |
|---|---|---|
| Encoder 1 | CLK (rotation) | GPIO 17 |
| Encoder 1 | DT (direction) | GPIO 27 |
| Encoder 1 | SW (button) | GPIO 22 |
| Encoder 2 | CLK (rotation) | GPIO 5 |
| Encoder 2 | DT (direction) | GPIO 6 |
| Encoder 2 | SW (button) | GPIO 13 |
Connect encoder common pins to ground. Internal pull-ups are enabled.
| Action | Effect |
|---|---|
| Button press | Cycle through parameters (highlighted in cyan) |
| Rotate | Adjust selected parameter |
Parameters cycle: SP.REF β SP.RNG β WF.REF β WF.RNG β (repeat)
- Reference levels: Β±1 dB per click
- Range values: Β±5 dB per click
| Action | Effect |
|---|---|
| Button press | Toggle between Zoom and Pan mode |
| Rotate (Zoom mode) | Change zoom level (1x β 16x) |
| Rotate (Pan mode) | Move view left/right |
Zoom Levels:
| Zoom | Span | Resolution |
|---|---|---|
| 1x | 192 kHz | 46.9 Hz/bin |
| 2x | 96 kHz | 23.4 Hz/bin |
| 4x | 48 kHz | 11.7 Hz/bin |
| 8x | 24 kHz | 5.9 Hz/bin |
| 16x | 12 kHz | 2.9 Hz/bin |
The active mode (SPAN or OFS) is highlighted in cyan.
The application automatically handles radio power cycling without needing to restart.
- The status indicator changes to gray (β)
- The spectrum and waterfall displays freeze
- The application begins polling for the device
- The application detects the USB device (may take a few seconds)
- A 3-second stabilization delay allows the FPGA to initialize
- The CAT serial port is reopened
- Streaming resumes and displays update
- The status indicator returns to green (β)
- The entire reconnection process takes approximately 5-8 seconds
- Your display settings (ref level, range, zoom, pan) are preserved
- The frequency display may briefly show invalid data during reconnection
- No manual intervention is required - just wait for the radio to fully boot
Cause: USB permission denied or device not connected.
Solutions:
- Check USB connection
- Verify FDM-DUO is powered on
- Run with sudo (temporary):
sudo ./build/elad-spectrum - Set up udev rules (permanent):
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1721", ATTR{idProduct}=="061a", MODE="0666"' | \ sudo tee /etc/udev/rules.d/99-elad-fdm-duo.rules sudo udevadm control --reload-rules
- Unplug and replug the USB cable
Cause: Serial port permission denied or wrong device.
Solutions:
- Add yourself to dialout group:
sudo usermod -a -G dialout $USER # Log out and back in
- Check if device exists:
ls -la /dev/ttyUSB* - The FDM-DUO serial port may be on a different device (ttyUSB1, etc.)
Cause: Application can't find or communicate with FDM-DUO.
Solutions:
- Ensure FDM-DUO firmware is up to date
- Try unplugging other USB devices
- Use a shorter or higher-quality USB cable
- Try a different USB port (USB 2.0 recommended)
Possible causes:
- USB streaming not started (check status indicator)
- FDM-DUO in standby mode
- Antenna not connected
Solutions:
- Wait a few seconds after connection
- Check that FDM-DUO front panel shows activity
- Verify antenna connection
Cause: CAT serial connection not working.
Solutions:
- Check serial cable connection
- Verify correct serial port
- CAT control is optional - spectrum will still work
Cause: Display range may not match signal levels.
Solutions:
- Adjust Ref (reference level) to match your signals
- Increase Rng (range) for more dynamic range
- Check that signals are present on the spectrum display
Possible causes:
- Not running in Pi mode
- GPIO permission denied
- Wiring incorrect
Solutions:
- Ensure you're using
-pflag - Check GPIO permissions (may need to run as root first time)
- Verify wiring matches the GPIO table above
- Check encoder common is connected to ground
Solution: Use both -p and -f flags:
./build/elad-spectrum -p -fNormal behavior: The application processes ~15 FFT frames per second.
If excessive:
- Close other applications
- On Raspberry Pi, ensure GPU memory is set appropriately
- Check for thermal throttling
Cause: System unable to maintain display refresh rate.
Solutions:
- Close other applications
- Reduce window size
- On Pi, use fullscreen mode for better performance
Currently, all interaction is via the control bar and optional rotary encoders. Future versions may add keyboard shortcuts.
| Parameter | Value |
|---|---|
| Sample rate | 192 kHz |
| FFT size | 4096 points |
| Frequency resolution | 46.9 Hz/bin |
| Spectrum averaging | 3 frames |
| Update rate | ~15.6 Hz |
| Display refresh | 30 fps |
- Issues: GitHub Issues
- Source: GitHub Repository