[SOLVED]HC-12 giving me trouble

hi, i'm new to wireless communication . I've been trying out and testing HC-12 modules since the past couple of weeks, I have referred to dozens of videos , articles on how to use the HC-12 , but none of them properly address my doubt, that is , if i am using a sensor to print data onto the Serial monitor , how (through code), will i send that data of the sensor from one arduino device to another arduino device. My project is , i want to send the GPS time from one arduino device to another arduino device , via the HC-12 long range communication module.
If anybody could tell me how to frame the transmitter - receiver code , it would be of great help, because i've been stuck here and constantly trying.

My project code so-far , is attatched for reference (removed the HC-12 part)

#include <NMEAGPS.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
#include<Wire.h>


SoftwareSerial gpsPort( 3, 2 );
LiquidCrystal_I2C lcd(0X27, 16, 2);
NMEAGPS gps;
DS3231 rtc(SDA, SCL);
gps_fix currentfix;
NeoGPS::time_t  localTime;


void setup()
{
  Serial.begin(9600);
  gpsPort.begin(9600);
  lcd.init();
  lcd.backlight();
  rtc.begin();

}

void loop()
{

  // Dispatch incoming characters

  while (gps.available( gpsPort))
  {

    currentfix = gps.read();

    if (currentfix.valid.date && currentfix.valid.time)
    {
      NeoGPS::clock_t localSeconds;
      NeoGPS::time_t  localTime;
      {
        using namespace NeoGPS;
        localSeconds = (clock_t) currentfix.dateTime; // convert structure to a second count
        localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
        localTime = localSeconds;              // convert back to a structure
      }

      lcd.setCursor(3,0);
      lcd.print( localTime.date );
      lcd.print( '/' );
      lcd.print( localTime.month );
      lcd.print( '/' );
      lcd.print( localTime.year );

      lcd.setCursor(3,1);
      lcd.print( localTime.hours );
      Serial.print( localTime.hours );
      lcd.print( ':' );
      Serial.print( ':' );
      if (localTime.minutes < 10) lcd.print(F("0"));
      lcd.print( localTime.minutes );
      Serial.print( localTime.minutes );
      lcd.print( ':' );
      Serial.print(':');
      if (localTime.seconds < 10) lcd.print(F("0"));
      lcd.print(localTime.seconds);
      Serial.print( localTime.seconds );
      Serial.println();
      int a = localTime.hours;
      int b = localTime.minutes;
      int c = localTime.seconds;
      rtc.setTime(a, b, c);

    }


    else
    {
      lcd.clear();
      lcd.setCursor(3,1);
      lcd.print(rtc.getTimeStr());
    }
  }
}

P.S, i have tried the codes , where i take input through keyboard into the serial monitor , and am successfully able to send the data from Arduino1 to Arduino2. I have also learnt about how to change the channels, set baud rate etc. I haven't been able to connect all the dots by myself.

In the code posted, you don't use the Serial monitor and the HC12's can be connected to hardware serial after the code is loaded to the Arduinos.

Do you have simple successful test code without the gps which sends data between the two HC12/Arduino pairs?

What Arduino's are you using? There are issues if trying to use multiple software serial instances. If you are going to need the monitor on hardware serial for input, and a gps and HC12 on software serial, you may want to consider an Arduino with multiple hardware serial ports.

1 Like

just connected a couple of HC-12 to UNOs and ran sample program OK transmitting text between Serial Monitors at 9600baud

1 Like

i have referred to websites such as

Understanding and Implementing the HC-12 Wireless Transceiver Module - Projects (allaboutcircuits.com)

I have been able to successfully send data from arduino uno1 to arduino uno2 using the code

#include<SoftwareSerial.h>

const byte HC12RxdPin = 4;                  // Recieve Pin on HC12
const byte HC12TxdPin = 5;                  // Transmit Pin on HC12

SoftwareSerial HC12(HC12TxdPin,HC12RxdPin); // Create Software Serial Port

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

void loop() {
  if(HC12.available()){                     // If Arduino's HC12 rx buffer has data
    Serial.write(HC12.read());              // Send the data to the computer
    }
  if(Serial.available()){                   // If Arduino's computer rx buffer has data
    HC12.write(Serial.read());              // Send that data to serial
  }
}

so , it wouldn't work on arduino UNO?

yeah , i have done this , it seems to be working perfectly. The only issue is when i try to send the sensor data which is written on the serial monitor of Computer-1 , to the other arduino , connected to Computer-2, i am unable to get the data on the Computer-2 Serial Monitor. It sometimes shows random values like "-1 -1 -1 -1 -1 ......"
or " 255 255 255 255 255 255..."
or "45 49 45 49 45 49 45 49.........."

while(Serial.available()) {
HC12.write(Serial.read())
}

if your transmitter has multiple serial devices (GSM, HC-12, ??) you need a microcontroller such as an Arduino Mega which has three hardware serial ports
you can still use the UNO to receive using SoftwareSerial if the only serial device is a HC-12 (keep the speed below 38400baud)

