HC12 not working

So im am fairly new to arduino. I am trying to make a long range alarm system using 2 HC12 modules and 2 leonardos. The problem is that I cant get the HC12 modules to work in any way. I just bought them and they just dont do anything they are supposed to do, but idk if it is my fault or if they were both broken when they arrived.

I first tried a simple program to test the communication between them:

/*    Arduino Long Range Wireless Communication using HC-12
                      Example 01
   by Dejan Nedelkovski, www.HowToMechatronics.com
*/
#include <SoftwareSerial.h>
SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
void setup() {
  Serial.begin(9600);             // Serial port to computer
  HC12.begin(9600);               // Serial port to HC12
}
void loop() {
  while (HC12.available()) {        // If HC-12 has data
    Serial.write(HC12.read());      // Send the data to Serial monitor
  }
  while (Serial.available()) {      // If Serial monitor has data
    HC12.write(Serial.read());      // Send that data to HC-12
  }
}

This didnt work, so I then tried to test if they even worked at all with the AT commands, but this didn't give any response.

Is there any way to test them so I can know for sure if they are broken or if it is just the method and code I've been using?

If you know a code and maybe something I should do that should always work on a hc12 I can test, that would be wonderful.

May be they are not configured at 9600 bauds

Tell us as well how they are wired and if you got them at the same time from the same seller

So to test them I set it up very basic
VCC-5V
GND-GND
RXD-TXD
TXD-RXD
the code I use is copied from internet, a guide I've been following but its very basic so i don't think it should be that, its the code in my original post.

then I also changed the softwareserial bit to just serial1, since that is rxd and txd on leonardo (for the mega I did not do this obviously)

so then i try the AT commands, just test it with AT but no response.

to test the communication between them I used this code on both arduinos, using a different pc. Then I send a message in console hoping it would appear on the other ones console but nothing.

I bought them at the same time, they came in a different transparent blue packaging sac tho and bought it from a dutch/ belgian website called opencircuit.

I hope this helps

How did you put the module into AT mode?

which pins did you use on the arduino?

post the real code you've been using then... The MEGA has multiple Hardware Serial port, you could use Serial1 too and it would be more robust than Software Serial.

I tested 2 methods, one where I connected RXD on HC12 to TX(pin 1) on leonardo and TXD on HC12 to RX(pin0) on leonardo, then I used this code on both the arduinos with that setup.

/*    Arduino Long Range Wireless Communication using HC-12
                      Example 01
   by Dejan Nedelkovski, www.HowToMechatronics.com
*/


void setup() {
  Serial.begin(9600);             // Serial port to computer
  Serial1.begin(9600);               // Serial port to HC12

}

void loop() {
  while (Serial1.available()) {        // If HC-12 has data
    Serial.write(Serial1.read());      // Send the data to Serial monitor
  }
  while (Serial.available()) {      // If Serial monitor has data
    Serial1.write(Serial.read());      // Send that data to HC-12
  }
}

I also tested the other method, using softwareserial and not serial1, in this case TX from HC12 was connected to pin 10 and RX to pin 11. I used this code then

/*    Arduino Long Range Wireless Communication using HC-12
                      Example 01
   by Dejan Nedelkovski, www.HowToMechatronics.com
*/

#include <SoftwareSerial.h>

SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin

void setup() {
  Serial.begin(9600);             // Serial port to computer
  HC12.begin(9600);               // Serial port to HC12

}

void loop() {
  while (HC12.available()) {        // If HC-12 has data
    Serial.write(HC12.read());      // Send the data to Serial monitor
  }
  while (Serial.available()) {      // If Serial monitor has data
    HC12.write(Serial.read());      // Send that data to HC-12
  }
}

basically the same thing I think.

normally when I type something in teh console of one arduino it should pop up in the other arduinos console. It doesn't. I am using the same baud rate for everythign so that isn't the problem

Tbh I am kinda new to the AT commands so do you have to put it into AT mode?
and how would you do that? Now I have just been following the tutorial. I use the same code as above ^ on one arduino with the HC12 connected and just try AT commands.

This is what the 'howtomechatronics' tutorial says about it

We can use the same code for sending AT Commands and configuring the module parameters. All we have to do is connect the “Set” pin of the module to Ground or any digital pin of the Arduino and set the pin to low logic level.

I did connect the set pin to gnd for this, not for the test with the 2 arduino communication.

Now I am going to go over every part and check if thats the problem because tbh it might even be the soldering I did that is bad and is causing issues.

I tested 2 different methods
for one method I connected the TXD on HC12 to RX(pin 0) on leonardo and RXD on hC12 to TX(pin1) on leonardo. I used this code then.

