Compare hex values received via serial

Hello,

I am working on a project that I was hoping to get some advice on. I am trying to read a hex string and compare the values from a radar detector. I have found all of the commands and I just need a way to compare the below packet.

The radar detector gives the following packet for a laser alert
F5 06 a9 00 00 38 5F 20

I have been able to find the following
F5 (start of every packet)
06 - packet length
A9 - Command type
00 - Frequency 1 (will populate for radar alerts)
00 - Frequency 2 (will populate for radar alerts)
38 - Band type (Laser alert in this case)
5F - Direction/strength of the signal received
20 - Dont know but does change

Basically, I want a way to story the received packet into an array starting at the F5 based on the length of the 06 byte. From there, I will compare the band type/direction and feed the data into my LCD Gauge cluster through CANBUS (Which I already have a way to do)

Does anyone have any suggestion on how I can start capturing the data at F5 based on the length of the 06? I tried to do some digging for the past couple of days but couldn't come up with anything. Any starting point would be much appreciated.

you can read complete packets and process the ones your interested in

you can read one byte at a time until you receive the "start" byte, F5. then read the length byte and continue to read that many bytes into a receive buffer. once the complete packet received process it.

that processing depends on the "command type" of the packet. undesired packets are simply discarded. of course the data from a desired packet is accessible from the receive buffer.

2 Likes

this code for an Automess does something similar (see receive())

1 Like

Look at how the serial input basics tutorial reads in a serial packet using a start marker (0xF5) and an end marker.

1 Like

Do you have a make/model?

My question is (always) if the data that you show is binary data or a hexadecimal text representation of the binary data.

How? Using some code? If so, can you show it. Or do you have the user manual / datasheet? If so, please provide a link.

That might be a CRC or checksum; probably the latter. In both cases the user manual / datasheet will tell you how to calculate so you can verify that the packet is not corrupted.

The below function looks for a start marker and next starts filling up an array of bytes; it's intended for binary receive. Note that the start marker is not stored.

// state machine states
enum BUFFERSTATE
{
  WAITSTART,
  WAITLENGTH,
  INPROGRESS,
  COMPLETE,
};

/*
  read a packet from radar
  Returns:
    >0 length of received data
    0  no complete packet yet
    -1 timeout while receiving
    -2 checksum / crc error (not implemented)
*/
int readPacket()
{
  // where to store the next byte in the radarBuffer
  static byte index;
  // indicate that we have received the start byte
  static BUFFERSTATE rcvState = WAITSTART;
  // time that last byte was received
  static uint32_t lastTime;
  // return value
  int rv = 0;

  // timeout
  if (millis() - lastTime >= timeout)
  {
    lastTime = millis();
    if (rcvState != WAITSTART)
    {
      // reset receive state
      rcvState = WAITSTART;
      // reset index
      index = 0;
      // indicate timeout to caller
      return ERR_TO;
    }
    return 0;
  }

  //if (Serial1.available() == 0)
  if (Serial.available() == 0)
  {
    // nothing to do, indicate to caller that no complete packet was received
    return 0;
  }

  // read the received byte
  //radarBuffer[index] = Serial1.read();
  radarBuffer[index] = Serial.read();
  Serial.println(radarBuffer[index], HEX);
  // update time that last byte was received
  lastTime = millis();

  // state machine
  switch (rcvState)
  {
    case WAITSTART:
      if (radarBuffer[index] == startByte)
      {
        Serial.println("started");
        rcvState = WAITLENGTH;
      }
      break;
    case WAITLENGTH:
      Serial.print("length field = "); Serial.println(radarBuffer[index], HEX);
      index++;
      rcvState = INPROGRESS;
      break;
    case INPROGRESS:
      index++;
      if (index == radarBuffer[0])
      {
        rcvState = COMPLETE;
      }
      break;
    case COMPLETE:
      Serial.println("complete");
      // verify checksum
      if (verifyCS() == false)
      {
        // set the return value
        rv = ERR_CS;
      }
      else
      {
        rv = index + 1;
      }

      // cleanup for next packet
      index = 0;
      rcvState = WAITSTART;
      break;
  }

  //indicate length / status to caller
  return rv;
}

/*
  verify checksum / crc
  Returns:
    false on mismatch, else true
*/
bool verifyCS()
{
  return true;
}

The function makes use of a finite state machine to keep track wjat is being expected (start marker, length, actual data). It also implements a timout in case a packet is 'interrupted'. verifyCS() is a place holder and currently just returns true to indicate that the packet is not corrupt. Some debug information is printed in the function; you can remove the serial print statements.

Place the below at the top of your code:

// radar receive buffer
uint8_t radarBuffer[256];
// start byte
const uint8_t startByte = 0xF5;
// timeout
const uint32_t timeout = 1000;

// receive error codes
const int ERR_TO = -1;
const int ERR_CS = -2;

You can adjust the size of the radarBuffer variable. 256 was based on the fact that the maximum length seems to be 255 (fits in a single byte); the length field plus 255 bytes equals 256. In loop(), you can use it as below

void loop()
{
  int len = readPacket();
  if (len > 0)
  {
    Serial.print("len = "); Serial.println(len);
    for (uint8_t cnt = 0; cnt < len; cnt++)
    {
      if (radarBuffer[cnt] < 0x10)
      {
        Serial.print("0");
      }
      Serial.print(radarBuffer[cnt], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
  else if (len == ERR_TO)
  {
    Serial.println("timeout while receiving");
  }
  else if (len == ERR_CS)
  {
    Serial.println("checksum / crc error");
  }
}

Note:
the code uses Serial; modify to your needs (e.g. Serial1 as shown).

// Edit
I forgot to mention that you can compare binary data using memcmp(3) - Linux manual page.

This is awesome!

I am using an escort max 360 I have connected to an old Bluetooth module. I am sniffing the data going between the two and I plan to use the Arduino in place of the Bluetooth module once I figure out which commands keep the detector satisfied and allow the communications to continue without the Bluetooth module

&

It most likely is just binary data but I have been reading it as hex packets. I used an oscilloscope to find that the data coming from the detector is an inverted ttl signal at 57.6k baud. The signals going to the detector from the bluetooth module are a standard (non inverted) ttl signal (both at 5V). I found it odd that they would invert one signal and not the other but im sure they had a reason.

Once I found out which packet created the alert and what each byte does, I paired the bluetooth module to the app and injected different hex values into the bluetooth module until I came up with all of the scenarios that I could find. Same deal with controlling it. I went through the app and sniffed each signal for the different commands

Commands to control the detector
Brightness		          Sensitivity			           ScreenColor	
F503830200	DARK	    F503830105 	Highway	          	F503831600 	Amber
F503830201	MIN	        F503830100	Auto		        F503831601	Red
F503830202	MED	        F503830100	Auto No X	        F503831602	Green
F503830203	MAX				                            F503831603	Blue
F503830204	AUTO					
						
					USER MODE	
Speed/Voltage					NOVICE	F5 03 83 1A 00
F503831700	Voltage				ADVANCED	F5 03 83 1A 01
F503831701  Speed					
F5029E01  	mute			
Display						
F503830400	Full Word					
F50383040A	Scanning Bar					
						
Meter Mode						
F503830600	Standard					
F503830604	Standard FR1					
F503830605	Standard FR2					
F503830606	Spec FR1					
F503830607	Spec FR2					
F503830608	Expert FR					
F503830603	Simple					
						
Auto Mute						
F503830700	Off					
F503830702	Low					
F503830703	Medium					
F503830704	High					

Radar Info ( Excel doesn't copy over too well but you get the idea)
start bit	Length	function (alert)	FREQUENCY1	FREQUENCY2	BAND	Direction/strength	???
F5       	06    	A9               	09       	3C  	    29       	3E  	        00
õ							
Baud Rate	57600						
							
							
BAND			Dir/Strength	DIRECTION	STRENGTH		
00	X BAND		00	NONE	1 BAR		
01	X BAND		01	NONE	1 BAR		
02	X BAND		02	NONE	1 BAR		
03	X BAND		03	NONE	1 BAR		
04	KU BAND		04	NONE	1 BAR		
05	KU BAND		05	NONE	1 BAR		
06	KU BAND		06	NONE	1 BAR		
07	KU BAND		07	NONE	2 BAR		
08	K BAND		08	NONE	2 BAR		
09	K BAND		09	NONE	2 BAR		
0A	K BAND		0A	NONE	2 BAR		
0B	K BAND		0B	NONE	2 BAR		
0C		        0C	NONE	2 BAR		
0D			    0D	NONE	3 BAR		
0E			    0E	NONE	3 BAR		
0F			    0F	NONE	3 BAR		
10	KA BAND		10	NONE	3 BAR		
11	KA BAND		11	NONE	3 BAR		
12	KA BAND		12	NONE	3 BAR		
13	KA BAND		13	NONE	4 BAR		
14	POP		    14	NONE	4 BAR		
15	POP		    15	NONE	4 BAR		
16	POP		    16	NONE	4 BAR		
17	POP		    17	NONE	4 BAR		
18	LASER		18	NONE	4 BAR		
19	LASER		19	NONE	5 BAR		
1A	LASER		1A	NONE	5 BAR		
1B	LASER		1B	NONE	5 BAR		
1C	STRELKA		1C	NONE	5 BAR		
1D	STRELKA		1D	NONE	5 BAR		
1E	STRELKA		1E	NONE	5 BAR		
1F	STRELKA		1F	NONE	5 BAR		
20	X BAND		20	FRONT	1 BAR		
21	X BAND		21	FRONT	1 BAR		
22	X BAND		22	FRONT	1 BAR		
23	X BAND		23	FRONT	1 BAR		
24	KU BAND		24	FRONT	1 BAR		
25	KU BAND		25	FRONT	1 BAR		
26	KU BAND		26	FRONT	1 BAR		
27	KU BAND		27	FRONT	2 BAR		
28	K BAND		28	FRONT	2 BAR		
29	K BAND		29	FRONT	2 BAR		
2A	K BAND		2A	FRONT	2 BAR		
2B	K BAND		2B	FRONT	2 BAR		
2C			    2C	FRONT	2 BAR		
2D			    2D	FRONT	3 BAR		
2E			    2E	FRONT	3 BAR		
2F			    2F	FRONT	3 BAR		
30	KA BAND		30	FRONT	3 BAR		
31	KA BAND		31	FRONT	3 BAR		
32	KA BAND		32	FRONT	3 BAR		
33	KA BAND		33	FRONT	4 BAR		
34	POP	       	34	FRONT	4 BAR		
35	POP		    35	FRONT	4 BAR		
36	POP		    36	FRONT	4 BAR		
37	POP	        37	FRONT	4 BAR		
38	LASER		38	FRONT	4 BAR		
39	LASER		39	FRONT	5 BAR		
3A	LASER		3A	FRONT	5 BAR		
3B	LASER		3B	FRONT	5 BAR		
3C	STRELKA		3C	FRONT	5 BAR		
3D	STRELKA		3D	FRONT	5 BAR		
3E	STRELKA		3E	FRONT	5 BAR		
3F	STRELKA		3F	FRONT	5 BAR		
40	MULTI RADAR CD		40	REAR	1 BAR		
41	MULTI RADAR CD		41	REAR	1 BAR		
42	MULTI RADAR CD		42	REAR	1 BAR		
43	MULTI RADAR CD		43	REAR	1 BAR		
44	MULTI RADAR CT		44	REAR	1 BAR		
45	MULTI RADAR CT		45	REAR	1 BAR		
46	MULTI RADAR CT		46	REAR	1 BAR		
47	MULTI RADAR CT		47	REAR	2 BAR		
48	GASTO		48	REAR	2 BAR		
49	GASTO		49	REAR	2 BAR		
4A	GASTO		4A	REAR	2 BAR		
4B	GASTO		4B	REAR	2 BAR		
4C	VG2		4C	REAR	2 BAR		
4D	VG2		4D	REAR	3 BAR		
4E	VG2		4E	REAR	3 BAR		
4F	VG2		4F	REAR	3 BAR		
50	ROBOT		50	REAR	3 BAR		
51	ROBOT		51	REAR	3 BAR		
52	ROBOT		52	REAR	3 BAR		
53	ROBOT		53	REAR	4 BAR		
54			54	REAR	4 BAR		
55			55	REAR	4 BAR		
56			56	REAR	4 BAR		
57			57	REAR	4 BAR		
58			58	REAR	4 BAR		
59			59	REAR	5 BAR		
5A			5A	REAR	5 BAR		
5B			5B	REAR	5 BAR		
5C			5C	REAR	5 BAR		
5D			5D	REAR	5 BAR		
5E			5E	REAR	5 BAR		
5F			5F	REAR	5 BAR		
60	MULTI RADAR CD		60	SIDE	1 BAR		
61	MULTI RADAR CD		61	SIDE	1 BAR		
62	MULTI RADAR CD		62	SIDE	1 BAR		
63	MULTI RADAR CD		63	SIDE	1 BAR		
64	MULTI RADAR CT		64	SIDE	1 BAR		
65	MULTI RADAR CT		65	SIDE	1 BAR		
66	MULTI RADAR CT		66	SIDE	1 BAR		
67	MULTI RADAR CT		67	SIDE	2 BAR		
68	GASTO		68	SIDE	2 BAR		
69	GASTO		69	SIDE	2 BAR		
6A	GASTO		6A	SIDE	2 BAR		
6B	GASTO		6B	SIDE	2 BAR		
6C	VG2		6C	SIDE	2 BAR		
6D	VG2		6D	SIDE	3 BAR		
6E	VG2		6E	SIDE	3 BAR		
6F	VG2		6F	SIDE	3 BAR		
70	ROBOT		70	SIDE	3 BAR		
71	ROBOT		71	SIDE	3 BAR		
72	ROBOT		72	SIDE	3 BAR		
73	ROBOT		73	SIDE	4 BAR		
74			74	SIDE	4 BAR		
75			75	SIDE	4 BAR		
76			76	SIDE	4 BAR		
77			77	SIDE	4 BAR		
78			78	SIDE	4 BAR		
79			79	SIDE	5 BAR		
7A			7A	SIDE	5 BAR		
7B			7B	SIDE	5 BAR		
7C			7C	SIDE	5 BAR		
7D			7D	SIDE	5 BAR		
7E			7E	SIDE	5 BAR		
7F			7F	SIDE	5 BAR		
80	X BAND		80				
81	X BAND		81				
82	X BAND		82				
83	X BAND		83				
84	KU BAND		84				
85	KU BAND		85				
86	KU BAND		86				
87	KU BAND		87				
88	K BAND		88				
89	K BAND		89				
8A	K BAND		8A				
8B	K BAND		8B				
8C			8C				
8D			8D				
8E			8E				
8F			8F				
90	KA BAND		90				
91	KA BAND		91				
92	KA BAND		92				
93	KA BAND		93				
94	POP		94				
95	POP		95				
96	POP		96				
97	POP		97				
98	LASER		98				
99	LASER		99				
9A	LASER		9A				
9B	LASER		9B				
9C	STRELKA		9C				
9D	STRELKA		9D				
9E	STRELKA		9E				
9F	STRELKA		9F				
A0	X BAND		A0				
A1	X BAND		A1				
A2	X BAND		A2				
A3	X BAND		A3				
A4	KU BAND		A4				
A5	KU BAND		A5				
A6	KU BAND		A6				
A7	KU BAND		A7				
A8	K BAND		A8				
A9	K BAND		A9				
AA	K BAND		AA				
AB	K BAND		AB				
AC			AC				
AD			AD				
AE			AE				
AF			AF				
B0	KA BAND		B0				
B1	KA BAND		B1				
B2	KA BAND		B2				
B3	KA BAND		B3				
B4	POP		B4				
B5	POP		B5				
B6	POP		B6				
B7	POP		B7				
B8	LASER		B8				
B9	LASER		B9				
BA	LASER		BA				
BB	LASER		BB				
BC	STRELKA		BC				
BD	STRELKA		BD				
BE	STRELKA		BE				
BF	STRELKA		BF				
C0	MULTI RADAR CD		C0				
C1	MULTI RADAR CD		C1				
C2	MULTI RADAR CD		C2				
C3	MULTI RADAR CD		C3				
C4	MULTI RADAR CT		C4				
C5	MULTI RADAR CT		C5				
C6	MULTI RADAR CT		C6				
C7	MULTI RADAR CT		C7				
C8	GASTO		C8				
C9	GASTO		C9				
CA	GASTO		CA				
CB	GASTO		CB				
CC	VG2		CC				
CD	VG2		CD				
CE	VG2		CE				
CF	VG2		CF				
D0	ROBOT		D0				
D1	ROBOT		D1				
D2	ROBOT		D2				
D3	ROBOT		D3				
D4			D4				
D5			D5				
D6			D6				
D7			D7				
D8			D8				
D9			D9				
DA			DA				
DB			DB				
DC			DC				
DD			DD				
DE			DE				
DF			DF				
E0	MULTI RADAR CD		E0				
E1	MULTI RADAR CD		E1				
E2	MULTI RADAR CD		E2				
E3	MULTI RADAR CD		E3				
E4	MULTI RADAR CT		E4				
E5	MULTI RADAR CT		E5				
E6	MULTI RADAR CT		E6				
E7	MULTI RADAR CT		E7				
E8	GASTO		E8				
E9	GASTO		E9				
EA	GASTO		EA				
EB	GASTO		EB				
EC	VG2		        EC				
ED	VG2		ED				
EE	VG2		EE				
EF	VG2		EF				
F0	ROBOT		F0				
F1	ROBOT		F1				
F2	ROBOT		F2				
F3	ROBOT		F3				
F4			F4				
F5			F5				
F6			F6				
F7			F7				
F8			F8				
F9			F9				
FA			FA				
FB			FB				
FC			FC				
FD			FD				
FE			FE				
FF			FF				



I used realterm software in hex display mode to display all of this data