The HC-12 is a serial cable without wires: what goes into one module’s RXD comes out of the other module’s TXD, up to several hundred metres away. It is used for gate alarms, remote pump switches and field sensors.
On the Mega it gets Serial3 (pins 14/15) and one extra pin, SET on D22, so the sketch can check the module’s settings at start-up before switching to radio mode. Then anything typed in the Serial Monitor is sent over the air.
Wiring
| Arduino Mega 2560 | HC-12 433 MHz wireless serial module | Wire | Notes |
|---|---|---|---|
| 5V | VCC | red | 100–470 µF capacitor across VCC/GND at the module for transmit peaks. |
| GND | GND | black | |
| D15 | TXD | green | HC-12 TX → RX3. |
| D14 | RXD | yellow | TX3 → HC-12 RX (accepts 5 V UART levels). |
| D22 | SET | orange | Driven LOW for AT mode, otherwise released (input) — never driven HIGH. |
3.2–5.5 V (100 mA peaks at full power) part, 5 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
- Serial3 is TX3 = pin 14, RX3 = pin 15 on the communication header. The HC-12 needs no level shifting on RXD.
- The sketch drives SET only LOW (AT mode) and otherwise switches the pin to INPUT, so the module’s own pull-up sets normal mode. That avoids pushing 5 V into a 3.3 V pin.
AT+RXprints baud, channel, transmit mode and power. Both HC-12s must match on all of them.- India’s 433 MHz licence-free band is narrow and low-power: stay on channels 001–004 and a low power setting (for example
AT+P4) unless you have checked the current rules. - Range is hundreds of metres at low power in the open, much less through concrete walls.
Code
// HC-12 433 MHz serial radio on an Arduino Mega 2560's hardware Serial3.
// HC-12 TXD → D15 (RX3), RXD ← D14 (TX3), SET ← D22 (pulled LOW only for AT mode), VCC → 5V, GND → GND.
// At start-up it reads the module's settings in AT mode, then bridges Serial ↔ radio.
const uint8_t SET_PIN = 22;
void hc12Command(const __FlashStringHelper *cmd) {
Serial3.println(cmd);
delay(200);
while (Serial3.available()) Serial.write(Serial3.read());
}
void setup() {
Serial.begin(115200);
Serial3.begin(9600); // HC-12 default (FU3, 9600 baud)
// SET is pulled up inside the HC-12 (3.3 V logic): never drive it HIGH from the 5 V Mega.
// Pull it LOW for AT mode, and release it (INPUT) for normal radio mode.
digitalWrite(SET_PIN, LOW);
pinMode(SET_PIN, OUTPUT); // LOW = AT command mode
delay(100);
Serial.println(F("HC-12 settings:"));
hc12Command(F("AT"));
hc12Command(F("AT+RX")); // baud, channel, mode and power in one go
pinMode(SET_PIN, INPUT); // released: back to transparent radio mode
delay(100);
Serial.println(F("Radio mode - type a line to send it"));
}
void loop() {
while (Serial.available()) Serial3.write(Serial.read());
while (Serial3.available()) Serial.write(Serial3.read());
}// HC-12 433 MHz serial radio on an Arduino Mega 2560's hardware Serial3.
// HC-12 TXD → D15 (RX3), RXD ← D14 (TX3), SET ← D22 (pulled LOW only for AT mode), VCC → 5V, GND → GND.
// At start-up it reads the module's settings in AT mode, then bridges Serial ↔ radio.
const uint8_t SET_PIN = 22;
void hc12Command(const __FlashStringHelper *cmd) {
Serial3.println(cmd);
delay(200);
while (Serial3.available()) Serial.write(Serial3.read());
}
void setup() {
Serial.begin(115200);
Serial3.begin(9600); // HC-12 default (FU3, 9600 baud)
// SET is pulled up inside the HC-12 (3.3 V logic): never drive it HIGH from the 5 V Mega.
// Pull it LOW for AT mode, and release it (INPUT) for normal radio mode.
digitalWrite(SET_PIN, LOW);
pinMode(SET_PIN, OUTPUT); // LOW = AT command mode
delay(100);
Serial.println(F("HC-12 settings:"));
hc12Command(F("AT"));
hc12Command(F("AT+RX")); // baud, channel, mode and power in one go
pinMode(SET_PIN, INPUT); // released: back to transparent radio mode
delay(100);
Serial.println(F("Radio mode - type a line to send it"));
}
void loop() {
while (Serial.available()) Serial3.write(Serial.read());
while (Serial3.available()) Serial.write(Serial3.read());
}Expected serial output
HC-12 settings:
OK
OK+B9600
OK+RC001
OK+RP:+20dBm
OK+FU3
Radio mode - type a line to send itHC-12 settings: OK OK+B9600 OK+RC001 OK+RP:+20dBm OK+FU3 Radio mode - type a line to send it
Common errors
No reply in AT mode
SET not pulled low, or the module was not given ~40 ms after SET changed. Check the D22 wire.
Radios don’t hear each other
Different channel, baud or FU mode. Read both with AT+RX and match them.