/*    Arduino Long Range Wireless Communication using HC-12
                      Example 01
   by Dejan Nedelkovski, www.HowToMechatronics.com
*/


void setup() {
  Serial.begin(9600);             // Serial port to computer
  Serial1.begin(9600);               // Serial port to HC12

}

void loop() {
  while (Serial1.available()) {        // If HC-12 has data
    Serial.write(Serial1.read());      // Send the data to Serial monitor
  }
  while (Serial.available()) {      // If Serial monitor has data
    Serial1.write(Serial.read());      // Send that data to HC-12
  }
}

Second method used the softwareserial in stead of serial 1. I connected TXD to pin 10 and RXD to pin 11 and used this code

/*    Arduino Long Range Wireless Communication using HC-12
                      Example 01
   by Dejan Nedelkovski, www.HowToMechatronics.com
*/

#include <SoftwareSerial.h>

SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin

void setup() {
  Serial.begin(9600);             // Serial port to computer
  HC12.begin(9600);               // Serial port to HC12

}

void loop() {
  while (HC12.available()) {        // If HC-12 has data
    Serial.write(HC12.read());      // Send the data to Serial monitor
  }
  while (Serial.available()) {      // If Serial monitor has data
    HC12.write(Serial.read());      // Send that data to HC-12
  }
}

this is also the way I tested the Mega.

I am kinda new to the AT commands so do u have to put it in AT mode? Never heard of that tbh.
I just followed the tutorial 'Howtomechatronics' and it sais this

"We can use the same code for sending AT Commands and configuring the module parameters. All we have to do is connect the “Set” pin of the module to Ground or any digital pin of the Arduino and set the pin to low logic level."

So thats what I did, I used the same code as above, this time only using one arduino. I conencted the Set to gnd and tested with "AT" but no response.

What I am going to do now is test every part, from arduino to cables and even my soldering (because that could be the problem). And see if I can find it.

try this on your MEGA

connect HC12 Rx to Arduino Serial1 Tx1 (pin 18)
connect HC12 Tx to Arduino Serial1 Rx1 (pin 19)
connect HC12 Set to Arduino pin 4
connect HC12 GND to Arduino GND
connect HC12 VCC to Arduino 5V

load this code

const uint8_t hc12SetPin = 4;  // for AT mode when Grounded
#define HC12 Serial1

void ATCommandMode(bool mode) {
  digitalWrite(hc12SetPin, mode ? LOW : HIGH); // pull SET to LOW to activate AT command mode
  delay(mode ? 40 : 80); // according to doc (40ms upon activation, 80ms upon exit)
}

void setup() {
  pinMode(hc12SetPin, OUTPUT);  // LOW by default (=> AT Command mode)
  Serial.begin(115200); Serial.println();
  HC12.begin(9600); // try 4800, 9600, 1200, 2400, 19200, 38400, 57600, 115200
  ATCommandMode(true);
}

void loop() {
  if (Serial.available()) HC12.write(Serial.read());
  if (HC12.available()) Serial.write(Serial.read());
}

open the serial monitor at 115200 bauds, set the console to sendCR/LF

type ATreturn in the Serial monitor
what do you see?

if nothing shows, try different baud rates here:

  HC12.begin(9600); // try 4800, 9600, 1200, 2400, 19200, 38400, 57600, 115200

but keep the Serial monitor at 115200 bauds

Ok so I did exactly as u said, and got 2 different resposnes from the different baud rates. sometimes (with 9600 and 4800 for example) after typing AT, there were a bunch of questionmarks that kept being spammed in console. With other baud rates nothing happened. I dont really understand teh Cr/LF thing but I set it to new line or both NL as CR idk if hat is right I dont have the option for CR/LF anywhere

That's the last option in the Serial monitor pull down menu
(here in French)
image

this is to ensure the program does receive (and thus send) the end of line characters as they are expected by the HC12

With the same setup as described precendently, can you try this code and copy the text of what you see in the Serial Monitor and paste it here (within code tags). There is nothing to type in the Serial monitor, just wait until all baud rates have been tested

const uint8_t hc12SetPin = 4;  // for AT mode when Grounded
#define HC12 Serial1

unsigned long baudRates[] = {1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200};

void ATCommandMode(bool mode) {
  digitalWrite(hc12SetPin, mode ? LOW : HIGH); // pull SET to LOW to activate AT command mode
  delay(mode ? 40 : 80); // according to doc (40ms upon activation, 80ms upon exit)
}

