[Solved] Read Serial Byte in HEX

Hello everybody,

I am trying to process a serial signal that I receive in binary (represented in Hexa): F2 40 05 65 FD 08 08 F6

This message is a measurement request that the Modem requests to several devices. It was sent in this form:

byte codeDmdMesure [] = {0xF2, 0x40, 0x05, 0x65,0xFD, 0x08, 0x08, 0xF6};

As several devices can be accessed from the Modem, I would like to extract from this message:

4005 (device id); 65 (transmit); FD0808F6 (modem id) to compare them to codes.

Ex: 4005: device # 1; 4006: device # 2; .... 4005 "oh it's me" I return my measurements to the modem:

F2 4005 75 FD 08 19 00 57 01 0A 00 17 01 AE FD 08 08 F6
id device; 75: return; data; modem id

Can you help me ?

Thank you

You "extract" data from the array by putting the array name on the right side of an equal sign, with the appropriate position in the brackets, or by passing that element to a function or operator.

   if(codeDmdMesure[1] == 0x40 && codeDmdMesure[2] == 0x05)
   {
      // The message is for little old me

   }

Thanks for answer,

i must "serial read " and stock first, before "extract" F2 40 05 65 FD 08 08 F6
How ?

How ?

I don't know. Maybe use the Serial.read() function, after you've use Serial.available() to determine how much data there is to read.

to start I would like to store the incomming message :

const byte numBytes = 8;
byte receivedBytes[numBytes];

Is it a good start ?

Is it a good start ?

If those are global variables, yes.

i could read F2 40 05 65 FD 08 08 F6 or F2 40 06 65 FD 08 08 F6 that's why i must extract for "id device " and respond the good mesurements

