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 433 MHz radio with NodeMCU ESP8266 — range-test receiver

Wire an HC-12 to a NodeMCU on SoftwareSerial (D5/D6) with SET on D7, read its settings, and count lost packets from a numbered beacon to test range.

Arduino C++Verified — core esp8266 3.1.2, 3 Nov 2026Compile-only

Community draft — report a mistake

The HC-12 sends serial text over 433 MHz for hundreds of metres. Paired with a NodeMCU it makes a good receiver and Wi-Fi gateway for a gate sensor, a pump-house alarm or a field node that Wi-Fi can’t reach.

The radio uses SoftwareSerial on D5 (RX) and D6 (TX) with SET on D7, all pins with no boot role. At start-up the sketch reads the module’s settings, then listens for numbered UNO <n> packets from a second HC-12 and reports how many arrived and how many were lost — a simple range tester.

Wiring

NodeMCU ESP8266Only the pins used are shown · 3.3 V logicHC-12 433 MHz wireless serial moduleGNDVIND5D6D7VCCGNDRXDTXDSET
Also needed: 100–470 µF electrolytic capacitor, A second HC-12 sending “UNO <n>” lines (see the Uno HC-12 guide).
Every connection
NodeMCU ESP8266HC-12 433 MHz wireless serial moduleWireNotes
VINVCCred5 V from USB, so the ~100 mA transmit peaks don’t load the NodeMCU’s 3.3 V regulator. 100–470 µF across VCC/GND at the module.
GNDGNDblack
D5TXDgreenGPIO14, SoftwareSerial RX. HC-12 TXD is a 3.3 V output.
D6RXDyellowGPIO12, SoftwareSerial TX.
D7SETorangeGPIO13. LOW = AT mode, HIGH = radio mode.

3.2–5.5 V (100 mA peaks at full power) part, 3.3 V board. TXD is a 3.3 V output, which every board reads as HIGH. RXD is designed to accept 3.3 V or 5 V UART levels, so ESP32, Pico and Uno connect directly. Power it from 3.3 V or 5 V.

Board quirks

  • The ESP8266’s only full UART is wired to USB, so the radio uses SoftwareSerial on D5/D6. At the HC-12’s default 9600 baud that is reliable even with Wi-Fi on.
  • Keep the radio off D3, D4 and D8. They decide the boot mode, and the HC-12’s pulled-up SET or a TXD idling HIGH on D8 can stop the NodeMCU starting. D1/D2 stay free for an I2C display.
  • Both sides use 3.3 V logic, so the NodeMCU drives SET HIGH and LOW directly — no “only pull it low” trick needed.
  • The sketch expects lines like UNO 17. A gap in the numbers is a lost packet, so carrying the sender around the building or along a farm boundary shows where the link breaks. Anything else received is printed with a timestamp.
  • India’s 433 MHz licence-free band is narrow and meant for low power: stay on channels 001–004 and a low power setting (for example AT+P4) unless you have checked the current rules. Both radios must match on channel, baud and FU mode.
  • A NodeMCU receiver is a natural gateway: radio from the field, Wi-Fi to your phone or an MQTT broker.

Code

hc12-nodemcu.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// HC-12 433 MHz serial radio on a NodeMCU (ESP8266) — range-test receiver that counts lost packets.
// HC-12 TXD → D5 (GPIO14, soft RX), RXD ← D6 (GPIO12, soft TX), SET ← D7 (GPIO13),
// VCC → VIN (5 V) with a 100–470 µF capacitor at the module, GND → GND.
// Pairs with a sender that transmits "UNO <n>" lines (see the Uno HC-12 guide): gaps in n = lost packets.
#include <SoftwareSerial.h>

SoftwareSerial hc12(D5, D6);  // RX, TX
constexpr uint8_t SET_PIN = D7;
String line;
long lastSeq = -1;
uint32_t got = 0, lost = 0;

void setup() {
  Serial.begin(115200);
  Serial.println();
  hc12.begin(9600);  // HC-12 default: 9600 baud, FU3
  pinMode(SET_PIN, OUTPUT);
  digitalWrite(SET_PIN, LOW);  // AT mode for a moment
  delay(60);
  hc12.println("AT+RX");
  delay(250);
  while (hc12.available()) Serial.write(hc12.read());
  digitalWrite(SET_PIN, HIGH);  // radio mode (3.3 V HIGH is fine for the HC-12)
  delay(100);
  Serial.println("Listening for UNO <n> packets");
}

void loop() {
  while (hc12.available()) {
    char c = hc12.read();
    if (c == '\r') continue;
    if (c != '\n') {
      if (line.length() < 60) line += c;
      continue;
    }
    if (line.startsWith("UNO ")) {
      long seq = line.substring(4).toInt();
      if (lastSeq >= 0 && seq > lastSeq + 1) lost += seq - lastSeq - 1;
      lastSeq = seq;
      got++;
      Serial.printf("%lu s  #%ld  received %lu  lost %lu (%.0f%% ok)\n", millis() / 1000, seq, (unsigned long)got,
                    (unsigned long)lost, 100.0 * got / (got + lost));
    } else if (line.length()) {
      Serial.printf("%lu s  %s\n", millis() / 1000, line.c_str());
    }
    line = "";
  }
  while (Serial.available()) hc12.write(Serial.read());
}

Expected serial output

Serial Monitor · 115200Output
OK+B9600
OK+RC001
OK+RP:+20dBm
OK+FU3
Listening for UNO <n> packets
42 s  #8  received 1  lost 0 (100% ok)
47 s  #9  received 2  lost 0 (100% ok)
57 s  #11  received 3  lost 1 (75% ok)

Common errors

Nothing printed after “Listening”

TXD/RXD swapped (HC-12 TXD goes to D5), the sender on another channel or baud, or no common GND. Run AT+RX on both modules.

NodeMCU doesn’t boot with the HC-12 connected

A wire is on D3, D4 or D8. Use D5, D6 and D7 as shown.

Many lost packets even close by

Missing capacitor, antennas touching other wires, or two transmitters on the same channel. Add the capacitor and straighten the spring antennas.

↑↓ to move · Enter to open