Go Down

Topic: [Solved] HC-12 433 MHz to receive a text message (Read 14420 times) previous topic - next topic

PaulS

Quote
because the serial buffer contains junk data from the last time.
It isn't junk data. If it truly were, you wouldn't have sent it.

Quote
How can I clean the buffer after the terminating 'N' is received?
Just like you showed. What you don't seem to have realized yet it is that serial data transmission is slow, compared to how fast the Arduino can read the data.

So, you send somNambula, and 's' arrives, and the Arduino reads and stores it. A whole bunch of loop() cycles later, the 'o' arrives, and the Arduino reads and stores it. A whole bunch of loop() cycles later, the 'm' arrives, and the Arduino reads and stores it. A whole bunch of loop() cycles later, the 'N' arrives, and the Arduino sees it as the end of the packet.

No other data has arrived, yet, so there is nothing to discard.

A whole bunch of loop() cycles later, the 'a' arrives, and the Arduino reads and stores it. And, the cycle repeats until the next 'N' arrives.

You need to understand what "end of packet" means. It does NOT mean "somewhere in the middle of the text" that is to be sent. It means "at the END".
The art of getting good answers lies in asking good questions.

ValeryOD

You're right) Adding a 100 ms delay solved this.

ValeryOD

#32
Nov 04, 2015, 12:30 pm Last Edit: Nov 05, 2015, 07:35 am by ValeryOD
So I have welded everything together, and it works perfectly. Thanks everyone for your kind assistance and help! [SOLVED]

Here is the final code for the TRANSMITTER:

Code: [Select]
// HC-12 TRANSCEIVER
// TRANSMITTER (TX) part
//
// This code is used to transmit an ALARM message from one Arduino with
// the wireless HC-12 (433 MHz) module on board to another. It makes make sure the important message
// has been received by waiting for confirmation.
// The program can be handy, when you have e.g. an autonomous wired alarm system
// in a garage or a shed and wish to transmit the alarm signal to the house.
// Or else it can bind with another alarm system, which is probably a GSM one,
// to trigger one of its control lines with a relay.
// Anyway, there aren't too many sketches utilizing the HC-12 433 MHz module
// on the internet - so here is a humble example.
//
// Valery Osipov, 2015
// valery.osipov@outlook.com

#include <SoftwareSerial.h>
SoftwareSerial hc12(9, 11); // RX, TX pins on Arduino

const int pcnPin = 3; // pin connected to the output of the client alarm system
const int greenLed = 4;
const int redLed = 5;
const int setPin = 7; // pin used to set up the HC-12 wireless module
boolean confirmed = false;
const byte numChars = 16;
char messageReceived[numChars]; // allocate some space for the incoming message
char alarmMessage[] = "ALARM\n"; // alarm message to be sent; '\n' is a forced terminator char
char confirmWord[] = "OK"; // confirmation keyword awaited

