0

I currently have 2 Arduinos both hooked up to HC-12s and have successfully got them communicating. But I am now trying to be able to process the data sent across and store it as a variable so as to make comparisons. But I'm getting junk data that comes over with the code, which prevents me from being able to do these comparisons.

For example, from one arduino when I sent "stop" I received

stop<⸮=l⸮⸮⸮

I cant figure out what this junk is from, also, I've limited the receivedChars to a size of 4, why am I getting more than 4 characters?

The code from the sender

#include <SoftwareSerial.h>

SoftwareSerial HC12(3, 2); // HC-12 TX Pin, HC-12 RX Pin

void setup() { Serial.begin(9600); // Serial port to computer HC12.begin(9600); // Serial port to HC12 Serial.print("Checking HC-12 module: "); HC12.write("AT"); //Check for response(this is sending data to the HC, the SET pin must be low for this to work) delay(1000); HC12.write("AT+RX"); //Gets configs of HC-12 }

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 } }

The simplified receiving code

    #define BYTELENGTH 4 //Limited to 4 chars
       #define ENDMARKER '\n'  //To know when stop stop reading serial
   SoftwareSerial HC12(3, 2); // HC-12 TX Pin, HC-12 RX Pin

Serial.begin(9600); //Fastest it can be on the nano HC12.begin(9600); // Serial port to HC12s

  char receivedChars[BYTELENGTH - 1];
  int byteIndex;
  char curChar;

  while (HC12.available()) {        // If HC-12 has data
    curChar = HC12.read();
    if(curChar != ENDMARKER){
      receivedChars[byteIndex] = curChar;
      byteIndex++;
    }
  }
  if(strcmp(receivedChars,&quot;&quot;) != 0){
    Serial.println(receivedChars);
    receivedChars[0] = 0;
  }

dka13
  • 3
  • 4

3 Answers3

1

I would say you are printing data outside of your char array, because you didn't terminate the C-string in it and the size of your array is too small.

You have

#define BYTELENGTH 4 //Limited to 4 chars
char receivedChars[BYTELENGTH - 1];

so your char array is only 3 elements big. When you want to save a string in that array, you always need to terminate it with a null character \0 (which is also zero in decimal representation). So in that char array you only have space for 2 characters. But your message "stop" is 4 characters long, so you need a char array with at least 5 elements. If you are not in an extreme tight memory situation I would suggest using a buffer with a bit headroom above your biggest message (to be sure, that nothing breaks, if you later use messages that are a bit longer). So more like this:

#define BYTELENGTH 10 //Limited to 4 chars
char receivedChars[BYTELENGTH + 1]; // message length + null character termination

And then you need to change your receiving code to add a null character at the end of the message. Also you might want to actually use the newline character \n as message delimiting (which you are currently not doing):

bool full_message_received = false;

void loop(){ while (HC12.available()) { // If HC-12 has data curChar = HC12.read(); if(curChar != ENDMARKER){ receivedChars[byteIndex] = curChar; byteIndex++; } else { receivedChars[byteIndex] = '\0'; // terminating the c-string full_message_received = true; // marking the message as fully received } } if(full_message_received){ Serial.println(receivedChars); receivedChars[0] = 0; full_message_received = false; } }

What happens, if I don't terminate the string with a null character? All the functions, that handle C-strings (like strcmp() or also Serial.print()) use the null character to determine, at which point the string is at its end. They don't know the size of your array, so they just read byte after byte, until they reach the null character. They even read more data than is in your array. The junk characters are most likely exactly, what currently is placed in the memory directly after your array. Serial.print() doesn't know, that they don't belong to the C-string, since you didn't use the null character to tell it that. It just keeps printing characters, until it reaches a byte, that is zero.

You even wrote data to memory outside of the array. Depending on what comes directly after your array in the memory this can be without any problems, but you might also overwrite some other data, without knowing, what that data is. That can lead to very weird and hard to debug problems. Be sure to never write outside of your array. You might break things in weird ways.

chrisl
  • 16,622
  • 2
  • 18
  • 27
0

It appears you have a baud rate problem. I am surprised you are getting anything. You need software to start the serial port such as SoftwareSerial mySerial(rxPin, txPin) then in setup mySerial.begin(9600); You need that in each application and the baud rates need to be the same.

I have used SC16IS750 I2C/SPI-to-UART devices as an external UART, they work great and have many nice features such as a 64 bytes of transmit and receive FIFOs. Some versions of this have been obsoleted but they are still available and work fine. You get 8 additional I/Os as well.

Gil
  • 1,863
  • 9
  • 17
-1

According to this vidéo in French it appeared that the problems comes from the SoftwareSerial library which if not reliable enough to provide accurate timings for your transmission. There are alternate software serial libraries (like AltSoftSerial), which use hardware timers, but I can't tel you more because I didn't try to use it.

All I can say, is that I my case removing SoftwareSerial to use the defaut hardware serial port solved the problems I had.

Alternatively, you can use I²C ⇒ UART IC like MAX3100, in order to provide aother hardware UART (With MAX3100 you'll need to add a 3.6468 or 1.8234 MHz crystal and 2×22pf capacitors) - I also didn't try it yet (Chip and crystal are ordered though. Or also you should be able to make the i2c ⇒ UART conversion with one more Arduino.

Camion
  • 109
  • 1