void tryThisRate(unsigned long baud) {
  unsigned long t0 = millis();
  ATCommandMode(false);
  ATCommandMode(true);
  HC12.begin(baud);
  Serial.print("-----------\nTesting at "); Serial.print(baud); Serial.println(" Bauds");
  
  HC12.println("AT");
  delay(100);
  HC12.println("AT+RX");

  while (millis() - t0 < 5000) {
    if (HC12.available()) {
      int r = Serial.read();
      switch (r) {
        case '\r':
        case '\n':
        case 'a'...'z':
        case 'A'...'Z':
        case '0'...'9':
          Serial.write(r);
          break;
        default: Serial.print("[0x"); Serial.print(r, HEX); Serial.write(']');
      }
    }
  }
  Serial.println("\nTest ended");
  HC12.end();
}

void setup() {
  pinMode(hc12SetPin, OUTPUT);  // LOW by default (=> AT Command mode)
  Serial.begin(115200); Serial.println();
  for (auto& b : baudRates) tryThisRate(b);
}


void loop() {}

first of all I wanna say thanks for the help I've been getting, didn't expect to get helped this much.

I did it with one of the HC12 modules:
these are the results:

(couldn't send it, too many characters)
(the first line might be from a previous test idk for sure tho)

This is from the other one.

-----------
Testing at 1200 Bauds

Test ended
-----------
Testing at 2400 Bauds

Test ended
-----------
Testing at 4800 Bauds

Test ended
-----------
Testing at 9600 Bauds

Test ended
-----------
Testing at 19200 Bauds

Test ended
-----------
Testing at 38400 Bauds

Test ended
-----------
Testing at 57600 Bauds

Test ended
-----------
Testing at 115200 Bauds

Test ended

But i think this one may have soem bad wire connection because with teh previous test I sometimes also got the question marks I got with the other one when I wiggled with the wires

Yes, when I use the software serial version of your code I can see responses to the AT commands. It does not matter what the line ending setting is on the module I am testing. 10 and 11 should be valid software serial pins on both the mega and the leonardo. I am testing on a UNO.

With these connections
VCC-5V
GND-GND
RXD- 11
TXD- 10
SET - GND

And this code

/*    Arduino Long Range Wireless Communication using HC-12
                      Example 01
   by Dejan Nedelkovski, www.HowToMechatronics.com
*/
#include <SoftwareSerial.h>
SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
void setup() {
  Serial.begin(9600);             // Serial port to computer
  HC12.begin(9600);               // Serial port to HC12
}
void loop() {
  while (HC12.available()) {        // If HC-12 has data
    Serial.write(HC12.read());      // Send the data to Serial monitor
  }
  while (Serial.available()) {      // If Serial monitor has data
    HC12.write(Serial.read());      // Send that data to HC-12
  }
}

Load the code. Disconnect the usb connector to cycle power. Reconnect the usb and type AT into the Serial monitor which should be set for 9600 baud. I then see OK as the response.

that sounds bad indeed...

If it hasn't been mentioned in the previous posts, some are fakes (HC-12).
From another forum:
The HC-12 is generally advertised at having an Si4463 IC which can cover from 142Mhz to 1050Mhz. However, they actually ship with an Si4438 IC, which only covers from 425-525 MHz.

If you happen to get one with an Si4463 IC, it could be configured for 868Mhz or 915MHz bands, but odds are that the antenna matching components will be for 433Mhz, so the performance/range will be significantly degraded.

You may find a supplier somewhere that actually uses an Si4463, but it will most likely be a fake/clone and the antenna matching will be for 433Mhz

Also, looking at the customer reviews on various sites, it seems that HC-12s can have different firmwares, likely depending on what chip is actually used . As I understand it, HC-12 modules with different firmwares cannot communicate with each other, even when set up to the same frequency/ baud rates. (Based on customer reviews at Banggood)

www.hc01.com is the originator of the HC-12 and may have used the Si4463 at one time, but now they use Si4438. I could probably get more info but I cannot get Google Translate to translate this Chinese site into English . If someone knows how, please let me know.

There are definitely issues with HC12 clones(mostly relating to range and different crystal oscillators used) but I have never heard of a failure to go into AT mode and respond to commands as being an issue. I do not think that @mospiessens issues are related to hc01 factory original or clone.

http://www.hc01.com/downloads/HC-12%20english%20datasheets.pdf

There is a very long thread about all the issues with the clones here TheBackShed.com - Forum 1.
There is a video about possibly fixing a bad one here
HC-12 FIX for bad clones - YouTube

Also a discussion of clone issues in this Arduino forum thread

I did the same thing but no response

Mine isn't a clone I think, it has the official "HC-12" and "www.hc01.com" written on the back

Which is exactly what you might expect if your passing off a clone as Geniune ?

+1 to that

there is something else at play here. either the modules is defective or there is something wrong in the setup