Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
HC-12 USB Radio Modem: the finished build
S2 MiniNetwork & ISP tools

HC-12 USB radio modem — a wireless Serial Monitor for your projects (LOLIN S2 Mini)

Your Serial Monitor, without the cable — for robots, rooftop sensors and the far end of the farm.

Difficulty
Easy
Build time
1 h
Parts cost
₹1,185 · $14
Verified — core esp32 3.3.12, 3 Nov 2026Compile-only

Community draft — report a mistake

Parts list

PartQtyApprox.Buy
LOLIN S2 Mini1₹350Buy LOLIN S2 Mini
HC-12 433 MHz transceiver with spring antenna1₹350Buy HC-12 433 MHz transceiver with spring antenna
12 mm push button1₹10Buy 12 mm push button
100 µF 16 V capacitor1₹5Buy 100 µF 16 V capacitor
USB-C data cable1₹120Buy USB-C data cable
Second HC-12 for the project you want to watch1₹350Buy Second HC-12 for the project you want to watch
Total₹1,185

Affiliate disclosure: “Buy” links may earn FlashReady a small commission at no extra cost to you. Prices are indicative.

Wiring

LOLIN S2 MiniOnly the pins used are shown · 3.3 V logicHC-12 433 MHz wireless serial modulePush button (6 mm tactile switch)3V339 · 3940 · 4037 · 3734 · 34GNDVCCGNDRXDTXDSET12
Every connection
LOLIN S2 MiniPart · pinWireNotes
37HC-12 433 MHz wireless serial module · TXDgreenGPIO37 → Serial1 RX (the variant’s “RX” pin, D1 mini RX position)
39HC-12 433 MHz wireless serial module · RXDblueGPIO39 → Serial1 TX (the variant’s “TX” pin)
40HC-12 433 MHz wireless serial module · SETpurpleGPIO40 — LOW = AT-command mode
3V3HC-12 433 MHz wireless serial module · VCCred100 µF capacitor across VCC/GND at the module; the S2 Mini’s regulator gives 500 mA
GNDHC-12 433 MHz wireless serial module · GNDblack
34Push button (6 mm tactile switch) · 1yellowGPIO34 — toggles AT mode
GNDPush button (6 mm tactile switch) · 2black

Board quirks: The far end is any project with an HC-12 on a UART at the same baud rate (9600 by default): wire its TXD/RXD to that board’s spare serial pins and print to it instead of (or as well as) Serial. The S2 Mini’s USB-C goes straight into the ESP32-S2’s USB-OTG controller, so the laptop sees a USB serial port without any CH340/CP2102 chip — and the terminal’s baud setting doesn’t matter. The radio side is fixed at <code>RADIO_BAUD</code>. Both HC-12s must be on the same channel and air rate. The default is channel 1 (433.4 MHz), FU3, 9600 baud. In AT mode, <code>AT+RX</code> prints all settings. 433 MHz is licence-free in India only at low power. Keep <code>AT+P4</code> (+8 dBm) or lower unless you have checked the current WPC rules — range is still 100–300 m with the spring antennas, more with a proper 17 cm wire antenna in the open. HC-12 links are half-duplex and a little slow (FU3 at 9600 baud ≈ 1 kB/s): fine for text logs, not for firmware uploads.

Code

hc12-usb-radio-modem.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// HC-12 USB radio modem — LOLIN S2 Mini + HC-12 433 MHz transceiver.
// Plug the S2 Mini into a laptop and it becomes a wireless serial port: whatever you type in
// the Serial Monitor goes out over the HC-12, and whatever the far HC-12 sends appears on the
// laptop. Use it to watch a robot's or a field sensor's Serial output from 100+ m away.
// Press the button to toggle AT-command mode (SET LOW, LED on) and talk to the HC-12 itself:
// AT+RX shows its settings, AT+C001 sets the channel, AT+P4 sets the power.
// The ESP32-S2's own USB is the serial port, so no USB-serial chip and no baud rate to match
// on the laptop side. HC-12: TXD -> GPIO37, RXD <- GPIO39, SET <- GPIO40, VCC 3V3.
// Button: GPIO34 to GND. Blue LED (GPIO15): on in AT mode, flickers with radio traffic.
constexpr int HC_RX = 37, HC_TX = 39, HC_SET = 40, BTN = 34;
constexpr uint32_t RADIO_BAUD = 9600;  // the HC-12's default (FU3); must match the far end

