Receiving 8 byte hex through serial

Good evening all.
I`m trying to receive the following serial communication from a device.
The device sents hex of a value of AA 78 0 1 CC 33 C3 3C or AA 78 0 0 CC 33 C3 3C depending on what page I am on.

Using the code below:

const unsigned int MAX_MESSAGE_LENGTH = 12;

void setup() {
 Serial.begin(115200);
 Serial3.begin(115200);
}

void loop() {
 
 //Check to see if anything is available in the serial receive buffer
 while (Serial3.available() > 0)
 {
   //Create a place to hold the incoming message
   static char message[MAX_MESSAGE_LENGTH];
   static unsigned int message_pos = 0;

   //Read the next available byte in the serial receive buffer
  char inByte = Serial3.read();

   //Message coming in (check not terminating character) and guard for over message size
   if ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1) )
   {
     //Add the incoming byte to our message
     message[message_pos] = inByte;
     message_pos++;
   }
   //Full message received...
   else
   {
     //Add null character to string
     message[message_pos] = '\0';
     

     //Print the message (or do other things)
    
    Serial.println(message);

     //Reset for the next message
     message_pos = 0;
   }
 }
}

I get:
3�<�x
y
3�<�y
x
3�<�x
y
3�<�y
x
3�<�x
y
3�<�y
x

This obviously isn`t what the display sent
It was suggested before that we cannot create string because the of the "0" in the code which is read as terminator.

My question is:
How can I receive an array / string from the HEX Serial message mentioned above so that the serial receive match what the display sent?

Thanks in advace.

Is the '0' the ASCII code for 0 or 0x30 or is it NULL, the string terminator (0x00). If the data is coming in over the serial port it may be ASCII data so the '0' will be 0x30.

The serial input basics tutorial may be of interest.

i assume the first several bytes in the message are always the same are provide a way to synchronize the receiver to the data stream. what happens if the receiver starts when half a message has already sent.

and unless the message size is always fixed, either something in the msg header indicates the size of the message or the message type implies the size.

This isn't fully clear but datasheet states that it's hex therefore it will be 0x00 to my understanding.

Why did you create a new post?

Correct. It is being stated that AA... CC 33 C3 3C is a part of message.
AA is the start and the CC 33 C3 3C is the end.

The other one said it was solver and suggested to create new with clear description of the need. Should I delete this and carry on with the old one?

Ok then if it’s clear the other one is closed (advices were already provided there)

consider

output

0 AA 78 2 3 CC 33 C3 3C
processMsg:  AA 78 2 3 CC 33 C3 3C
 AA 78 4 5 CC 33 C3 AA
processMsg: tail mismatch
 75 2 3 CC 33 C3 3C AA 79 2 3 CC 33 C3 3C
processMsg:  AA 79 2 3 CC 33 C3 3C
 1 AA 72 4 5 6 7 CC 33 C3 3C
processMsg:  AA 72 4 5 6 7 CC 33 C3 3C
 AA 73 9 8 7 6 CC 33 C3 3C
processMsg:  AA 73 9 8 7 6 CC 33 C3 3C

simulation code


byte data [] = {
    0,
    0xAA, 0x78, 2, 3, 0xCC, 0x33, 0xC3, 0x3C,
    0xAA, 0x78, 4, 5, 0xCC, 0x33, 0xC3,
    0xAA, 0x75, 2, 3, 0xCC, 0x33, 0xC3, 0x3C,
    0xAA, 0x79, 2, 3, 0xCC, 0x33, 0xC3, 0x3C,
    1,
    0xAA, 0x72, 4, 5, 6, 7, 0xCC, 0x33, 0xC3, 0x3C,
    0xAA, 0x73, 9, 8, 7, 6, 0xCC, 0x33, 0xC3, 0x3C,
};
unsigned idx;

char s [80];

// -----------------------------------------------------------------------------
int
dataAvailable (void)
{
    return idx < sizeof(data);
}

// -------------------------------------
byte
dataRead (void)
{
    if (idx < sizeof(data))
        return data [idx++];
    return 0;
}

// -----------------------------------------------------------------------------
const byte Tail [] = { 0xCC, 0x33, 0xC3, 0x3C };
#define Ntail  sizeof(Tail)

void
processMsg (
    byte     *buf,
    unsigned  nByte )
{
    Serial.print ("\nprocessMsg: ");

    for (unsigned i = 0; i < Ntail; i++)  {
        sprintf (s, " %d, 0x%02x 0x%02x", i, buf [nByte - Ntail + i], Tail [i]);
     // Serial.println (s);

        if (buf [nByte - Ntail + i] != Tail [i])  {
            Serial.println ("tail mismatch");
            return;
        }
    }

    for (unsigned i = 0; i < nByte; i++)  {
        Serial.print (" ");
        Serial.print (buf [i], HEX);
    }
    Serial.println ();
}


// -------------------------------------
byte buf [80];
unsigned  bufIdx;

