If you've ever wanted to switch between multiple HF antennas without walking out to the feedpoint, this project is for you. Using an ESP32 Wi-Fi microcontroller, a 4-channel relay module, and a few SO-239 connectors, you can build a remote antenna switch that you control directly from your phone or any web browser.
Overview
The concept is simple: each antenna feedline connects to a relay that's switched by the ESP32. The ESP32 hosts a small Wi-Fi web server, allowing you to select which relay (and therefore which antenna) is active from your phone or computer. The relays handle RF path switching, and the ESP32 handles logic and connectivity.
Power Rating: This design is suitable for transmitter power levels up to 100 watts. For higher power operations, you'll need to use these relays as control relays to switch external high-power RF relays or coaxial switches.
Choosing the Right Relay Module
Look for relay modules with:
- 10A contact rating minimum (handles up to 100W safely)
- Optoisolator isolation between control and switching circuits
- COM, NO, NC terminals clearly labeled
- Active-LOW trigger (most common type)
Popular options include the HiLetgo 4-channel or Songle SRD-05VDC relay boards available from most electronics suppliers.
Wiring the System
Each relay controls the center conductor of an antenna port, connecting it to a common feedline output. The relay board's inputs (IN1–IN4) connect to GPIO pins on the ESP32, with the relay board powered from the ESP32's 5V output and ground shared between both.
Control Connections:
- Relay IN1 → ESP32 GPIO 23
- Relay IN2 → ESP32 GPIO 22
- Relay IN3 → ESP32 GPIO 21
- Relay IN4 → ESP32 GPIO 19
- Relay VCC → ESP32 5V (or external 5V supply)
- Relay GND → ESP32 GND
RF Connections:
- Antenna 1-4: Connect coax center conductors to relay COM terminals
- Common Output: Connect all relay NO (Normally Open) terminals together, then to transceiver SO-239 center conductor
- Ground all shields to metal enclosure for proper RF return path
Important: Keep the coax shield connections intact and grounded. Only the center conductors are switched by the relays.
Power Supply Notes
While the ESP32 can provide 5V to the relay module through its voltage regulator, this may be marginal when all four relays are energized. For best reliability:
- Use a 2A USB power supply for the ESP32, or
- Power the relay module from a separate 5V 2A supply, sharing only ground with the ESP32
ESP32 Web Server Code
The following Arduino sketch turns your ESP32 into a Wi-Fi access point and web server with buttons to control each relay. Upload this using the Arduino IDE with ESP32 board support installed.
// Remote Antenna Switch - ESP32 Web Server
// Author: Danny Davis - BrokenSignal.tv
// Power Rating: Up to 100 watts
#include <WiFi.h>
#include <WebServer.h>
// Wi-Fi credentials for Access Point mode
const char* ssid = "AntennaSwitch";
const char* password = "hamradio";
WebServer server(80);
// Relay control pins (active LOW)
int relays[4] = {23, 22, 21, 19};
String antennaNames[4] = {"Dipole", "Vertical", "Beam", "EFHW"};
// Track currently active relay
int activeRelay = 0;
void handleRoot() {
String html = "<html><head><title>Antenna Switch</title>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
html += "<style>";
html += "body { font-family: Arial, sans-serif; text-align: center; background: #1a1a1a; color: #fff; padding: 20px; }";
html += "h1 { color: #4CAF50; }";
html += ".button { background-color: #4CAF50; border: none; color: white; padding: 15px 32px; ";
html += "text-decoration: none; display: inline-block; font-size: 18px; margin: 10px; ";
html += "cursor: pointer; border-radius: 8px; width: 200px; }";
html += ".button.active { background-color: #FF5722; }";
html += ".info { background: #333; padding: 10px; margin: 20px auto; max-width: 400px; border-radius: 5px; }";
html += "</style></head><body>";
html += "<h1>ESP32 Antenna Switch</h1>";
html += "<div class='info'>Currently Active: <strong>" + antennaNames[activeRelay] + "</strong></div>";
for (int i = 0; i < 4; i++) {
html += "<form action='/relay' method='get' style='display:inline'>";
html += "<input type='hidden' name='r' value='" + String(i) + "'>";
String buttonClass = (i == activeRelay) ? "button active" : "button";
html += "<button class='" + buttonClass + "' type='submit'>";
html += antennaNames[i] + " (Ant " + String(i + 1) + ")</button></form>";
}
html += "<div class='info' style='margin-top: 30px; font-size: 12px;'>";
html += "Power Rating: 100W max<br>IP: " + WiFi.softAPIP().toString() + "</div>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleRelay() {
if (server.hasArg("r")) {
int index = server.arg("r").toInt();
// Validate relay index
if (index >= 0 && index < 4) {
// Deactivate all relays (set HIGH for active-LOW modules)
for (int i = 0; i < 4; i++) {
digitalWrite(relays[i], HIGH);
}
// Activate selected relay (set LOW for active-LOW)
digitalWrite(relays[index], LOW);
activeRelay = index;
Serial.print("Switched to antenna: ");
Serial.println(antennaNames[index]);
}
}
// Redirect back to main page
server.sendHeader("Location", "/");
server.send(303);
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\nESP32 Antenna Switch Starting...");
// Configure all relay pins as outputs
for (int i = 0; i < 4; i++) {
pinMode(relays[i], OUTPUT);
digitalWrite(relays[i], HIGH); // Start with all relays off
}
// Activate first antenna by default
digitalWrite(relays[0], LOW);
activeRelay = 0;
Serial.println("Default antenna: " + antennaNames[0]);
// Create Wi-Fi Access Point
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
Serial.println("SSID: " + String(ssid));
Serial.println("Password: " + String(password));
// Set up web server routes
server.on("/", handleRoot);
server.on("/relay", handleRelay);
// Start the server
server.begin();
Serial.println("Web server started!");
}
void loop() {
server.handleClient();
// Optional: Add watchdog or status LED blinking here
delay(2); // Small delay to prevent watchdog issues
}
Customizing the Code
You can easily customize this code:
- Change antenna names: Edit the
antennaNames[] array
- Modify Wi-Fi credentials: Change
ssid and password
- Adjust GPIO pins: If you have boot issues, try pins 16, 17, 18 instead of 23
- Add more relays: Expand the arrays and add more GPIO pins
Programming the ESP32
- Install Arduino IDE with ESP32 board support (instructions here)
- Select board: "ESP32 Dev Module" from Tools → Board
- Select port: Your ESP32's COM/USB port
- Upload: Click the upload button
- Monitor: Open Serial Monitor (115200 baud) to see the IP address
How It Works
Once powered, the ESP32 creates a Wi-Fi network named "AntennaSwitch". Here's how to use it:
- Connect your phone or computer to the "AntennaSwitch" Wi-Fi network
- Enter password:
hamradio
- Open browser: Navigate to
192.168.4.1
- Select antenna: Tap any button to switch antennas
The web interface shows which antenna is currently active (in red) and displays all available antennas. When you tap a button, the ESP32 deactivates all other relays and activates the selected one, ensuring only one antenna is connected at a time.
The active-LOW relay logic means the relays are normally off (HIGH signal) and energize when selected (LOW signal). This is the most common relay module configuration.
RF Switching Considerations
Power Handling
This design uses standard 10A electromechanical relays, which are suitable for up to 100 watts of RF power. The actual power handling depends on several factors:
- Duty cycle: CW and digital modes generate more heat than SSB
- SWR: High SWR increases voltage and current stress
- Contact quality: Clean, tight connections are essential
- Ventilation: Adequate airflow prevents overheating
For Higher Power (>100W)
If you operate at 500W or 1500W (legal limit), use this switch as a control relay system to drive:
- High-power coaxial relays (like Ameritron RCS-4 or Array Solutions)
- Vacuum relays rated for RF power
- External antenna switches with relay coil inputs
Simply wire the relay COM/NO contacts to energize the external relay coils instead of switching RF directly.
Grounding and Shielding
Proper RF grounding is critical:
- Metal enclosure: Houses all components and acts as shield
- Star grounding: Connect all coax shields to a single ground point on enclosure
- Short connections: Keep relay-to-connector leads under 2 inches
- Solid bonds: Use solder or crimp terminals, not wire nuts
Isolation Between Ports
To prevent RF feedback between unused antennas:
- Mount relays with adequate spacing (1-2 inches)
- Route each antenna port's coax away from others inside enclosure
- Consider adding ferrite beads on each antenna feedline
- Use proper coax (RG-8X minimum for 100W, RG-213 preferred)
Installation and Mounting
Weatherproofing
If mounting outdoors:
- Use a NEMA-rated weatherproof enclosure
- Install cable glands for all coax entries
- Apply silicone sealant around SO-239 mounting holes
- Add desiccant packs inside to prevent condensation
- Position enclosure connector-side down to prevent water intrusion
Indoor Installation
For shack installation:
- Mount at operating position height for easy manual override if needed
- Ensure adequate ventilation around enclosure
- Keep away from high-voltage equipment
- Label all antenna connections clearly
Strain Relief
Coax connectors bear significant mechanical stress:
- Use P-clips or cable ties to secure coax near connectors
- Don't let coax weight hang on SO-239 solder joints
- Allow service loop for future maintenance
Testing and Troubleshooting
Initial Testing (No RF)
Before connecting to your transceiver:
- Power up and verify Wi-Fi network appears
- Connect and access web interface at 192.168.4.1
- Test each relay by clicking buttons and listening for relay clicks
- Verify exclusivity: Only one relay should be active at a time
- Check with multimeter: Measure continuity from each antenna port COM to output when selected
RF Testing
Start with low power (5-10 watts):
- Connect a dummy load to one antenna port
- Select that port on web interface
- Key transmitter briefly and verify normal operation
- Check SWR—should match dummy load's rating
- Test each port individually
- Increase power gradually to your normal operating level
Common Issues
ESP32 won't boot or reboots randomly:
- Try different GPIO pins (avoid 0, 2, 12, 15 during boot)
- Add 10µF capacitor across ESP32 power pins
- Use external 5V supply for relay module
Relays clicking but no RF switching:
- Verify center conductors connected to COM terminals
- Check NO terminals all tied together to output
- Ensure shields properly grounded
High SWR when switching:
- Check all solder connections on SO-239 connectors
- Verify coax shields bonded to enclosure ground
- Inspect relay contacts for corrosion or damage
Web interface unreachable:
- Confirm connected to "AntennaSwitch" network
- Verify IP address in Serial Monitor (should be 192.168.4.1)
- Try different browser or clear cache
- Check ESP32 power supply is adequate
Future Upgrades
This basic design can be expanded with additional features:
Status Indicators
- Add LEDs to show active antenna (connect to same GPIO pins through current-limiting resistors)
- OLED display showing active antenna and SWR
- Buzzer confirmation when switching
Network Integration
- Connect to home Wi-Fi instead of AP mode for remote access
- MQTT integration for home automation control
- Web logging to track antenna usage patterns
- Password protection for the web interface
Expanded Capabilities
- 8-relay version for more antennas
- Dual-output switching for separate receive antennas
- Interlock with transceiver via CAT control
- Automatic antenna selection based on frequency
Advanced Features
- OTA (Over-The-Air) updates for code changes without USB cable
- SWR monitoring with directional coupler inputs
- Preset memories for different bands/modes
- Mobile app instead of web interface
- Voice control via home assistant integration
Safety Additions
- Transmit interlock during switching (requires interface to PTT line)
- Default antenna timeout if Wi-Fi lost
- Watchdog timer for automatic recovery from crashes
- Power monitoring to detect relay failures
Code Expansion Example: Station Integration
Here's how you might add MQTT support for home automation integration:
#include <PubSubClient.h>
WiFiClient espClient;
PubSubClient mqtt(espClient);
// In setup():
mqtt.setServer("192.168.1.100", 1883);
mqtt.setCallback(mqttCallback);
// Callback function:
void mqttCallback(char* topic, byte* payload, unsigned int length) {
String message = "";
for (int i = 0; i < length; i++) message += (char)payload[i];
if (String(topic) == "hamshack/antenna/set") {
int antenna = message.toInt();
if (antenna >= 0 && antenna < 4) {
// Switch to antenna
for (int i = 0; i < 4; i++) digitalWrite(relays[i], HIGH);
digitalWrite(relays[antenna], LOW);
}
}
}
This allows control via Node-RED, Home Assistant, or other automation platforms.
Conclusion
With just a few inexpensive components and a weekend of work, you can create a reliable Wi-Fi controlled antenna switch for your ham station. The ESP32's built-in Wi-Fi and web server capabilities make it easy to control relays directly from your smartphone or computer, and the modular design means you can expand or adapt it to suit your shack's needs.
Key takeaways:
- Simple, cost-effective design using readily available parts
- Suitable for up to 100 watts transmit power
- Expandable to control high-power external switches
- Web-based control works on any device with a browser
- Perfect weekend project combining modern IoT with classic ham radio
It's a practical solution that brings modern convenience to your station without complicated installation or expensive commercial switches. Whether you're running QRP portable or a fixed home station, having instant antenna switching at your fingertips improves operating efficiency and lets you quickly adapt to changing band conditions.
73 and happy building!