Reading RAW Data From RS232 Device & Split Them!

Hy There, This is my first posting.

I want to understand how to split the data, the result of the command, which I send to the RS232 Truck Controller.

I get real time data, with the following command:

02 4D 32 03 75

HEX Data Result from RS232 Truck Controller like this :

02 06 03 07 02 4d 32 10 02 a0 01 7d 01 c8 00 fa 00 15 00 00 00 00 01 00 00 01 03 96 (Truck Condition is Empty & Stopped)

02 06 03 07 >> Unit Distinction
02 4D 32 10 02 A0 01 7D 01 C8 00 FA 00 15 00 00 00 00 01 00 00 01 03 96 >> Data Frame With STX ETX & BCC(XOR)

02 4D 32 10 02 >> HEAD
A0 01 7D 01 C8 00 FA 00 15 00 00 00 00 01 00 00 01 >> Real Time Data
03 96 >> ETX & BCC

I want to split them and the final result is like this :

FL:
FR:
PRL:
RR:
INC:
PAYLD:
SP:
STST DIG:
ANA1:
ANA2:
VEH STAT:

Anyone can help me please ?
Thanks Before.


Please give us the code you are starting with.
Paul

This is my First Code to collect the Data :

int inBytes;

void setup()
{
pinMode(onBoardLed, OUTPUT);
Serial.begin(9600);
Serial1.begin(9600); //Begin Serial to talk to the Truck Controller
}

void loop() {
//Send Command to Truck RS232 Device
byte message = {0x02, 0x4d, 0x32, 0x03, 0x7e};
Serial1.write(message, sizeof(message));
delay(1000);
while (Serial1.available())
{
inBytes = Serial1.read();
if ( inBytes < 0x10 )
{
Serial.write( '0' );
}
Serial.print(inBytes, HEX);
}
}

OK. But get rid of the delay.
Does the code work?
Paul

consider the output from the code below (amended)

     77  FL
     50  FR
      3  PRL
    126  RR

byte msg [] = {0x02, 0x4d, 0x32, 0x03, 0x7e};

const char *label [] = {
    "", "FL",    "FR",   "PRL",     "RR",
    "INC",  "PAYLD", "SP",      "STST DIG",
    "ANA1", "ANA2",  "VEH STAT",
};

char s [80];


void
dispMsg (
    byte *msg,
    int   nByte )
{
    for (int n = 1; n < nByte; n++)  {
        sprintf (s, " %6d  %s", msg [n], label [n]);
        Serial.println (s);
    }

}

void setup()
{
    Serial.begin(9600);

    dispMsg (msg, sizeof(msg));
}

void loop() {
}

Help me understand the protocol.
Does you device only, ever send a message one time after you have sent a request? So the communication is request and then response.
Otherwise, there is no way to identify the beginning of a new message, nor is there a way to identify the end of a message.
Are the messages of a single type ALWAYS the same length?
Paul

It seems all messages are framed with STX < message > ETX CRC.

so read until STX is seen
then read until ETX -- readByteUntil ()
and if you care, process the CRC

A version that does not check the CRC, but that could be added.

uint8_t testData[] = {
  0x02, 0x06, 0x03, 0x07, 0x02, 0x4d, 0x32, 0x10, 0x02, 0xa0, 0x01, 0x7d, 0x01, 0xc8, 0x00, 0xfa,
  0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x96, 0x02, 0x06, 0x03, 0x07,
  0x02, 0x4D, 0x32, 0x10, 0x02, 0xA0, 0x01, 0x7D, 0x01, 0xC8, 0x00, 0xFA, 0x00, 0x15, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x96, 0x02, 0x4D, 0x32, 0x10, 0x02, 0xA0, 0x01, 0x7D,
  0x01, 0xC8, 0x00, 0xFA, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x96
};

class DummySerial {
    const uint8_t * dPtr;
    size_t dLen;
  public:
    DummySerial(const byte* data, size_t dataLen) : dPtr(data), dLen(dataLen) {}
    bool available() {
      return dLen > 0;
    }
    int16_t read() {
      if (available()) {
        dLen--;
        return *dPtr++;
      } else {
        return -1;
      }
    }
} DSerial(testData, sizeof(testData));

const byte STX = 2;
const byte ETX = 3;

const byte maxMsgLen = 64;

void setup() {
  Serial.begin(115200);
  Serial.println(F("process data from DummySerial\n"));
}

void loop() {
  handleDSerial();
}

