Error coding HC-12

#define RXD2 44 //(RX2)
#define TXD2 43 //(TX2)
#define HC12 Serial2  //Hardware serial 2 on the ESP32

int counter = 0;
bool cont = true;

void setup() 
{
  Serial.begin(115200);           // Serial port to computer
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);           //Normally HIGH, LOW for settings
  delay(1000);
  HC12.begin(9600, SERIAL_8N1, RXD2, TXD2);      // Serial port to HC12
 
}

void loop() 
{ 
  while (HC12.available()) 
  {        
    // If HC-12 has data]
    Serial.println("1");
    Serial.println(HC12.read());      // Send the data to Serial monitor
  }
  while (Serial.available()) 
  {      
    // If we have data from Serial monitor
    Serial.println("2");
    HC12.write(Serial.read());      // Send that data to HC-12
  }
  counter++;
}

I am trying to program a custom ESP32-S3-WROOM-1 chip connected to an HC-12 transmitter. I found the code above online on this link ESP32 I2C Communication: Set Pins, Multiple Bus Interfaces and Peripherals | Random Nerd Tutorials and modified it slightly to see if my HC-12 works. According to the website, when I run this code and enter “AT” in my serial monitor, the monitor should print “OK”. However, I don’t get any such response. The modifications I introduced in the code are the print lines in the different while loops, to basically see whether the Serial and HC12 are active. When I upload the code, I get the following output:

1
224

The “1” comes from my print statement, which means the HC-12 is receiving data, while the 224 comes from the HC-12. Not sure what that means. (EDIT 1: I decided to completely disconnect the HC-12, and re-run, and the 224 is still printed. No idea why)

However, after that, whenever I enter any data on the serial monitor, I get back a bunch of "2"s, which means my Serial is sending data, but I don’t see any other "1"s, which means the HC-12 isn’t receiving any data. I have no idea what I am doing wrong, could anybody help?

1 Like

Please check your connections along with the continuities of your jumper wires.

I have checked the continuity with a multimeter, and double and triple checked the connections

Hi @Ishan286537

My first instinct is to get more clarity over the serial feedback.
Let’s modify the print statements with more detail and re-run the test.

void loop() {

  while (HC12.available())
  {
    Serial.println("Received Data from HC12");
    Serial.print("r = ");
    Serial.println(HC12.read());
  }
  while (Serial.available())
  {
    Serial.println(“Reading user serial input”);
    String userInput = Serial.readString();
    // what are we about to send?
    Serial.print("sending w =");
    Serial.println(userInput);
    // punch it!
    for(char dataByte : userInput)
    {
      HC12.write(dataByte); 
    }
  }
  counter++;
}

It’s verbose, but it might provide more information. :slight_smile:

What is the communication protocol for the HC-12, specifically in respect of line termination. I suspect it won’t do anything until the line is terminated, and it may be fussy about how you are terminating the line. If you can show an example of what you are sending and the number of 2s you get back, that may indicate what line termination is being used (LF, CR, both, or neither) and may give a clue to the lack of response. Depending on the IDE you are using you may have an option to adjust the line terminator.

However, as the first step in confirming that you have a usable connection, it might be worthwhile hard coding the exact string you want to send and avoiding any oddity that can be introduced as a result of using console input as you string source.

1 Like

Assuming this is the unit you are using

from a scan of the pdf, by default the unit is is “passthrough” mode where anything sent into its serial port is sent over the radio, it would only send data back out its serial port if data is received from its radio.

If you want to enter serial config mode, it seems you need to put it into AT mode first.

OP is using the first way:

pinMode(5, OUTPUT);
digitalWrite(5, LOW); //Normally HIGH, LOW for settings

I can’t see that there is any indication of the current mode to confirm that it has been selected correctly, other than looking for the ‘OK’.

3 Likes

Fair call.

I still have questions…
“…first put Pin 5 “Set” in low level, and then energize it;…”
This is not 100% clear, but to me “energize it” would imply give power to the unit. If that is the case, then pin would need to be held low at power on.

My 2nd question/comment would be pin 5 in the code would refer to pin 5 on the controller, so I will assume they have that going to pin 5 of the device.

Any chance we can get a voltage reading on pin 5 of the device to ensure its pulled down. (The PDF states it has an internal 10K pull up, so its self held high)

Well worth checking on both points. I have never tried to configure the setting mode from software. Considering that adjusting the settings could be needed at any time after the code is finalised, it always seemed easier to solder a tiny tactile momentary button on the side of the device between pin 5 and a convenient ground, and avoid the extra wiring to the MCU.

1 Like

This is the output, instead of 240 I get 192 now but that’s most likely because I’m using a different HC-12 from yesterday.

Sorry, I am not really sure what communication protocol you are referring to. I think it uses UART, apologies if that’s not what you are asking for.

For the second part, I modified the code that @Pixmusix wrote to send a string “AT\n” instead of the userinput:

#define RXD2 44	//(RX2)
#define TXD2 43	//(TX2)
#define HC12 Serial2  //Hardware serial 2 on the ESP32

void setup() 
{
  Serial.begin(115200);           // Serial port to computer
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);           //Normally HIGH, LOW for settings
  delay(1000);
  HC12.begin(9600, SERIAL_8N1, RXD2, TXD2);      // Serial port to HC12
 
}

