I have set up a pair of HC-12 to work together with Arduino Nanos. One of the devices transmits numbers from 0 to 9 in sequence and the receiver sends them back. The transmitter than shows what it received back on a OLED display. I know it is working because I can see the numbers incrementing when bot devices are on. However, for some reason, I can no longer send AT command using the Arduino IDE serial monitor. This was working yesterday, or at least, I was able to send the AT command and get an OK back. This is no longer working. The "set" pin is being grounded and it is definitely doing something since when I do that, the communications between the pair stops. But commands sent through the serial monitor give no response. Is there anything else I should check?
Transceiver code:
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// declare an SSD1306 display object connected to I2C
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
int x = 0;
int ReceivedValue = 0;
void setup() {
Serial.begin(9600); // Serial port to computer
HC12.begin(9600); // Serial port to HC12
// initialize OLED display with address 0x3C for 128x64
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
delay(2000); // wait for initializing
oled.clearDisplay(); // clear display
oled.setTextSize(1); // text size
oled.setTextColor(WHITE); // text color
oled.setCursor(0, 10); // position to display
oled.println("Awaiting Feedback"); // text to display
oled.display(); // show on OLED
delay(2000);
}
void loop() {
while (HC12.available()) { // If HC-12 has data
ReceivedValue = HC12.read();
oled.clearDisplay(); // clear display
oled.setTextSize(4); // text size
oled.setCursor(0, 10); // position to display
oled.println(String(ReceivedValue)); // text to display
oled.display(); // show on OLED
}
HC12.write(x); // Send that data to HC-12
x++;
if(x >= 10){
x = 0;
}
delay(250);
}
Repeater Code:
#include <SoftwareSerial.h>
SoftwareSerial HC12(10, 11); // HC-12 TX Pin, HC-12 RX Pin
int ReadValue;
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
ReadValue = HC12.read();
HC12.write(ReadValue); // Send back data to HC-12
Serial.println(String(ReadValue));
}
}
according to the documentation, you need to set the SET pin HIGH or LOW depending if you want to be in AT Command mode or transparent bridge. The doc also states some mandatory delay for the mode to become active.
I'm using this function:
void setATCommandMode(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)
}
call it with true when you want to go to AT command mode and false when you want to exit that mode.
of course the hc12SetPin needs to be defined (the pin number of your Arduino connected to the SET pin of the HC-12) and you need to have pinMode(hc12SetPin, OUTPUT); in your setup.
As the default for an OUTPUT pin is to be LOW, it means you are in AT Command mode in the setup() once you've done the pinMode().
the SET pin on the module has an 1kΩ internal PULLUP and the doc states:
Module Parameter Setting AT Command
AT command is used to set the module parameters and switch the module functions, and after setting, it will be valid only after exiting from setting state. Meanwhile, modification of parameters and functions will not be lost in case of power failure.
(1) Command mode entering The first way to enter: in normal use (energized), put Pin 5 “SET” in low level; The second way to enter: disconnect power supply, first put Pin 5 “Set” in low level, and then energize it;
Either of the above two ways can make the module enter AT command mode; release it (not put pin “SET” in low level), and exit from the command mode. If the module function is changed after exiting from command mode, it will be switched to corresponding functional status.
In the second way, the module enters AT in the serial port format of 9,600, N, 1 constantly.
That is what I am doing. But the AT commands sent from the Serial Monitor are not working. The serial connection is working though, and I am sure of that because when not in AT mode, the Arduino is able to communicate to the PC through the USB cable.
I believe I have found the problem. Apparently, depending on the sketch that is running on the Arduino, it has an effect on whether the AT commands work or not. I tried replacing the repeater code shown in the original post with this code:
#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
}
}
Now the AT commands work properly. I guess some part of the code was inhibiting the serial communication needed to send AT commands from the PC to the HC-12 module through the Arduino.
Just a quick note, I had a very similar problem as the OP, although I was using a PC terminal emulator. All I ever got returned from the HC-12 was "ERROR" with every character I typed (but nicely formatted so clearly correct baud rate), it was driving me batty. Tried your code and BAM, everything worked immediately.
Thanks ospreygozo for posting this and seeing it through!
PS the SET input was always grounded in my case too.....