void loop ()
{
    static unsigned msgSize;

    if (dataAvailable ()) {
        byte b = dataRead ();

        Serial.print (" ");
        Serial.print (b, HEX);

        if (0 == bufIdx && 0xAA == b)
            buf [bufIdx++] = b;
        else if (1 == bufIdx)  {
            buf [bufIdx++] = b;

            switch (b)  {
            case 0x72:
            case 0x73:
                msgSize = 10;
                break;
            case 0x78:
            case 0x79:
                msgSize = 8;
                break;
            default:
                Serial.println ("\nloop: invalid msg type");
                bufIdx = 0;     // reset
                break;
            }
        }

        else if (bufIdx < msgSize)  {
            buf [bufIdx++] = b;

            if (bufIdx == msgSize)  {
                processMsg (buf, bufIdx);
                msgSize = bufIdx = 0;
            }
        }
    }
}

void setup()
{
    Serial.begin (115200);
}

In your previous thread https://forum.arduino.cc/t/decoding-serial-to-usefull-data/1071536 and in this one, you have been pointed at the Serial Input Basics tutorial.

Have your tried using AA as the start marker and read 8 bytes?

Because of the embedded 0 in the data, you will need to print out the received message byte by byte in hex and not use .print( ) for the entire message.

// Example to receive data with a start marker and 8 bytes of data

const byte startMarker = 0xAA;
const byte messageLength = 8;
byte receivedBytes[messageLength + 1]; //include start marker
boolean newData = false;

void setup() {
 
 Serial.begin(115200);
 Serial3.begin(115200);
 Serial.println("<Arduino is ready>");
}

void loop() {
  recvBytesWithStartMarker();
  showNewData();
}

void recvBytesWithStartMarker() {
  static boolean recvInProgress = false;
  static int ndx = 0;
  byte rc;

  while (Serial3.available() > 0 && newData == false) {
    rc = Serial3.read();

    if (recvInProgress == true) {
      receivedBytes[ndx] = rc;
      ndx++;
      if (ndx == messageLength+1 ) {
        newData = true;
        recvInProgress = false;
        ndx = 0;
      }
    }
    else if (rc == startMarker) {
      recvInProgress = true;
      ndx = 0; // save start marker
      receivedBytes[ndx] = rc;
      ndx++;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.println("This just in ... ");
    for (byte i = 0; i <= messageLength; i++)
    {
      Serial.println(receivedBytes[i], HEX);
    }
    newData = false;
  }
}

I must admint i wasn`t paying a lot of attention to the SERIAL INPUT BASICS which i am sorry for.

Did some playing around, and your proposal didn`t returned much other than what basic serial.read() does.
The result from your code is:
This just in ...

AA
79
0
1
CC
33
C3
3C
AA

However, I used the code which is on the reference page with 0xAA as start and 0x3C as end:

// Example 3 - Receive with start- and end-markers

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

void setup() {
    Serial.begin(115200);
    Serial3.begin(115200);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = 0xAA;
    char endMarker = 0x3C;
    char rc;
 
    while (Serial3.available() > 0 && newData == false) {
        rc = Serial3.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

And the result is (i think) "y" for touch, "x" for release which makes me even more confused.

This just in ... y
This just in ... x

Any thoughts?

That's because that is what the message is
AA 79 0 1 CC 33 C3 3C
I'm clear about the trailing AA in what you posted, but there may be an extra byte being read so that you are seeing the start of the next message.
Try and change this line.

//if (ndx == messageLength+1 ) 
 if (ndx == messageLength ) {

I used the code which is on the reference page with 0xAA as start and 0x3C as end:

This will work if 0x3C is never part of the data stream.

And the result is (i think) "y" for touch, "x" for release which makes me even more confused.

This just in ... y
This just in ... x

You can not print out the received message array using Serial.print because of the embedded 0 and the fact that you have other non printable characters. You will have to print out the results byte by byte in HEX.

The 'x' and the 'y' are 0x78 and 0x79 and from you posted data sheet link they are some sort of command code.

What are you trying to extract from the data.
AA 79 0 1 CC 33 C3 3C

I though you wanted to extract a page integer from bytes 3 and 4.

What are you trying to extract from the data.
Byte 3 and 4 is page id (00 01 so that page id can have 9999 number as max) which in this example I am trying to get. However, my goal would be to recveive the whole message in format as AA7901CC33C33C and then treat this with just simple if statement.
Would some sort convrsion to text could take place from what we get?

The dispalay can forward much more commands with AA....CC33C33C as start and finis with different commands mostly starting AA CMD 00 end.

//if (ndx == messageLength+1 ) if (ndx == messageLength ) {

Changed const byte messageLength = 7; so the result is now ok.

Why do you think that the max page number is 9999?
Are the page numbers always positive?

The index numbers start at 0, so To combine bytes 2 and 3 into a single integer you would do
int myPageNumber = (receivedBytes[2] <<8) + receivedBytes[3];

You assigning page number manually. Basically bitmap number is a page number. 0,1,2 and so on.
I think i could just name the page1111 and go from their, however are other functions that preaty much always contain 0 so a bit of pain.
I`ve reattached datasheet just for reference.
T5L_TA-AIoT-LCM-Platform-Instruction-Screen-Development-Guide.pdf (1.9 MB)

I think combining is the way to go in this case.
What does the <<8 mean?

Bitshift left by 8 to make the received byte the high byte of the 16 bit combined integer.

It's the same as multiplying by 256.

Awesome, Thanks for a good lesson.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.