Skip to content

Instantly share code, notes, and snippets.

@VladVanyuk
Last active July 4, 2025 01:40
Show Gist options
  • Select an option

  • Save VladVanyuk/32b2113512fa298d84cb2faa926c82a1 to your computer and use it in GitHub Desktop.

Select an option

Save VladVanyuk/32b2113512fa298d84cb2faa926c82a1 to your computer and use it in GitHub Desktop.
Put the HC12 is config mode, send a given command and display the result
#include "Arduino.h"
#include "SoftwareSerial.h"
#define INIT_BPS (9600)
#define WORK_BPS (38400)
#ifdef ARDUINO_AVR_UNO
#define HC12RX (7)
#define HC12TX (6)
#define HC12SET (5)
#else
#define HC12RX (D7)
#define HC12TX (D8)
#define HC12SET (D5)
#endif
#define LED_RED (LED_BUILTIN)
SoftwareSerial HC12(HC12TX, HC12RX);
void HC12_flush(bool binary=false) {
while (HC12.available()) {
Serial.print("Flushing ");
Serial.println((char)HC12.read(), (binary ? BIN : HEX));
}
}
// Put the HC12 is config mode:
void HC12_SET() {
pinMode(HC12SET, OUTPUT);
digitalWrite(HC12SET, 0);
}
// Exit from config mode:
void HC12_UNSET() {
pinMode(HC12SET, INPUT_PULLUP);
}
// Send a given command and display the result
void ATcmd(const char* 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 low
while (HC12.available()) {
Serial.write(HC12.read());
}
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
Serial.begin(INIT_BPS);
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);
// 9 is tab
uint8_t a=HC12.available();
if ((a>0) && (a != 4))
{
if(a != 2)
{
char c = (char)HC12.read();
if((c != 'O') || (c != 'K') || (c != 13) || (c != 10))
{
Serial.print(a);
Serial.println(" char received.\nHC12 KO ?\n");
Serial.print(c, BIN);
HC12_flush();
}else{
return;
}
}else{ // == 2
Serial.end();
Serial.begin(WORK_BPS);
HC12.end();
HC12.begin(WORK_BPS);
}
}else if(a == 0){
Serial.end();
Serial.begin(WORK_BPS);
HC12.end();
HC12.begin(WORK_BPS);
}
// ATcmd("AT+DEFAULT"); // Restore default settings
// ATcmd("AT"); // ok / not ok
ATcmd("AT+V"); // display firmware version
ATcmd("AT+B38400"); // change serial speed
ATcmd("AT+FU3"); //set our main operation mode
ATcmd("AT+P8"); //set power to maximum
ATcmd("AT+C001"); // set to channel 001
ATcmd("AT+RX"); // Display all the configuration parameters
HC12_UNSET();
Serial.println("\nHC12 ok\n");
digitalWrite(LED_BUILTIN, LOW);
delay(4000);
}
void loop()
{
if(Serial.available())
{
while(1)
{
digitalWrite(LED_BUILTIN, HIGH);
}
}
if(HC12.available())
{
digitalWrite(LED_BUILTIN, HIGH);
String msg = "";
while (HC12.available()) {
msg += (char)HC12.read();
// Serial.write(msg);
}
Serial.println(msg);
digitalWrite(LED_BUILTIN, LOW);
}
}
#include "Arduino.h"
#include "SoftwareSerial.h"
#define INIT_BPS (9600)
#define WORK_BPS (38400)
#if defined(ARDUINO_AVR_UNO)
#define HC12RX (7)
#define HC12TX (6)
#define HC12SET (5)
#elif defined(ESP8266)
#define HC12RX (3) // D9 // RX //armFirePin
#define HC12TX (1) // TX
#define HC12SET (14) // D5 // deto
#endif
#define LED_RED (LED_BUILTIN) //d4 or 13
SoftwareSerial HC12(HC12TX, HC12RX);
void HC12_flush(bool binary=false) {
while (HC12.available()) {
Serial.print("Flushing ");
Serial.println((char)HC12.read(), (binary ? BIN : HEX));
}
}
// Put the HC12 is config mode:
void HC12_SET() {
pinMode(HC12SET, OUTPUT);
digitalWrite(HC12SET, 0);
}
// Exit from config mode:
void HC12_UNSET() {
pinMode(HC12SET, INPUT_PULLUP);
}
// Send a given command and display the result
void ATcmd(const char* 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 low
while (HC12.available()) {
Serial.write(HC12.read());
}
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
#ifdef ESP8266
Serial.swap();
#endif
Serial.begin(INIT_BPS);
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);
// 9 is tab
uint8_t a=HC12.available();
if ((a>0) && (a != 4))
{
if(a != 2)
{
char c = (char)HC12.read();
if((c != 'O') || (c != 'K') || (c != 13) || (c != 10))
{
Serial.print(a);
Serial.println(" char received.\nHC12 KO ?\n");
Serial.print(c, BIN);
HC12_flush();
}else{
return;
}
}else{ // == 2
Serial.end();
Serial.begin(WORK_BPS);
HC12.end();
HC12.begin(WORK_BPS);
// ifdef esp HC12.updateBaudRate(WORK_BPS);
}
}else if(a == 0){
Serial.end();
Serial.begin(WORK_BPS);
HC12.end();
HC12.begin(WORK_BPS);
}
// ATcmd("AT+DEFAULT"); // Restore default settings
// ATcmd("AT"); // ok / not ok
ATcmd("AT+V"); // display firmware version
ATcmd("AT+B38400"); // change serial speed
ATcmd("AT+FU3"); //set our main operation mode
ATcmd("AT+P8"); //set power to maximum
ATcmd("AT+C001"); // set to channel 001
ATcmd("AT+RX"); // Display all the configuration parameters
HC12_UNSET();
Serial.println("\nHC12 ok\n");
// todo file.open();
digitalWrite(LED_BUILTIN, LOW);
}
struct TelemetryData
{
int state;
int32_t accelerometr;
int free_fall;
int reserved1;
int16_t acc_x;
int16_t acc_y;
int16_t acc_z;
uint8_t pin_state;
uint16_t batary;
uint32_t battlefield_distance;
uint32_t ToF_signal;
uint32_t sys_time;
};
// Test data format (copy and paste into Serial monitor):
// 1 12345 0 0 -150 200 1000 255 3700 1500 850 987654321
// HC12Config data = {0, 0, 0, 0, 0};
void loop()
{
if(Serial.available())
{
while(1)
{
digitalWrite(LED_BUILTIN, HIGH);
}
}
if(HC12.available())
{
digitalWrite(LED_BUILTIN, HIGH);
String msg = "";
TelemetryData data = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint32_t startTime = millis();
const uint32_t timeout = 80; // milliseconds
while (true)
{
if (HC12.available())
{
// msg += (char)HC12.read();
msg += HC12.readStringUntil('\n');
startTime = millis(); // reset timeout after receiving a char
}
else if (millis() - startTime > timeout)
{
break; // exit if timeout reached
}
}
// Parse the received text message
msg.trim(); // Remove whitespace and newlines
Serial.print("Received: ");
Serial.println(msg);
//TODO
//
// file.println(msg);
// file.close();
// Parse tab-separated values
long values[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int valueIndex = 0;
String currentValue = "";
for (int i = 0; i < msg.length() && valueIndex < 12; i++) {
char c = msg.charAt(i);
if (c == '\t' || c == '\n' || c == '\r') {
if (currentValue.length() > 0) {
values[valueIndex] = currentValue.toInt();
valueIndex++;
currentValue = "";
}
} else {
currentValue += c;
}
}
// Handle the last value if there's no trailing delimiter
if (currentValue.length() > 0 && valueIndex < 12) {
values[valueIndex] = currentValue.toInt();
}
// Assign parsed values to struct
data.state = values[0];
data.accelerometr = values[1];
data.free_fall = values[2];
data.reserved1 = values[3];
data.acc_x = values[4];
data.acc_y = values[5];
data.acc_z = values[6];
data.pin_state = values[7];
data.batary = values[8];
data.battlefield_distance = values[9];
data.ToF_signal = values[10];
data.sys_time = values[11];
Serial.print("State: ");
Serial.println(data.state);
Serial.print("Accelerometr: ");
Serial.println(data.accelerometr);
Serial.print("Free Fall: ");
Serial.println(data.free_fall);
Serial.print("X: ");
Serial.println(data.acc_x);
Serial.print("Y: ");
Serial.println(data.acc_y);
Serial.print("Z: ");
Serial.println(data.acc_z);
Serial.print("Pin State: ");
Serial.println(data.pin_state);
Serial.print("Battery: ");
Serial.println(data.batary);
Serial.print("Distance: ");
Serial.println(data.battlefield_distance);
Serial.print("ToF Signal: ");
Serial.println(data.ToF_signal);
Serial.print("System Time: ");
Serial.println(data.sys_time);
digitalWrite(LED_BUILTIN, LOW);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment