1

I'm working on a project, and I purchased a 24 GHz "Human existence/presence" mm Wave sensor from micradar, the R24DVD1. The output of the module is serial data which varies in length and is of the structure shown below; enter image description here

The Data element of the stream could get as large as 5bytes and as show each package ends with a 0x54 0x43. My intention is to have my Arduino Uno read the data for further processing. Since I use the Arduino Uno which has only one physical serial port, I felt using it to read the sensor data could prove problematic since the pc is equally connected to that serial line via USB. So I decided to use the SoftwareSerial to read the data from the senor then forward it to the pc and I wrote the following code for that;

#include <SoftwareSerial.h>
const int txpin = 3;
int const rxpin = 2;
SoftwareSerial mySerial(rxpin,txpin);
const unsigned int PACK_SIZE = 14;
int inByte1;
int inByte2;
unsigned int recvdByte = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
mySerial.begin(115200);
 }
void loop() {
// put your main code here, to run repeatedly:
if (mySerial.available() > 0){
int pack[PACK_SIZE];
inByte1 = mySerial.read();
inByte2 = mySerial.read();
if(inByte1 != 84 && inByte2 != 67){
 pack[recvdByte] = inByte1;
 pack[recvdByte+1] = inByte2;
 recvdByte += 2;
 }
else{
 pack[recvdByte] = inByte1;
 pack[recvdByte+1] = inByte2;
 recvdByte = 0;
 }
for(int i = 0; i < PACK_SIZE; i++)
{
 Serial.print(pack[i],HEX);
}
Serial.println();
 }
}

I would like to know if my thought process in reading and parsing the data is correct because the output is quite inconsistent to what I expect

asked Nov 4, 2022 at 7:03
2
  • you read two bytes if maybe only one is available Commented Nov 4, 2022 at 7:39
  • My thought process was to read two bytes so I can compare if two consecutive bytes are 0x54 and 0x43 then I know it's the end of a frame of data. Any suggestion on how to go about it?@Juraj Commented Nov 4, 2022 at 7:51

1 Answer 1

1

First of all, I would advise you against using SoftwareSerial, especially at this high baud rates: it is a recipe for problems. Since you seem to be using the link to the computer only for writing, and the link to the sensor only for reading, you can use the hardware serial port for both. Connect the sensor's TX to the Arduino RX, and you will be able to read the sensor data with Serial.read(). Do not connect the sensor's RX, and you will be able to Serial.print() to the serial monitor without disturbing the sensor.

Next, you must be aware that serial data is received one byte at a time. If you waited until you had a full packet in the serial buffer, then you could read and process the whole packet at once. This is, however, difficult, because you cannot know the length of the packet before starting to read it.

I would recommend that instead you process one incoming byte at a time, and you do the necessary sanity checks in the process. Here is how I would do it (warning: untested code):

const unsigned int MAX_PACKET_SIZE = 14;
const unsigned char char start_signature[] = {0x53, 0x59};
const unsigned char char end_signature[] = {0x54, 0x43};
unsigned char packet[MAX_PACKET_SIZE];
int recvdByte = 0; // number of bytes received and buffered so far
int dataLength = 0; // length of the data field
void processPacket(); // defined elsewhere
// Handle a single input byte.
void processInputByte(unsigned char inByte) {
 if (recvdByte < 2) { // check the start signature
 if (inByte != start_signature[recvdByte]) { // wrong signature?
 recvdByte = 0; // discard the packet
 return;
 }
 } else if (recvdByte == 4) { // grab the data length
 dataLength = inByte;
 if (dataLength > MAX_PACKET_SIZE - 9) { // overlong packet?
 recvdByte = 0; // discard the packet
 dataLength = 0;
 return;
 }
 } else if (recvdByte == 5) { // check the second data length
 if (dataLength != inByte) { // doesn't match?
 recvdByte = 0; // discard the packet
 dataLength = 0;
 return;
 }
 } else if (recvdByte == 6 + dataLength) { // check sum
 // TODO: Look at the datasheet to see how to control that
 // the checksum is correct. Discard the packet if it is not.
 } else if (recvdByte >= 7 + dataLength) { // check end signature
 if (inByte != end_signature[recvdByte - (7 + dataLength)]) {
 recvdByte = 0; // discard the packet
 dataLength = 0;
 return;
 }
 }
 // All correct so far, we can buffer the incoming byte.
 packet[recvdByte++] = inByte;
 // If we have a complete packet now, handle it.
 if (recvdByte == 9 + dataLength) {
 processPacket();
 recvdByte = 0; // reset for the next packet
 dataLength = 0;
 }
}

You may want to sprinkle a few Serial.println() here and there for testing and debugging. These could be removed once everything works as expected.

Then, in the main loop, you just have to:

void loop() {
 if (Serial.available() > 0) {
 processInputByte(Serial.read());
 }
}
answered Nov 4, 2022 at 10:14
1
  • Thanks a million Edgar. This with a little modification does the trick most of the time. I will keep working on it to see if I can get it working better Commented Nov 22, 2022 at 12:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.