void oneLineReceived(const uint8_t * buffer, size_t len) {
  if (len < 10) {
    Serial.write(' ');
  }
  Serial.print(len);
  Serial.print(F(":"));
  while (len--) {
    Serial.write(' ');
    if (*buffer < 16) {
      Serial.write('0');
    }
    Serial.print(*buffer++, HEX);
  }
  Serial.println();
}

enum RxState {
  waitForSTX,
  collectUntilETX,
  waitForCRC,
};

void handleDSerial() {
  static RxState rxs = waitForSTX;
  static uint8_t bIndex;
  static uint8_t buffer[maxMsgLen + 1];
  if (DSerial.available()) {
    uint8_t inChar = DSerial.read();
    switch (rxs) {
      case waitForSTX:
        if (inChar == STX) {
          buffer[bIndex++] = inChar;
          rxs = collectUntilETX;
        }
        break;
      case collectUntilETX:
        buffer[bIndex++] = inChar;
        if (inChar == ETX) {
          rxs = waitForCRC;
        }
        break;
      case waitForCRC:
        buffer[bIndex++] = inChar;
        oneLineReceived((const uint8_t *)(buffer + 1), bIndex - 3);
        bIndex = 0;
        rxs = waitForSTX;
        break;
    }
  }
}
18:26:12.090 -> process data from DummySerial
18:26:12.090 -> 
18:26:12.090 ->  1: 06
18:26:12.090 -> 21: 4D 32 10 02 A0 01 7D 01 C8 00 FA 00 15 00 00 00 00 01 00 00 01
18:26:12.090 ->  1: 06
18:26:12.090 -> 21: 4D 32 10 02 A0 01 7D 01 C8 00 FA 00 15 00 00 00 00 01 00 00 01
18:26:12.090 -> 21: 4D 32 10 02 A0 01 7D 01 C8 00 FA 00 15 00 00 00 00 01 00 00 01