void loop() {

  while (HC12.available())
  {
    Serial.println("Received Data from HC12");
    Serial.print("r = ");
    Serial.println(HC12.read());
  }
  delay(5000);
  Serial.println("Reading user serial input");
  String userInput = "AT\n";
  // what are we about to send?
  Serial.print("sending w = ");
  Serial.println(userInput);
  // punch it!
  for(char dataByte : userInput)
  {
    HC12.write(dataByte); 
  }
  
}

However, I still get no response back:

1 Like

(Disconnected the SET pin for this image to read the voltage)

(Red connected to Pin 5, Black connected to ground)

(Pin placement on my board)

Hi Ishan
I believe this “HC-12” device is a radio TX/RX. As such it will only send what is given to it. You have got another unit to RX this with a suitable device connected to reply haven’t you??

I think the TX sends what it is asked to then the receiver passes this on to a device at that end. If a reply is expected the same thing should happen in reverse. I don’t think the actual HC-12 actually does the replying. It is whatever you have connected at the other end.

I could be wrong here but I read this as being just a Radio Link and I have never had anything to do with these particular devices. But Radio Links I have been involved with are usually pretty dumb. They just take what is given them and send it on and vice versa.
The only way I could see the HC-12 communicating directly back to a PC is if it were in some set up mode where confirmation of settings are required.
Cheers Bob

1 Like

Im not 100% on what you have tested.

Please correct me as needed.

Pin 5 on the micro controller is what you selected in your code to contol the HT-12 AT mode. I assume this is GPIO5.

That Pin 5 on the micro controller is connected directly to pin 5 on the HC-12 device (as its Pin 5 on the HC-12 that needs to be low to enter AT mode).

The HC-12 (based on the pdf I read) said it has in internal pull up (10K ohm), and to get to AT command mode (where that device WILL response to AT (or should), you need to pull pin 5 of the HC-12 low “then energize”

I did not really like the way its worded… As it implies to me that pin 5 should be pulled down “prior” to the unit getting power.

In theory, you should be able to wire pin5 of the HC-12 to ground, then power everything up (level pin 5 on the micro controller not connected)

That “should” hard wire it to be in AT mode at power on.

Of course I think two key things needs to noted.

  1. Confirm that the pdf link I posted was correct for YOUR HC-12. i.e. make sure it all match’s - My advice is based on that, so if thats wrong, it may invalidate some details.

  2. Keep in mind that when in AT mode you wont be able to use the radio side, but we are trying to test coms in AT mode.

With reference to my other post, I wanted to see what the voltage was on pin 5 of the HC-12 after the code on the micro was running and should have asserted the micro controller pin5 to low. i.e. I wanted to confirm in fact that it did pull down the HC-12 pin 5.

1 Like

Hi Michael,

The datasheet for the HC-12 is definitely not written as well as it could be, my reading of it would indicate that while the SET pin (pin 5) is pulled low the unit is in a configuration mode that allows you to alter the channel, baud rate, transmission mode and transmission power level. It will stay in this mode until the pin is then pulled high again where it would return to its transmission mode.

@Ishan286537 do you have any other microcontrollers on hand that you could use to rule out the board that you’re using having some contributing factor to the device not working?

UART is the physical interface - the wiring and voltages and suchlike. The protocol is things like baud rate, data bits, stop bits, ASCII encoding and line termination.

You wouldn’t use ‘AT\n’ with println() because println() adds its own line terminator.

To control the line termination precisely, either:

  1. Add \n, \r or both to the test string, and use print(), or
  2. Add nothing to the text string, use println(), and choose CR, LF or CR/LF in the line termination options (if your IDE supports that option).

(I am assuming that no line termination will not work).

Hi Robert, I am currently not using another HC-12 for communication. As you mentioned in your last line, I have grounded the Set pin of the HC-12, which should mean that the HC-12 is in a set-up mode and can communicate back to the computer that it is working

Apologies, I’m a bit new to this so I wasn’t very sure. I connected the “SET” Pin on my HC-12 to pin 5 on my esp32 which was then set to LOW. I decided to scrap that for now and just connect it directly to the ground, although I don’t think (?) there’s a difference.

The voltage on the set pin when connected to Ground:


The manual of the HC-12 you sent is indeed the one for my HC-12.

I just tested my HC-12 with an Arduino Uno, where I used Software Serial, and I seem to get the right results there

I don’t think esp32 has a software serial? Or else I would try that.

The ESP32 will support software serial, but it shouldn’t be needed as it has multiple hardware serial devices. They will be referred to as Serial1, Serial2 etc. As you have done

#define HC12 Serial2 //Hardware serial 2 on the ESP32
and
HC12.begin(9600, SERIAL_8N1, RXD2, TXD2); // Serial port to HC12
then that is equivalent to
Serial2.begin(9600);
and simply referring to the port as ‘Serial2’ rather than ‘HC12’, except that you have defined your own pin usage for Serial2.
Can you confirm from the documentation for your ESP device that the second serial port can be assigned to 44,43? Or are you using 44,43 because they are the pins on the dev module? If so, then that is incorrect and you should be using the GPIO port that those pins connect to (which could be the default 16,17). A link to the reference page for the dev board you are using would help to sort that out.

Or perhaps you can simply use Serial2 with the default pins, which are GPIO16 (Rx) and GPIO17 (Tx) (but you still need to confirm that you are connecting to those ESP32 pins, not the dev board pin numbers).

1 Like