bool atMode = false;
uint32_t ledOffAt = 0, toRadio = 0, fromRadio = 0;

void setAt(bool on) {
  atMode = on;
  digitalWrite(HC_SET, on ? LOW : HIGH);
  delay(on ? 60 : 100);  // the HC-12 needs a moment to switch modes
  if (on) Serial1.updateBaudRate(9600);  // AT mode always talks at 9600
  else Serial1.updateBaudRate(RADIO_BAUD);
  digitalWrite(LED_BUILTIN, on ? HIGH : LOW);
  Serial.println(on ? "\n[AT mode - type AT commands, e.g. AT+RX]" : "\n[radio mode]");
}

void flicker() {
  if (atMode) return;
  digitalWrite(LED_BUILTIN, HIGH);
  ledOffAt = millis() + 20;
}

void setup() {
  Serial.begin(115200);  // USB CDC: the number is ignored, any terminal setting works
  pinMode(HC_SET, OUTPUT);
  digitalWrite(HC_SET, HIGH);
  pinMode(BTN, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial1.begin(RADIO_BAUD, SERIAL_8N1, HC_RX, HC_TX);
  delay(1500);  // give the laptop time to open the port
  Serial.println("HC-12 USB radio modem ready - type to send, press the button for AT mode");
}

void loop() {
  while (Serial.available()) {
    char ch = Serial.read();
    Serial1.write(ch);
    toRadio++;
    flicker();
  }
  while (Serial1.available()) {
    Serial.write(Serial1.read());
    fromRadio++;
    flicker();
  }
  if (!atMode && ledOffAt && millis() > ledOffAt) {
    digitalWrite(LED_BUILTIN, LOW);
    ledOffAt = 0;
  }
  static bool last = HIGH;
  bool b = digitalRead(BTN);
  if (b == LOW && last == HIGH) {
    delay(30);
    setAt(!atMode);
    Serial.printf("[%lu bytes sent, %lu received so far]\n", toRadio, fromRadio);
  }
  last = b;
}

Compiled for s2mini on esp32 3.3.12 · 3 Nov 2026

How it works

Testing a line-follower on the floor, a robot in the playground, or a sensor on the water tank on the roof usually means running after it with a laptop and a long USB cable. This little dongle replaces the cable with a 433 MHz radio link. Plug it into the laptop, open any serial terminal (the Arduino Serial Monitor is fine), and the far project’s Serial output scrolls past as if it were plugged in.

The HC-12 is a cheap transceiver module built around a Silicon Labs Si4463: give it bytes on its UART and it sends them over the air; whatever it receives comes out of its TXD pin. Two HC-12s on the same channel make a transparent serial link. Here the S2 Mini simply copies bytes both ways: laptop → HC-12, and HC-12 → laptop. Its blue LED flickers with traffic.

The LOLIN S2 Mini is the right board because its ESP32-S2 has native USB: the laptop sees a USB serial port directly, with no separate USB-serial chip, and it costs about the same as a cable adapter. The HC-12 sits on Serial1, routed to the S2 Mini’s RX/TX header positions (GPIO37/39).

Press the button and the S2 pulls the HC-12’s SET pin LOW: now the laptop talks to the radio itself, so you can check and change the channel, power and air rate with AT commands (AT+RX, AT+C002, AT+P4). Press again to go back to radio mode.

Troubleshooting

Nothing comes through from the far end

Press the button and type AT+RX on both ends: channel, FU mode and baud must match. Check TXD → GPIO37 and RXD → GPIO39 (crossed, like any UART).

AT commands get no reply

The LED must be on (SET LOW). Type exactly AT and press Enter with “Newline” or “No line ending” selected; the HC-12 answers OK.

Garbled characters

The far project’s Serial1 baud rate isn’t the same as the HC-12’s (9600 by default), or the two radios use different air rates (FU modes).

Upgrades

  • Add a small OLED showing bytes per second and the time since the last message.
  • Timestamp every received line before printing it, for logging rooftop sensors.
  • Use two of these between two laptops as a simple offline chat.

↑↓ to move · Enter to open