consider following checked on laptop (yes, looks like BCC (0x75) is incorrect in first msg;

 processMsg: BCC error 0x75 0x7e

    0x06 0x03 0x07

    0x4d 0x32 0x10 0x02 0xa0 0x01 0x7d 0x01
    0xc8 0x00 0xfa 0x00 0x15 0x00 0x00 0x00
    0x00 0x01 0x00 0x00 0x01 0x03 0x96

    0x06 0x03 0x07

    0x4d 0x32 0x10 0x02 0xa0 0x01 0x7d 0x01
    0xc8 0x00 0xfa 0x00 0x15 0x00 0x00 0x00
    0x00 0x01 0x00 0x00 0x01 0x03 0x96

    0x4d 0x32 0x10 0x02 0xa0 0x01 0x7d 0x01
    0xc8 0x00 0xfa 0x00 0x15 0x00 0x00 0x00
    0x00 0x01 0x00 0x00 0x01 0x03 0x96
#include <stdio.h>

typedef unsigned char byte;

byte input [] = {
  0x02, 0x4D, 0x32, 0x03, 0x75,
  0x02, 0x06, 0x03, 0x07,
  0x02, 0x4d, 0x32, 0x10,  0x02, 0xa0, 0x01, 0x7d,
  0x01, 0xc8, 0x00, 0xfa,  0x00, 0x15, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00,  0x00, 0x01, 0x03, 0x96,
  0x02, 0x06, 0x03, 0x07,
  0x02, 0x4D, 0x32, 0x10,  0x02, 0xA0, 0x01, 0x7D, 
  0x01, 0xC8, 0x00, 0xFA,  0x00, 0x15, 0x00, 0x00, 
  0x00, 0x00, 0x01, 0x00,  0x00, 0x01, 0x03, 0x96,
  0x02, 0x4D, 0x32, 0x10,
  0x02, 0xA0, 0x01, 0x7D,  0x01, 0xC8, 0x00, 0xFA,
  0x00, 0x15, 0x00, 0x00,  0x00, 0x00, 0x01, 0x00,
  0x00, 0x01, 0x03, 0x96,
};


struct Serial_s {
    int idx;
    int available (void)   { return sizeof(input) - idx; };
    byte read (void)        { return input [idx++]; }

    int readByteUntil (byte c, byte *buf, int len) {
     // printf ("%s: c 0x%02x", __func__, c);
        for (int n = 0; n < len; n++) {
            buf [n] = read();
            if (c == buf [n])
                return n+1;
        }
        return len;
    }

    void println (char *s) { printf ("%s\n", s); }
    void println (byte  c) { printf (" 0x%02x\n", c); }
    void println (byte *buf, int nByte) {
        for (int n = 0; n < nByte; n++)  {
            if (! (n % 8))
                printf ("\n   ");
            printf (" 0x%02x", buf [n]);
        }
        printf ("\n");
    }
};

Serial_s Serial;

// -----------------------------------------------------------------------------
byte buf [100];
#define BufSize  sizeof(buf)

const byte STX  = 0x02;
const byte ETX  = 0x03;

// ---------------------------------------------------------
void
processMsg (
    byte  *buf,
    int    nByte )
{
    int  sum = 2;
    for (int n = 0; n < nByte-1; n++)
        sum = sum ^ buf [n];

    if (sum != buf [nByte-1])  {
        printf (" %s: BCC error 0x%02x 0x%02x\n",
            __func__, buf [nByte-1], sum);
        return;
    }

    Serial.println (buf, nByte);
}

// ---------------------------------------------------------
void
loop (void)
{
    if (Serial.available ())  {
        byte c = Serial.read ();
        if (STX != c)
            return;

        int nByte = Serial.readByteUntil (ETX, buf, BufSize);

        // unfortunately code needs to read one by byte
        while (! Serial.available ())
            ;
        buf [nByte++] = Serial.read ();

        processMsg (buf, nByte);
    }
}

// -----------------------------------------------------------------------------
int
main (void)
{
    for (int n = 0; n < 100; n++)
        loop ();
    return 0;
}

Yes, the code can work, but some of the data is incomplete.

I will include the procedure for communication with the Truck Controller that I got from the Shop Manual. Yes, the communication is request and then response.

This is output from Arduino (The Truck Is Empty And Stopped):

And, This is output from RS232 Serial Cable With App Software :

The Truck controller transmits the real-time data normally
after 0.2 seconds. If this condition is repeated 10 times, the Controller stops transmission. So I need to send command continuously to get Real Time data.

Yes, All messages format are frame with STX-ETX & BCC.

I apologize from my typo, you are right, it is 7E Not 75
(Calculation from STX-ETX)

Thanks for helping me, I'll try again.

I apologize.
Due to the time difference between our locations, I'm late in replying to your message

My search results on google, there is no code that explains. and I want to display it on the Arduino serial monitor

Here is the problem, if your posting of the message in hex is correct, the message can contain any hex number from x00 to xff and you cannot differentiate a STX or ETX from what is included in the text.
So, my solution would be to store the fixed count of bytes in an array until the count of bytes matches exactly the documented message length.
Then process the array, using only the data portion.
Then request the next message from the truck and do it all over again.
Paul

Thanks Paul for sharing the solution, I'll try to understand it first. Because, this is something new for me, I will try harder to get it.

After trying to read the fine print in what you posted for documentation, I see they correctly insert a DLE/escape character in front of any character in the text that may be interpreted as a control character, ie. STX, or ETX.
So while moving each byte you read to the array, look for a DLE character and do not store the first DLE of a pair of characters. But, if the DLE comes before a second DLE, do store the second DLE in the buffer. I know that seems complicated, and it is, but that is what we have to work with.
Paul

Thank you for explaining the code.
and this is real time data that I get when the truck in loading condition.

02 06 03 07 02 4d 32 10 02 42 10 02 47 10 03 8c 05 9f 10 03 4b 10 02 a7 10 03 00 10 02 00 00 10 03 03 8b

and I'm trying to split the result data from the truck controller, Like This :

02 06 03 07 >>>>>>>>>>>>>>>>>>>>>>> From Truck Controller
02 4d 32 10 02 >>>>>>>>>>>>>>>>>>>>> Header

42 10 02 >>>>>>>>>>>>>>>>>>>>>>>>>> Suspension Pressure (Sometime Only 2 Byte, When the load mass 0.0 Tons)
47 10 03 >>>>>>>>>>>>>>>>>>>>>>>>>> Suspension Pressure (Sometime Only 2 Byte, When the load mass 0.0 Tons)
8c 05 >>>>>>>>>>>>>>>>>>>>>>>>>>>> Suspension Pressure (Sometime Only 2 Byte, When the load mass 0.0 Tons)
9f 10 03 >>>>>>>>>>>>>>>>>>>>>>>>>>Suspension Pressure (Sometime Only 2 Byte, When the load mass 0.0 Tons)
4b 10 02 >>>>>>>>>>>>>>>>>>>>>>>>> Inclination Of The Truck (Sometime 2 or 1 Byte)
a7 10 03 >>>>>>>>>>>>>>>>>>>>>>>>> Payload (Sometime Only 2 or 1 Byte)
00 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Current Speed (only 1 byte)
10 02 >>>>>>>>>>>>>>>>>>>>>>>>>>>> DIG STST (Sometime 2 or 1 Byte)
00 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ANA 1 (only 1 byte)
00 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ANA 2 (only 1 byte)
10 03 >>>>>>>>>>>>>>>>>>>>>>>>>>> Status Of Dump Truck (Sometime Only 2 or 1 Byte)

03 8b >>>>>>>>>>>>>>>>>>>>>>>>>>> ETX & BCC

Ex: I read the Payload value:
a7 10 03 >>>>>>>>> Payloads,

I convert it to decimal, If I remove the 10 value, only A7 and 03.
then I read from the back to 03 A7,

3A7(HEX) = 935(DECIMAL)
to Decimal 1 Place = 93.5 Tons, and this is the same as shown on the truck monitor screen

Can You help Me Please.
what i need is :

  1. Split the data and select only the real time data
  2. Reading on Arduino Serial Monitor With :
    -Suspension Pressure 1:
    -Suspension Pressure 2:
    -Suspension Pressure 3:
    -Suspension Pressure 4:
    -Payload :
    -Current Speed ;
    -Dump Truck Status :

and I am very confused to split the data, because I am a newbie in this case,

here is some code that unpacks the fields based on your description

in many cases you say there is a varying number of bytes in each field. i would have thought each field has an ID byte that may imply the # of data values following. the image you posted presumably from a description of the packet doesn't explain this.

could you post a link to the description of the packet?

          from truck controller   02 06 03 07
                         header   02 4d 32 10 02
            suspension pressure   42 10 02
            suspension pressure   47 10 03
            suspension pressure   8c 05
            suspension pressure   9f 10 03
       inclination of the truck   4b 10 02
                        payload   a7 10 03
                  current speed   00
                       DIG STST   10 02
                          ANA 1   00
                          ANA 2   00
           status of dump truck   10 03

typedef unsigned char byte;

byte msg [] =  {
    0x02, 0x06, 0x03, 0x07,  0x02, 0x4d, 0x32, 0x10,
    0x02, 0x42, 0x10, 0x02,  0x47, 0x10, 0x03, 0x8c,
    0x05, 0x9f, 0x10, 0x03,  0x4b, 0x10, 0x02, 0xa7,
    0x10, 0x03, 0x00, 0x10,  0x02, 0x00, 0x00, 0x10,
    0x03, 0x03, 0x8b
};

struct Blk_s {
    int         idx;
    int         len;
    const char *desc;
};

Blk_s blks [] = {
    {  0, 4, "from truck controller" },
    {  4, 5, "header" },
    {  9, 3, "suspension pressure" },
    { 12, 3, "suspension pressure" },
    { 15, 2, "suspension pressure" },
    { 17, 3, "suspension pressure" },
 
    { 20, 3, "inclination of the truck" },
    { 23, 3, "payload" },

    { 26, 1, "current speed" },
    { 27, 2, "DIG STST" },
    { 29, 1, "ANA 1" },
    { 30, 1, "ANA 2" },
    { 31, 2, "status of dump truck" },
    {  0, 0, "" },
};

#include <stdio.h>

void
decode (
    byte *msg,
    int   nByte )
{
    Blk_s *b = blks;

    for (b = blks; 0 < b->len; b++)  {
        printf (" %30s  ", b->desc);
        for (int n = 0; n < b->len; n++)
            printf (" %02x", msg [b->idx + n]);
        printf ("\n");
    }
}


int main ()
{
    decode (msg, sizeof(msg));
    return 0;
}

Looks like

  1. 10 is used to escape 02 and 03
  2. "header" consists of STX and a pressure value

The CRC of your last example seems to be wrong.

Here is a version that removes the ESC chars and checks the CRC:

uint8_t testData[] = {
  0x02, 0x06, 0x03, 0x07, 0x02, 0x4d, 0x32, 0x10, 0x02, 0xa0, 0x01, 0x7d, 0x01, 0xc8, 0x00, 0xfa,
  0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x96, 0x02, 0x06, 0x03, 0x07,
  0x02, 0x4D, 0x32, 0x10, 0x02, 0xA0, 0x01, 0x7D, 0x01, 0xC8, 0x00, 0xFA, 0x00, 0x15, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x96, 0x02, 0x4D, 0x32, 0x10, 0x02, 0xA0, 0x01, 0x7D,
  0x01, 0xC8, 0x00, 0xFA, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x96,
  0x02, 0x06, 0x03, 0x07, 0x02, 0x4d, 0x32, 0x10, 0x02, 0x42, 0x10, 0x02, 0x47, 0x10, 0x03, 0x8c,
  0x05, 0x9f, 0x10, 0x03, 0x4b, 0x10, 0x02, 0xa7, 0x10, 0x03, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10,
  0x03, 0x03, 0x8b
};

class DummySerial {
    const uint8_t * dPtr;
    size_t dLen;
  public:
    uint8_t chkS;
    DummySerial(const uint8_t* data, size_t dataLen) : dPtr(data), dLen(dataLen), chkS(0) {
      while (dataLen--) {
        chkS ^= *data++;
      }
    }
    bool available() {
      return dLen > 0;
    }
    int16_t read() {
      if (available()) {
        dLen--;
        return *dPtr++;
      } else {
        return -1;
      }
    }
} DSerial(testData, sizeof(testData));

const uint8_t ESCIT = 0x10;
const uint8_t STX = 2;
const uint8_t ETX = 3;

const uint8_t maxMsgLen = 64;

void setup() {
  Serial.begin(115200);
  if (DSerial.chkS != 0) {
    Serial.print(F("\n***ERROR*** "));
  }
  Serial.print(F("Checksum of data is 0x"));
  Serial.println(DSerial.chkS, HEX);
  Serial.println(F("\nprocess data from DummySerial"));
}

void loop() {
  handleDSerial();
}

void oneLineReceived(const uint8_t * buffer, size_t len, bool chkOk) {
  dumpLine(buffer,  len, chkOk);
  if (len == 20) {
    lInt16at(F("Suspension 1"), buffer, 3);
    lInt16at(F("Suspension 2"), buffer, 5);
    lInt16at(F("Suspension 3"), buffer, 7);
    lInt16at(F("Suspension 4"), buffer, 9);
    lInt16at(F("Inclination"), buffer, 11);
    lInt16at(F("Payload"), buffer, 13);
    lInt8at(F("Speed"), buffer, 15);
    lInt8at(F("Dig Stst"), buffer, 16);
    lInt8at(F("ANA 1"), buffer, 17);
    lInt8at(F("ANA 2"), buffer, 18);
    lInt8at(F("Dump Truck"), buffer, 19);
  }
}

void lInt16at(const __FlashStringHelper* lab, const uint8_t* buffer, size_t pos) {
  for (size_t i = strlen_P((const char*)lab); i < 15; i++) {
    Serial.write(' ');
  }
  Serial.print(lab);
  uint16_t val = buffer[pos] + (buffer[pos + 1] << 8);
  Serial.print(F(": "));
  Serial.print(val * .1, 1);
  Serial.print(F(", "));
  Serial.print(val);
  Serial.print(F(", 0x"));
  Serial.println(val, HEX);
}

void lInt8at(const __FlashStringHelper* lab, const uint8_t* buffer, size_t pos) {
  for (size_t i = strlen_P((const char*)lab); i < 15; i++) {
    Serial.write(' ');
  }
  Serial.print(lab);
  uint16_t val = buffer[pos];
  Serial.print(F(": "));
  Serial.print(val);
  Serial.print(F(", 0x"));
  Serial.println(val, HEX);
}

void dumpLine(const uint8_t * buffer, size_t len, bool chkOk) {
  Serial.println();
  if (len < 10) {
    Serial.write(' ');
  }
  Serial.print(len);
  Serial.print(F(":"));
  while (len--) {
    Serial.write(' ');
    if (*buffer < 16) {
      Serial.write('0');
    }
    Serial.print(*buffer++, HEX);
  }
  Serial.println(chkOk ? F(" CRC ok") : F(" CRC bad"));
}

enum RxState {
  waitForSTX,
  collectUntilETX,
  waitForCRC,
};

void handleDSerial() {
  static RxState rxs = waitForSTX;
  static bool nextCharLiteral = false;
  static uint8_t chkSum;
  static uint8_t bIndex;
  static uint8_t buffer[maxMsgLen + 1];
  if (DSerial.available()) {
    uint8_t inChar = DSerial.read();
    if (nextCharLiteral) {
      chkSum ^= inChar;
      buffer[bIndex++] = inChar;
      nextCharLiteral = false;
      return;
    } else if (inChar == ESCIT) {
      chkSum ^= inChar;
      nextCharLiteral = true;
      return;
    }
    switch (rxs) {
      case waitForSTX:
        if (inChar == STX) {
          bIndex = 0;
          chkSum = inChar;
          buffer[bIndex++] = inChar;
          rxs = collectUntilETX;
        }
        break;
      case collectUntilETX:
        chkSum ^= inChar;
        buffer[bIndex++] = inChar;
        if (inChar == ETX) {
          rxs = waitForCRC;
        }
        break;
      case waitForCRC:
        buffer[bIndex++] = inChar;
        if (inChar != chkSum) {
          Serial.print(F("\ncomputed 0x"));
          Serial.print(chkSum, HEX);
          Serial.print(F(", received 0x"));
          Serial.print(inChar, HEX);
          Serial.print(F(", diff 0x"));
          Serial.print(inChar ^ chkSum, HEX);
        }
        oneLineReceived((const uint8_t *)(buffer + 1), bIndex - 3, inChar == chkSum);
        bIndex = 0;
        rxs = waitForSTX;
        break;
    }
  }
}

generating


***ERROR*** Checksum of data is 0xA

process data from DummySerial

 1: 06 CRC ok

20: 4D 32 02 A0 01 7D 01 C8 00 FA 00 15 00 00 00 00 01 00 00 01 CRC ok
   Suspension 1: 41.6, 416, 0x1A0
   Suspension 2: 38.1, 381, 0x17D
   Suspension 3: 20.0, 200, 0xC8
   Suspension 4: 25.0, 250, 0xFA
    Inclination: 2.1, 21, 0x15
        Payload: 0.0, 0, 0x0
          Speed: 0, 0x0
       Dig Stst: 1, 0x1
          ANA 1: 0, 0x0
          ANA 2: 0, 0x0
     Dump Truck: 1, 0x1

 1: 06 CRC ok

20: 4D 32 02 A0 01 7D 01 C8 00 FA 00 15 00 00 00 00 01 00 00 01 CRC ok
   Suspension 1: 41.6, 416, 0x1A0
   Suspension 2: 38.1, 381, 0x17D
   Suspension 3: 20.0, 200, 0xC8
   Suspension 4: 25.0, 250, 0xFA
    Inclination: 2.1, 21, 0x15
        Payload: 0.0, 0, 0x0
          Speed: 0, 0x0
       Dig Stst: 1, 0x1
          ANA 1: 0, 0x0
          ANA 2: 0, 0x0
     Dump Truck: 1, 0x1

20: 4D 32 02 A0 01 7D 01 C8 00 FA 00 15 00 00 00 00 01 00 00 01 CRC ok
   Suspension 1: 41.6, 416, 0x1A0
   Suspension 2: 38.1, 381, 0x17D
   Suspension 3: 20.0, 200, 0xC8
   Suspension 4: 25.0, 250, 0xFA
    Inclination: 2.1, 21, 0x15
        Payload: 0.0, 0, 0x0
          Speed: 0, 0x0
       Dig Stst: 1, 0x1
          ANA 1: 0, 0x0
          ANA 2: 0, 0x0
     Dump Truck: 1, 0x1

 1: 06 CRC ok

computed 0x81, received 0x8B, diff 0xA
20: 4D 32 02 42 02 47 03 8C 05 9F 03 4B 02 A7 03 00 02 00 00 03 CRC bad
   Suspension 1: 57.8, 578, 0x242
   Suspension 2: 83.9, 839, 0x347
   Suspension 3: 142.0, 1420, 0x58C
   Suspension 4: 92.7, 927, 0x39F
    Inclination: 58.7, 587, 0x24B
        Payload: 93.5, 935, 0x3A7
          Speed: 0, 0x0
       Dig Stst: 2, 0x2
          ANA 1: 0, 0x0
          ANA 2: 0, 0x0
     Dump Truck: 3, 0x3

1 Like

You are right that the last CRC is wrong. I'm sorry.

Your code is running very well, Tomorrow I'll be fetching real time data from an operating dump truck again. And I will attach the result.

BIG THANKS FOR YOU :star_struck: :pray:

Regards
Rusda.