Proof of Concept: sudo Walkie-Talkie
Web-controlled radio via ESP8266 – Because sometimes you need to transmit from the couch
Sudo Grizzly Gents • April 2026
We’ve all been there: you’re deep in a project, the walkie-talkie is across the bench, and you don’t want to get up and mash the PTT button like a caveman. Solution? Stuff an ESP8266 inside it and give every control its own web button.
This is a full end-to-end Proof of Concept that turns any cheap push-to-talk radio into an IoT device you can command from a phone, laptop, or even a script. No custom PCB, no voice streaming (yet), just pure button-toggling over Wi-Fi.
Why this exists
- Remote activation for monitoring stations, props, escape rooms, or field ops
- Zero-latency web dashboard instead of carrying the radio everywhere
- Future-proof: same hardware can later drive relays, sensors, or even a software-defined radio HAT
Parts list (total cost < $15 if you already own a radio)
- Any FRS/GMRS walkie-talkie with tactile or membrane buttons (we used a $8 pair of Retevis RT22 clones – perfect because the PCB is huge and the buttons are easy to tap)
- ESP8266 NodeMCU (or D1 Mini – both 3.3 V native)
- 4× 2N7000 or BS170 N-channel MOSFETs (or 2N2222 transistors) – one per control you want to toggle
- 100 nF ceramic caps for debounce on the GPIO side
- Thin wire, heat-shrink, solder
- Optional: 3.3 V LDO if your radio runs at 4.5 V+ (most cheap ones are 3×AAA = 4.5 V, so we added a tiny AMS1117)
Hardware mod – 30 minutes of surgery
- Pop the radio open (usually 4–6 screws + clips).
- Find the button pads on the PCB. Most cheap radios pull the button line to ground when pressed (active-low).
- PTT pad: big obvious pair of traces under the rubber button
- Channel ± pads: two smaller pads
- Power / volume up/down: whatever you care about
- Solder a wire from each pad to the drain of a 2N7000.
- Source → radio ground
- Gate → ESP8266 GPIO (we used D1, D2, D5, D6)
- 10 kΩ pull-down on gate so it doesn’t float
- Power the ESP from the radio’s battery pack (after the switch if possible) via the LDO. ESP draws \~80 mA in AP mode – the radio battery laughs at that.
- Hot-glue everything so it doesn’t rattle when you inevitably drop it in the woods.
That’s it. The radio still works exactly as before; the ESP just pretends to be your finger.
Software – ESP8266WebServer + simple HTML/JS dashboard
We flashed the ESP with the Arduino core because it’s the fastest way to get a web server running.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
const char* ssid = "sudo-Grizzly-Radio";
const char* password = "grizzly123"; // change this or switch to AP-only
ESP8266WebServer server(80);
#define PTT_PIN D1 // active-low
#define CH_UP_PIN D2
#define CH_DN_PIN D5
#define VOL_UP_PIN D6
void setup() {
pinMode(PTT_PIN, OUTPUT); digitalWrite(PTT_PIN, HIGH);
pinMode(CH_UP_PIN, OUTPUT); digitalWrite(CH_UP_PIN, HIGH);
// ... same for others
WiFi.softAP(ssid, password); // or WiFi.begin() if you want to join your home network
server.on("/", handleRoot);
server.on("/ptt", handlePTT);
server.on("/chup", [](){ pulsePin(CH_UP_PIN); server.send(200); });
server.on("/chdn", [](){ pulsePin(CH_DN_PIN); server.send(200); });
server.on("/volup", [](){ pulsePin(VOL_UP_PIN); server.send(200); });
server.begin();
}
void pulsePin(int pin) {
digitalWrite(pin, LOW);
delay(120); // realistic button press time
digitalWrite(pin, HIGH);
}
void handlePTT() {
String state = server.arg("state");
if (state == "on") digitalWrite(PTT_PIN, LOW);
else digitalWrite(PTT_PIN, HIGH);
server.send(200, "text/plain", "PTT " + state);
}
String HTML = R"rawliteral(
<!DOCTYPE html>
<html>
<head><title>sudoradio</title>
<style>body{font-family:monospace;background:#111;color:#0f0;padding:20px;}</style>
</head>
<body>
<h1>sudoradio v0.1 – Grizzly Gents</h1>
<button onclick="fetch('/ptt?state=on')">PTT ON</button>
<button onclick="fetch('/ptt?state=off')">PTT OFF</button>
<button onclick="fetch('/chup')">CH +</button>
<button onclick="fetch('/chdn')">CH –</button>
<button onclick="fetch('/volup')">VOL +</button>
<p>Connected to: <span id="ip"></span></p>
<script>document.getElementById('ip').innerText = location.hostname;</script>
</body>
</html>
)rawliteral";
void handleRoot() { server.send(200, "text/html", HTML); }
void loop() { server.handleClient(); }
Flash, power up, connect to the “sudo-Grizzly-Radio” access point, open 192.168.4.1 in any browser. Click the buttons. The radio obeys instantly.
Demo
Phone browser → PTT button lights up red on the dashboard and the radio starts transmitting a test tone.
Channel buttons cycle through all 22 FRS channels.
Works from anywhere on the local Wi-Fi (or the ESP’s own AP if you’re off-grid).
Known limitations / next steps for Grizzly Gents
- Current version is button simulation only – no audio streaming (that’s v2 with an I²S mic + WebSocket)
- Range is Wi-Fi limited (≈50 m indoors). Want LoRa? Swap to ESP32 + LoRa module.
- Power management: the ESP stays on even when radio is “off”. We’ll add a MOSFET on the battery line later.
- Security: right now it’s wide open. Add basic auth or mDNS + HTTPS in the next sprint.
Files & repo
Everything (schematics, Arduino sketch, HTML, Gerber if we ever make a tiny shield) is already up in the Grizzly vault:
git clone https://github.com/sudogrizzly/sudo-walkie
Now go forth and never hunt for the PTT button again.
— Sudo Grizzly Gents
Turning radios into robots since the last time someone said “it can’t be done”





Leave a comment