void setup() {
  pinMode(setPin, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  pinMode(pcnPin, INPUT_PULLUP); // my alarm system will ground the dry contact upon alarm
  hc12.begin(9600); // start the software serial port

  // setup of the hc12 module
  digitalWrite(7, LOW); // enter AT command mode
  hc12.print(F("AT+DEFAULT\r\n")); // 9600, CH1, FU3, (F) to bypass flash memory
  delay(100);
  digitalWrite(7, HIGH); // enter transparent mode
}

void loop() {
  static byte ndx = 0; // it will define an index # in the array
  char charReceived; // this will contain one last character received via serial port
  char endMarker = '\n'; // newline character will be terminating
  // note that Serial.println() already includes both '\r' and '\n' symbols in the string

  if (digitalRead(pcnPin) == HIGH) { // standby mode
    digitalWrite(redLed, LOW);
    digitalWrite(greenLed, HIGH);
    confirmed = false;

  } else { // if the alarm pin is grounded
    digitalWrite(greenLed, LOW);

    for (int i = 0; i < 10; i++) {
      if (confirmed == true) { // until the receipt is confirmed
        break;
      }
      hc12.print(alarmMessage);
      digitalWrite(redLed, HIGH);
      delay(1000);
      digitalWrite(redLed, LOW);
      delay(1000);
      while (hc12.available() > 0) { // in case return data is pending
        charReceived = hc12.read(); // put the last buffered symbol into the variable char
        if (charReceived != endMarker) { // if it's not the terminating '\n'
          messageReceived[ndx] = charReceived;
          ndx++;
          if (ndx >= numChars) { // if there is not enough space in the array
            ndx = numChars - 1;
          }
        } else { // when the '\n' terminator finally arrives
          messageReceived[ndx] = '\0'; // close the array
          ndx = 0;
          delay(100); // Arduino loops faster, than the serial data arrives, so wait a moment
          while (hc12.available() > 0) hc12.read(); // to clean the HC-12 buffer
          if (strcmp(messageReceived, confirmWord) == 0) { // compare the received string to the confirmation word
            confirmed = true; // if they are equal (strcmp() returns 0), receipt is confirmed
          }
        }
      }
    } // only after we get a confirmation, that the ALARM is received
    digitalWrite(redLed, HIGH);
    delay(100); // debounce the alarm system relay
  }
}


And the RECEIVER:

Code: [Select]
// HC-12 TRANSCEIVER
// RECEIVER (RX) part

#include <SoftwareSerial.h> // import the necessary library
SoftwareSerial hc12(9, 11); // RX, TX pins on Arduino

const int relayPin = 3;// pin connected to a 5V relay
const int greenLed = 4;
const int redLed = 5;
const int setPin = 7; // pin used to set up the HC-12 wireless module
boolean alarmOn = false; // the alarm has not been triggered yet
const byte numChars = 32;
char messageReceived[numChars]; // allocate some space for the incoming message
char keyWord[] = "ALARM"; // alarm keyword awaited (not too much awaited)
char confirmWord[] = "OK\n"; // confirmation message to be sent

void setup() {
  pinMode(setPin, OUTPUT); //  setPin on hc12
  pinMode(greenLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  pinMode(relayPin, OUTPUT);
  hc12.begin(9600); // Start the software serial port
  // Serial.begin(9600); // activate for debugging purposes

  // setup of the hc12 module
  digitalWrite(7, LOW); // enter AT command mode
  hc12.print(F("AT+DEFAULT\r\n")); // 9600, CH1, FU3, (F) to bypass flash memory
  delay(100);
  digitalWrite(7, HIGH); // enter transparent mode
}

void loop() {
  static byte ndx = 0; // it will define an index # in the array
  char charReceived; // this will contain one last character received via serial port
  char endMarker = '\n'; // newline character will be terminating
  // note that Serial.println() already includes both '\r' and '\n' symbols in the string

  digitalWrite(redLed, LOW);
  digitalWrite(greenLed, HIGH);
  while (hc12.available() > 0) { // in case return data is pending
    charReceived = hc12.read(); // put the last buffered symbol into the variable char
    if (charReceived != endMarker) { // if it's not the terminating '\n'
      messageReceived[ndx] = charReceived;
      ndx++;
      if (ndx >= numChars) { // if there is not enough space in the array
        ndx = numChars - 1;
      }
    } else { // and if the '\n' terminator finally arrives
      messageReceived[ndx] = '\0';  // close the array
      ndx = 0;
      delay(100); // Arduino loops faster, than the serial data arrives, so wait a moment
      while (hc12.available() > 0) hc12.read(); // to clean the HC-12 buffer
      if (strcmp(messageReceived, keyWord) == 0) { // compare the received string to the alarm keyword
        hc12.println(confirmWord); // if they are equal (strcmp() returns 0), send a confirmation of receipt
        digitalWrite(greenLed, LOW);
        digitalWrite(relayPin, HIGH); // turn on the relay for a few second and blink a LED
        digitalWrite(greenLed, LOW);
        digitalWrite(redLed, HIGH);
        delay(1000);
        digitalWrite(relayPin, LOW);
        digitalWrite(redLed, LOW);
        delay(1000);
      }
    }
  }
}

Go Up