A robust radio "fox" (hidden transmitter) controller for amateur radio foxhunt events. Built on the Teensy 4.1 platform with support for both Morse code CW identification and WAV file audio playback using a Baofeng UV-5R radio.
Working Demo at https://www.youtube.com/shorts/eFTWidu8624
Audio sourced from https://www.nasa.gov/historical-sounds/
Amateur radio foxhunting (also called radio direction finding or T-hunting) is a competitive activity where participants use radio direction-finding equipment to locate hidden transmitters called "foxes." This project provides an automated, reliable controller for those hidden transmitters.
Build a production-ready fox controller with:
- Non-blocking architecture - State machine design for concurrent operations
- Morse code CW transmission - Automated callsign identification
- WAV file playback - Voice announcements and taunts from SD card
- Safety-first design - Watchdog timer, battery protection, PTT timeout
- Baofeng UV-5R integration - Proper PTT timing (1000ms pre-roll, 500ms tail)
- Battery watchdog system - Dual-threshold protection (soft warning + hard shutdown)
- Extended battery life - Deep sleep between transmissions (future)
- Field-proven reliability - 12+ hour operation with 4.5Ah battery (extensible to 30+ hours with larger batteries)
Two working reference implementations demonstrating core functionality (now archived):
1. Morse Code Controller (archived-files/Morse Code Controller.mdc)
- Blocking implementation for CW identification
- Standard ITU Morse timing
- Configurable WPM and tone frequency
- Pin 2 PTT control, Pin 12 audio output
- 1000ms pre-roll, 500ms tail timing
2. Audio Controller (archived-files/Audio Controller Code.mdc)
- Blocking implementation for WAV playback
- Teensy Audio Library integration
- SD card support (built-in Teensy 4.1 slot)
- MQS audio output on Pin 12
- Automatic playback completion detection
These reference implementations proved the concept and provided working code patterns for the production system.
Production Controller (controller/controller-production/controller-production.ino)
Version 1.3 - Documentation alignment with Project Specification v2.0:
Core Features Implemented:
- ✅ Random WAV file selection (automatic SD card scanning)
- ✅ Intelligent playback (loop if <30s, play to completion if >=30s)
- ✅ Battery monitoring with 5-state system (GOOD/LOW/VERY_LOW/SHUTDOWN/CRITICAL)
- ✅ Morse code station ID (FCC compliant)
- ✅ LED status indicators (Morse battery patterns)
- ✅ Dual logging (Serial Monitor + SD card)
- ✅ PTT timeout watchdog (90s max)
- ✅ Reset cause detection for troubleshooting
- ✅ Audio memory optimization (40 blocks)
Recent Updates (v1.3):
- ✅ Documentation aligned with Project Specification v2.0
- ✅ Clarified power architecture (single buck for Teensy, optional buck for radio)
- ✅ Updated performance metrics (60s TX cycle, ~12.5 hour runtime with 4.5Ah battery)
- ✅ Added Pin 10 MQS configuration details
- ✅ Documented foil tape SD card fix
- ✅ Standardized on 150 MHz minimum CPU speed
Field-Tested Performance:
- 8+ consecutive cycles with zero errors
- Stable operation with random file selection
- Complete transmission cycles (PTT + Morse + WAV + ID)
- Peak audio memory: 2-5 blocks (40 allocated for safety margin)
- No reboots or crashes during normal operation
- Clean audio quality with RF shielding
Hardware Requirements for Stability:
- Ferrite beads on radio and Teensy power lines (tight/snug fit)
- Foil tape over SD card slot (covers card slot opening - critical fix from field testing)
- Class 10 or better SD card, freshly formatted FAT32
Ready for field deployment!
After production system is stable:
- Power management - Deep sleep during idle periods (~5mA vs ~100mA)
- Duty cycle management - Prevent radio overheating (20% max)
- Configuration system - SD card based config file
- Remote control - DTMF commands (optional hardware)
- VOX activation - Silent operation until "called" (optional)
- Teensy 4.1 microcontroller (Cortex-M7 @ 600MHz, configured to 150 MHz minimum)
- Baofeng UV-5R radio (set to LOW power: 1W)
- 2N2222 NPN transistor (PTT control)
- 12V LiFePO4 battery (Bioenno 4.5Ah recommended)
- Buck converter: 5.0V for Teensy VIN
- BL-5 Battery Eliminator for radio (direct from 12V battery)
- Optional Buck A (8.0V): May be required for cheaper off-market battery eliminators (field testing recommended)
- Quality BL-5 eliminators work directly from 12V battery
- MicroSD card (8GB+, FAT32 formatted)
- 5A inline fuse (XT60 main battery lead)
Components:
- 1kΩ resistor (low-pass filter with capacitor)
- 10µF electrolytic capacitor (DC blocking)
- 10kΩ linear potentiometer (volume control)
Purpose: Smooths MQS PWM output and prevents radio distortion
Components:
- 10kΩ resistor (R1) - Battery+ to Pin A9
- 2.0kΩ resistor (R2) - Pin A9 to Ground
- 100nF ceramic capacitor (noise filter, parallel with R2)
Purpose: Real-time voltage monitoring for dual-threshold battery protection
Components:
- 0.1µF ceramic capacitor (104) - soldered across buck converter output
- 3× snap-on ferrite cores:
- Two (2) on radio power lines
- One (1) on Teensy power lines
- Foil tape over SD card slot - covers the card slot opening
Purpose: Prevents RF coupling during 1W transmission and eliminates SD card read/write errors (discovered during field testing)
- Project Specification v2.0.md - Complete wiring specifications, pinout, voltage calculations, power architecture, operational logic, and reference implementation examples
| Function | Teensy Pin | Connection |
|---|---|---|
| PTT Control | Pin 2 | Digital Output → 1kΩ → 2N2222 base |
| Audio Out (Primary) | Pin 12 | MQS → 10µF cap → 1kΩ → 10kΩ pot → Radio mic |
| Audio Out (Secondary) | Pin 10 | MQS → 10µF cap → 1kΩ → Ground (filter path) |
| Status LED | Pin 13 | Built-in LED (heartbeat/TX/warning/SOS) |
| Battery Monitor | Pin A9 | Via voltage divider (10kΩ + 2.0kΩ + 100nF cap) |
| Power In | VIN | 5.0V from buck converter |
| Ground | GND | Star ground configuration (all grounds meet at ONE point) |
Start here:
- Project Specification v2.0.md - Master reference document (hardware specs, power architecture, operational requirements)
Reference implementations:
audio_wav_test/audio_wav_test.ino- Audio and transmission control referencebattery_monitor_test/battery_monitor_test.ino- Battery monitoring reference
Follow wiring specifications in Project Specification v2.0.md:
- Power system - 5V buck converter for Teensy, direct 12V to BL-5 eliminator (optional 8.0V buck for cheaper eliminators)
- PTT circuit - 2N2222 transistor with 1kΩ base resistor
- Audio circuit - Dual MQS output (Pin 12 + Pin 10) with 1kΩ resistor + 10µF cap + 10kΩ pot
- Battery monitor - Voltage divider on Pin A9 (10kΩ + 2.0kΩ)
- Star ground - All grounds meet at one common point
Critical RF Suppression:
- 2× ferrite beads on radio power lines
- 1× ferrite bead on Teensy power line
- 0.1µF ceramic capacitor across buck converter output
- Foil tape over SD card slot (covers card slot opening, eliminates read/write errors during transmission)
Format microSD card as FAT32 and add WAV files:
SD_CARD/
├── Apollo8a.wav # NASA Apollo 8 audio
├── JFKmoon1.wav # JFK Moon speech
├── Skylab02.wav # Skylab audio
├── WWVBBL01.wav # WWV time station
└── WWVMarks.wav # WWV time marks
Audio file specs:
- Format: 16-bit PCM WAV
- Sample rate: 22.05kHz or 44.1kHz
- Mono (recommended for best compatibility)
- Remove all metadata from files
- Use 8.3 filename format (8 chars + .WAV extension)
Automatic Selection:
- Controller scans SD card root directory at startup
- Randomly selects one file per transmission cycle
- Files < 30s automatically loop to reach 30s minimum
- Files >= 30s play to completion (no looping)
Location: controller/controller-production/controller-production.ino
Configuration:
- Open file in Arduino IDE 2.3.7
- Update
CALLSIGN_IDconstant with your call sign (e.g., "WX7V/F") - Verify CPU speed: Tools → CPU Speed → 150 MHz or higher (critical!)
- Select board: Tools → Board → Teensy 4.1
- Upload to Teensy
Important: CPU speed must be 150 MHz or higher for stable WAV playback. Lower speeds will cause audio glitches or crashes.
Initial Testing:
- Open Serial Monitor (115200 baud)
- Observe startup sequence and reset cause
- Verify WAV files are detected
- Watch first transmission cycle complete
- Check audio quality and battery voltage
Field Deployment Checklist:
- ✅ Multiple transmission cycles completed without errors
- ✅ Battery voltage reading accurately
- ✅ Audio output clean (no distortion)
- ✅ PTT timing correct (1000ms pre-roll, 500ms tail)
- ✅ RF suppression installed (ferrites + capacitors)
- ✅ Station ID transmitting correctly
Critical for battery protection:
- Connect fully charged battery (14.6V)
- Measure voltage at Pin A9 with multimeter
- Calculate ratio:
actual_ratio = 14.6V / measured_voltage - Update
VOLTAGE_DIVIDER_RATIOconstant in code - Test at 13.0V and 12.4V to verify accuracy
See Project Specification v2.0.md for voltage divider specifications and battery_monitor_test/battery_monitor_test.ino for calibration reference code.
This is safety-critical code - a stuck PTT can drain batteries, overheat equipment, or cause interference.
1. PTT Timeout Watchdog
- 90-second maximum transmission time
- Automatic PTT release if timeout exceeded
- Prevents stuck PTT from draining battery or overheating radio
- System continues running normally after forced PTT release
2. Multi-State Battery Protection
-
GOOD (≥12.0V / 3.0V per cell):
- Normal operation, LED heartbeat blink
-
LOW (≥11.0V / 2.75V per cell):
- Monitor closely, operation continues
-
VERY_LOW (≥10.5V / 2.625V per cell):
- Warning zone, rapid LED blink (200ms)
-
SHUTDOWN (≥10.2V / 2.55V per cell):
- Completes current TX with station ID, then disables future transmissions
- SOS LED pattern (...---...)
-
CRITICAL (<10.2V / <2.55V per cell - LVP threshold):
- IMMEDIATE PTT disable (set to INPUT mode)
- PERMANENT shutdown until power cycle
- Conservative threshold protects LiFePO4 battery cycle life
3. Non-Blocking Architecture
- Responsive to all safety checks
- Concurrent monitoring (battery, watchdog, timing)
- No
delay()calls in production code
Why 10.2V critical shutdown? This conservative LVP (Low Voltage Protection) threshold (2.55V per cell) protects LiFePO4 battery cycle life and ensures reliable operation per Project Specification v2.0.
CPU Speed: 150 MHz minimum (REQUIRED for v1.3)
- Production controller requires 150 MHz minimum for stable WAV playback with SD card operations
- 396 MHz recommended for optimal performance and power balance
- Lower speeds will cause WAV playback to fail due to insufficient SD card read/decode performance
- Set in Arduino IDE: Tools → CPU Speed → 150 MHz or higher
Radio Power: LOW (1W)
- Reduces current from ~1.5A to ~0.35-0.4A (75% savings)
- Minimizes RF interference with Teensy
- Sufficient range for typical foxhunts (0.5-2 miles)
- Set via radio menu: Menu → 2 (TXP) → LOW
Runtime: ~12.5 hours with 4.5Ah battery (80% DoD). See Project Specification v2.0 for battery capacity comparison table (3.0Ah to 12.0Ah options extend runtime from 8 hours to 33 hours).
| Metric | Value | Notes |
|---|---|---|
| Battery Life (Practical) | ~12.5 hours | 4.5Ah LiFePO4 @ 80% DoD, 60s TX / 240s idle (5-min cycle) |
| Battery Life (Theoretical) | ~15.6 hours | 4.5Ah LiFePO4 @ 100% capacity (not recommended) |
| Transmit Duration | 60 seconds | Per cycle (Morse + WAV + Station ID) |
| PTT Pre-roll | 1000ms | Required for Baofeng squelch opening |
| PTT Tail | 500ms | After transmission ends |
| Duty Cycle | 20% | 60s TX / 300s total cycle (safe for continuous operation) |
| Average Current | ~289mA | Combined system @ 12V (radio + Teensy) across TX/idle cycles |
| TX Current | ~1049mA @ 12V | Radio (1W) + Teensy during transmission |
| Idle Current | ~99mA @ 12V | Radio RX + Teensy between transmissions |
| Deep Sleep | ~5mA | With Snooze library (future implementation) |
| Battery Voltage | Cell Voltage | Pin A9 Voltage | Status |
|---|---|---|---|
| 13.8V | 3.45V | 2.30V | Fully Charged (LiFePO4 max) |
| 13.0V | 3.25V | 2.17V | Nominal |
| 12.0V | 3.00V | 2.00V | ✅ GOOD |
| 11.0V | 2.75V | 1.83V | |
| 10.5V | 2.625V | 1.75V | |
| 10.2V | 2.55V | 1.70V | 🛑 SHUTDOWN |
| <10.2V | <2.55V | <1.70V | 🔴 CRITICAL (immediate PTT disable) |
Voltage Divider: 10kΩ (R_High) + 2.0kΩ (R_Low) on Pin A9
Divider Ratio: 6.0 (Battery voltage = Pin voltage × 6.0)
- Project Specification v2.0.md - SINGLE SOURCE OF TRUTH for hardware specs, power architecture, pinout, operational requirements, and implementation examples
- controller-production.ino - Production controller v1.3 (field-ready)
- audio_wav_test/audio_wav_test.ino - Audio & transmission control reference (WAV playback, Morse, PTT timing, MQS configuration)
- battery_monitor_test/battery_monitor_test.ino - Battery monitoring reference (voltage divider, 5-state system, debouncing, LED patterns)
- CHANGELOG.md - Detailed change log and version history
- archived-files/ - Phase 1 blocking implementations (not for production use)
- .cursorrules - AI-assisted development guidelines and project rules
- Morse code CW transmission (reference implementation)
- WAV file audio playback (reference implementation)
- Basic PTT control with proper timing
- Hardware specifications documented
- Software requirements documented
Core Implementation:
- Random WAV file selection with automatic SD scanning
- Intelligent playback (loop if <30s, play to completion if >=30s)
- Battery monitoring with 5-state system
- PTT timeout watchdog (90s max)
- Morse code station ID (FCC compliant)
- LED status indicators (Morse battery patterns)
- Dual logging (Serial Monitor + SD card)
- Reset cause detection
- Audio memory optimization
- SD card contention handling
- WAV file validation
Testing Complete:
- No blocking operations during WAV playback
- PTT timing accurate (1000ms pre-roll, 500ms tail)
- Battery protection triggers correctly
- Stable operation through multiple transmission cycles
- Field-tested with RF transmission
- Deep sleep power management
- Duty cycle tracking and enforcement
- Configuration system (CONFIG.TXT on SD card)
- DTMF remote control (optional hardware)
- VOX activation mode (optional hardware)
- Amateur Radio Foxhunts - Competitive direction-finding events
- Training Exercises - Practice radio direction-finding skills
- Emergency Preparedness - Search and rescue training
- Educational Demos - Teaching RF propagation and antenna theory
- Field Day Activities - Fun side activities at ham radio events
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright © 2026 Chris L White, WX7V
Hardware specifications created with assistance from Gemini 3
Code development with assistance from Claude Sonnet 4.5
This software is designed for amateur radio operations only. Users are responsible for:
- Compliance with FCC Part 97 rules (US) or equivalent regulations
- Proper station identification (every 10 minutes minimum)
- Licensed operation on authorized frequencies
- Adherence to duty cycle and power limitations
The authors assume no liability for improper or unlicensed use of this software.
- PJRC - For the excellent Teensy platform and Audio Library
- Amateur Radio Community - For foxhunting traditions and techniques
- Google DeepMind - For Gemini 3 AI assistance in hardware design
- Anthropic - For Claude Sonnet 4.5 AI assistance in code development
Chris L White, WX7V
Project repository: GitHub - teensy4.1 foxhunt controller
73 de WX7V 📡🦊
Good luck and happy hunting!