Every public project I have seen uses the HC12's default configuration: FU3 at 9600 bps.
When really long distance is needed, the FU4 mode must be set, which works at 1200bps (500bps over the air). The options are persistent so it makes sense to have a separate program to configure the options, rather than include it in all the peers of a network. And this saves a GPIO pin.
Since I had to reverse-engineer quite a lot to make sense of the HC12's datasheet, and I have not found an equivalent anywhere, I make this program public. Tell me if this is useful to you too !
The program is quite simple. This version only displays the current configuration. Many AT commands are available (look at the datasheet) and are commented out, enable them at your convenience.
/*
* HC12config.ino
* created 20211014 by Yann Guidon
*
* Configure a HC12 module for custom operation.
* Not interactive : define the parameters in the #defines.
*
* Connections:
*
* Arduino: HC12:
* D4 RXD
* D5 TXD
* D6 SET
*/#include"Arduino.h"#include"SoftwareSerial.h"#define INIT_BPS (9600)#define HC12RX (4)#define HC12TX (5)#define HC12SET (6)#define LED_RED (13)SoftwareSerial HC12(HC12TX, HC12RX);
// actual order from the Arduino point of view : RX, TXvoidHC12_flush(){
while (HC12.available()) {
Serial.print("Flushing ");
Serial.println(HC12.read());
}
}
// Put the HC12 is config mode:voidHC12_SET(){
pinMode(HC12SET, OUTPUT);
digitalWrite(HC12SET, 0);
}
// Exit from config mode:voidHC12_UNSET(){
pinMode(HC12SET, INPUT_PULLUP);
}
// Send a given command and display the resultvoidATcmd(constchar* cmd){
for (uint8_t i=0; cmd[i]; i++) {
HC12.write(cmd[i]);
Serial.write(cmd[i]);
}
HC12.write(13); // replace the trailing null byte// by the <CR> character.
Serial.print('\n');
delay(200); // Might need increase if speed is very lowwhile (HC12.available()) {
Serial.write(HC12.read());
}
}
voidsetup(){
pinMode(LED_RED, OUTPUT);
digitalWrite(LED_RED, 1);
Serial.begin(9600);
Serial.println("Probing HC12...");
HC12_UNSET();
HC12.begin(INIT_BPS);
delay(100);
HC12_SET();
delay(100);
HC12_flush();
// First check : send the AT command// and expect AT<CR><LF>
HC12.write('A');
HC12.write('T');
HC12.write(13); // optional ?
delay(200);
uint8_t a=HC12.available();
if ((a != 4)
|| (HC12.read() != 'O')
|| (HC12.read() != 'K')
|| (HC12.read() != 13)
|| (HC12.read() != 10)) {
Serial.print(a);
Serial.println(" char received.\nHC12 KO ?\n");
HC12_flush();
return;
}
// ATcmd("AT+DEFAULT"); // Restore default settings
ATcmd("AT+V"); // display firmware version// ATcmd("AT+C042"); // change to channel 42// ATcmd("AT+B1200"); // change serial speed// ATcmd("AT+FU4"); // sets the interface to 1200bps, and OTA to 500bps
ATcmd("AT+RX"); // Display all the configuration parameters
HC12_UNSET();
Serial.println("\nHC12 ok\n");
}
voidloop(){
// nothing to be done here.
digitalWrite(LED_RED, 0);
}
Operation is pretty simple :
Wire the boards as shown in the code.
Open the source code in the Aruino IDE
Plug the board on the USB port.
Open the serial monitor to display all the messages from the Arduino board.
Compile & upload the code
Examine the messages on the monitor : If "HC12 KO ?" appears, check your connections and the settings, in particular INIT_BPS. For example when INIT_BPS=9600 and the HC12 is at 1200bps, the flush will display a number of 128 and 0.
The ATcmd() calls are executed: So far only configuration parameters are read. You can uncomment the desired commands to suit your needs.
Goto 5 until you reach the configuration you desire.
When I set mode AT+FU4, I can't seem to get the AT+B2400 setting to work despite the datasheet saying it's possible, and AT+RX confirming the mode is accepted. When I restart the boad, I can only talk to it with INIT_BPS=1200.
I noticed something frustrating :
When I set mode AT+FU4, I can't seem to get the AT+B2400 setting to work despite the datasheet saying it's possible, and AT+RX confirming the mode is accepted. When I restart the boad, I can only talk to it with INIT_BPS=1200.