how could i use while (Serial1.available() to store message incomming F2 40 05 65 FD 08 08 F6 in a variable ?

superninja:
to start I would like to store the incomming message :

const byte numBytes = 8;

byte receivedBytes[numBytes];



Is it a good start ?

Who can tell without seeing the complete program.

It is not clear to me if "F2 40 05 65 FD 08 08 F6" is the complete message or if it is just the part you are interested in.

Does the message have regular start- and end-markers?

If not, how do you determine where a message starts and ends?

...R
Serial Input Basics - simple reliable ways to receive data.

how could i use
Code: [Select]

while (Serial1.available()

to store message incomming F2 40 05 65 FD 08 08 F6 in a variable ?

byte variable[80];
byte index = 0;

void loop()
{
   while(Serial.available() > 0)
   {
      byte b = Serial.read();
      variable[index++] = b;
   }

   // If you got a whole packet, use it and reset index to 0
}

Now, you will see that the problem is determining whether the array contains a whole packet and nothing but one packet.

If every packet starts with 0xF2, then you wouldn't store the byte in the array until you had received the 0xF2.

If every packet is the same size, you'd exit the while loop when all the data for a packet had arrived, even if the buffer wasn't empty.

@Robin2 i know and use your great tutorial for many other project and thank to you !

But in this project , about solar panel & monitoring meter, the modem talk to solar panel F2 40 05 65 FD 08 08 F6 every 5sec. See 4005 : solar panel ID; and FD0808F6 : Modem ID

The solar panel respond F2 4005 75 FD 08 19 00 57 01 0A 00 17 01 AE FD 08 08 F6 where see Solar panel ID : 4005 and modem ID FD0808F6

Its seems to be allaways 8 Bytes , got Start And End maker , but not < or > characters but 0xF2 ....and 0xFD0808F6

the goal is to extract this protocole to use with other cloud Data like thingSpeak or other:

So i must read the serial message + extract IDs

If the start marker is 0xF2 and the end marker is 0xF6 then put those in my 3rd example and it should work.

You will probably also need to change the datatypes from char to byte.

...R

PaulS:
Now, you will see that the problem is determining whether the array contains a whole packet and nothing but one packet.

i test your code :

byte variable[80];
byte index = 0;
//===================================
//=              SETUP              =
//===================================
void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  delay(3000);
  Serial.println("+++ Search ID +++");
} // FIN de setup
//===================================
//=              LOOP               =
//===================================
void loop() {
  while (Serial1.available() > 0) {
    byte b = Serial1.read();
    variable[index++] = b;
  }
  if (index == 8) {
    Serial.print("variable 0: "); Serial.println(variable[0], HEX);
    Serial.print("variable 1: "); Serial.println(variable[1], HEX);
    Serial.print("variable 2: "); Serial.println(variable[2], HEX);
    Serial.print("variable 3: "); Serial.println(variable[3], HEX);
    Serial.print("variable 4: "); Serial.println(variable[4], HEX);
    Serial.print("variable 5: "); Serial.println(variable[5], HEX);
    Serial.print("variable 6: "); Serial.println(variable[6], HEX);
    Serial.print("variable 7: "); Serial.println(variable[7], HEX);

    Serial.print("Search Device ID 4005 (#1+2): "); Serial.print((variable[1] + variable[2]), HEX);
    if (variable[1] == 0x40 && variable[2] == 0x05) {
      Serial.println("  ID searched OK");

    }
    else Serial.println("  ID searched NO OK");

    index = 0;
    Serial.println(' ');
  }

}

The first message is matched :

+++ Search ID +++
variable 0: F2
variable 1: 40
variable 2: 5
variable 3: 65
variable 4: FD
variable 5: 8
variable 6: 8
variable 7: F6
Search Device ID 4005 (#1+2): 45  ID searched OK

That's sound very good !!

Robin2:
If the start marker is 0xF2 and the end marker is 0xF6 then put those in my 3rd example and it should work.

You will probably also need to change the datatypes from char to byte.

...R

I test your 3rd example : If an other solar panel reply to the modem, somewhere, there will be probably a 0xF6 in data :confused: so , the ideal would be to look at what happens between start: 0xF2 and the end: 0xFD0808F6

i'm near from the goal but i got an issue with byte lenth .... this is the result :

byte startMarker = 0xF2;   
byte endMarker = 0xFD0808F6;  <----------------- warning: large integer implicitly truncated to unsigned type 

Rx (HEX): 40 5 65 FD 8 8 
Byte START: F2      <------ good !
Byte 0: 40            ok
Byte 1: 5              ok
Byte 2: 65            ok
Byte 3: FD    
Byte 4: 8
Byte 5: 8
Byte END: F6     <------------ ISSUE: i think is lenth of byte problem: How to read END marker FD0808F6    ?

the code :

byte startMarker = 0xF2;  
byte endMarker = 0xFD0808F6;

const byte numBytes = 10;
byte receivedBytes[numBytes];
byte numReceived = 0;
boolean newData = false;
//===================================
//=              SETUP              =
//===================================
// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);//moniteur serie
  Serial1.begin(9600);//reception wireless
  delay(3000);  //delai pour ouvrir COM8 apres televersement
  //========== LED =========
  pinMode(ledInt, OUTPUT);
  digitalWrite(ledInt, HIGH);// Éteindre la LED
  Serial.println(F("+++ RxBinaryData +++"));

} // FIN de setup
//===================================
//=              LOOP               =
//===================================
void loop() {

  recvBytesWithStartEndMarkers();
  showNewData();


} //FIN de loop
//=================================================================================
//======================    AUTRES FONCTIONS     ==================================
//================================================================================
void recvBytesWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;

  byte rb;

  while (Serial1.available() > 0 && newData == false) {//Rx:  F2 40 05 65 FD 08 08 F6
    rb = Serial1.read();

    if (recvInProgress == true) {
      if (rb != endMarker) {
        receivedBytes[ndx] = rb;
        ndx++;
        if (ndx >= numBytes) {
          ndx = numBytes - 1;
        }
      }
      else {
        receivedBytes[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        numReceived = ndx;  // save the number for use when printing
        ndx = 0;
        newData = true;
      }
    }//FIN de recinprogress true

    else if (rb == startMarker) {
      recvInProgress = true;
    }
  }//FIN de while serial1
}// FIN DE FONCTION
//================================================================================
void showNewData() {
  if (newData == true) {
    Serial.print("Rx (HEX): ");
    for (byte n = 0; n < numReceived; n++) {
      Serial.print(receivedBytes[n], HEX);
      Serial.print(' ');
    }//FIN de serial print N Bytes


    //pr2: display Bytes
    ///*
    Serial.print("\nByte START: "); Serial.print(startMarker, HEX); 
    Serial.print("\nByte 0: "); Serial.print(receivedBytes[0], HEX);
    Serial.print("\nByte 1: "); Serial.print(receivedBytes[1], HEX); 
    Serial.print("\nByte 2: "); Serial.print(receivedBytes[2], HEX); 
    Serial.print("\nByte 3: "); Serial.print(receivedBytes[3], HEX); 
    Serial.print("\nByte 4: "); Serial.print(receivedBytes[4], HEX); 
    Serial.print("\nByte 5: "); Serial.print(receivedBytes[5], HEX);
    Serial.print("\nByte END: "); Serial.println(endMarker, HEX);
    //*/

    Serial.println();
    newData = false;
  }//FIN de new data true
}// FIN DE FONCTION

IN RESUME i want :

when see 0xF2 :
begin to read ..... and count number of Bytes ....
when see 0xFD0808F6 :
stop reading + store the data between 0xF2 and 0xFD0808F6 on a variable "Data", + the lenght of the "Data" in a variable "NumberOfBytes" ...... That will be greaaat !!

From the code in Reply #13 ...

This is nonsense

byte endMarker = 0xFD0808F6;

You are trying to stuff 4 bytes into 1 byte.

If the endMarker is 0xF6 the correct code would be

byte endMarker = 0xF6;

...R

Robin2:
From the code in Reply #13 ...

This is nonsense

byte endMarker = 0xFD0808F6;

You are trying to stuff 4 bytes into 1 byte.

If the endMarker is 0xF6 the correct code would be

byte endMarker = 0xF6;

...R

Yes i know the mistake , it's for example i put 0xFD0808F6 .

how should i declare endMarker to accept and detect 0xFD0808F6 ( instead of 0xF6 ) at the end of the incomming message ?

superninja:
how should i declare endMarker to accept and detect 0xFD0808F6 ( instead of 0xF6 ) at the end of the incomming message ?

I don't understand why that is necessary. Why isn't oxF6 sufficient?

...R

Robin2:
I don't understand why that is necessary. Why isn't oxF6 sufficient?

...R

Because if there is a 0xF6 in the data reply mesurements from the solar panel , what's happen ? the message will be cutted before the real 0xF6 endMarker ?

superninja:
Because if there is a 0xF6 in the data reply mesurements from the solar panel , what's happen ? the message will be cutted before the real 0xF6 endMarker ?

Gimme a break here...

You are the one who led me to believe that 0xF6 is the end marker.

If it cannot be used as an end-marker then how do you know when a message finishes? Perhaps there is a minimum time interval between messages?

...R

Robin2:
You are the one who led me to believe that 0xF6 is the end marker.

Sorry for the confusion: :-[

the modem requests a measurement for each device:
F2 40 05 65 FD 08 08 F6
F2 40 06 65 FD 08 08 F6 ... It is correct to say: F2 = start; F6 = End

BUT:

Each device responds to the modem their measurement:
F2 4005 75 FD 08 19 00 57 01 0A 00 17 01 AE FD 08 08 F6
F2 4006 75 FD 08 19 00 F6 01 0F 00 24 01 AE FD 08 08 F6 .... It's correct to say: F2 = start; but there is a F6 somwhere, in the data message from device 4006!

How will the modem understand this?