1 Like

thank you . i will get an Arduino Mega and try this out.

Uning a Mega is a good choice, but you can try your code on the uno using a hardware serial connection(rx>tx, tx>rx) after the code is loaded. You should be able to send the sensor value to both the monitor and the other Arduino with a Serial.print() statement.

You can test this out, using the code of your first post, and not using any HC12's, but just connecting the two uno's with wires (cross connect) between the serial ports. You should be able to confirm gps data transferred between the unos and the lcd functions.

Then, with the HC12's connected to hardware serial and no changes in code, should be able to replace the wired serial connection on the hardware port.

With this arrangement you can not provide any input from the monitor or load code when the devices are connected. You must disconnect the wires from the serial port to load code.

so , i tried on your recommendations, got myself an arduino mega , ported my code from Arduino uno to Arduino mega, added the HC-12 part as well, and now my sender's code looks something like this

#include <NMEAGPS.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
#include<Wire.h>
#define gpsPort Serial1
const byte HC12RxdPin = 0;                  // Recieve Pin on HC12
const byte HC12TxdPin = 1;

LiquidCrystal_I2C lcd(0X27, 16, 2);
NMEAGPS gps;
DS3231 rtc(SDA, SCL);
gps_fix currentfix;
NeoGPS::time_t  localTime;
SoftwareSerial HC12(HC12TxdPin, HC12RxdPin); // Create Software Serial Port

void setup()
{
  Serial.begin(9600);
  gpsPort.begin(9600);
  lcd.init();
  lcd.backlight();
  rtc.begin();
  HC12.begin(9600);

}

void loop()
{

  // Dispatch incoming characters

  while (gps.available(gpsPort))
  {

    currentfix = gps.read();

    if (currentfix.valid.date && currentfix.valid.time)
    {
      NeoGPS::clock_t localSeconds;
      NeoGPS::time_t  localTime;
      {
        using namespace NeoGPS;
        localSeconds = (clock_t) currentfix.dateTime; // convert structure to a second count
        localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
        localTime = localSeconds;              // convert back to a structure
      }

      lcd.setCursor(3, 0);
      lcd.print( localTime.date );
      lcd.print( '/' );
      lcd.print( localTime.month );
      lcd.print( '/' );
      lcd.print( localTime.year );

      lcd.setCursor(3, 1);
      lcd.print( localTime.hours );
      Serial.print( localTime.hours );
      lcd.print( ':' );
      Serial.print( ':' );
      if (localTime.minutes < 10) lcd.print(F("0"));
      lcd.print( localTime.minutes );
      Serial.print( localTime.minutes );
      lcd.print( ':' );
      Serial.print(':');
      if (localTime.seconds < 10) lcd.print(F("0"));
      lcd.print(localTime.seconds);
      Serial.print( localTime.seconds );
      Serial.println();
      int a = localTime.hours;
      int b = localTime.minutes;
      int c = localTime.seconds;
      rtc.setTime(a, b, c);

      if (Serial.available()) {                   // If Arduino's HC12 rx buffer has data
        HC12.write(Serial.read());              // Send the data to the computer
      }

      // If Arduino's computer rx buffer has data

    }


    else
    {
      lcd.clear();
      lcd.setCursor(3, 1);
      Serial.println(rtc.getTimeStr());
      lcd.print(rtc.getTimeStr());


    }
  }
}

and my reciever's code is something like

#include<SoftwareSerial.h>

const byte HC12RxdPin = 5;                  // Recieve Pin on HC12
const byte HC12TxdPin = 4;                  // Transmit Pin on HC12

SoftwareSerial HC12(HC12TxdPin, HC12RxdPin); // Create Software Serial Port

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

void loop() {
  while(HC12.available()){                     // If Arduino's HC12 rx buffer has data
    Serial.write(HC12.read());              // Send the data to the computer
    }

}

the issue i'm facing now is weird. There seems to be some interaction between the HC-12s, everytime i upload the sender's code to the mega , the serial monitor of the arduino UNO, seems to write weird characters, then questionmarks and then stops , when the lcd refreshes , and even though the lcd continues showing me data(i.e time and date), the Serial Monitor connected to the arduino doesn't print anything.


Arduino Mega Connection :point_up_2:


Arduino Uno connections :point_up_2:

My LCD Display working just fine :point_up_2:


My Arduino Mega Serial Monitor :point_up_2:


My Arduino Uno Serial Monitor :point_up_2:

You should not be using SoftwareSerial with the mega. You have four hardware serial ports.

Garbage on the serial monitor is usually a result of mismatched Baud rates. Match the setting on the serial monitor with the rate specified by serial.begin().

What is the baud rate that you're selecting in the serial monitor? Can't see in your photo. This type of garbage data appear due to baud rate mismatch usually.

why are you using mega pins 0 and 1 for Software Serial for the HC12 ?
you have hardware ports - use Serial2 pins 16 and 17

1 Like

alright , will check that out.

all baud rates were set to 9600. there seemed to be no mismatch

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.