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

2
  • you read two bytes if maybe only one is available
    – Juraj
    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
    – obatala
    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());
    }
}
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
    – obatala
    Commented Nov 22, 2022 at 12:28

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.