- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I am currently working in making a receiver for an RC car. I already configured the transmitter to send 2 bytes of data using the UART_PutArray function. Now I am trying to read these values on the receiver. The problem is that I do not know how to read more than one byte incoming from the transmitter into the receiver. Would anyone have any idea?
P.S these bytes of data are commands for moving forward and moving sideways.
Thanks
Solved! Go to Solution.
- Labels:
-
PSoC 5 Device Programming
-
PSoC 5LP
- Tags:
- serial comm
- uart
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So, I modified my sample and made a couple of projects.
=== transmitter ===
schematic
ADC config
Note: In my experience, if I used Fee running, I got surprising value(s) time to time.
So I use Software trigger.
If you need to use a couple of ADCs, probably you need to use Hardware trigger for both ADCs
and feed trigger from another component like ControlReg to both socs.
main.c
======================
#include "project.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#define STR_LEN 32
char str[STR_LEN+1] ; /* print buffer */
void init_hardware(void)
{
CyGlobalIntEnable ; /* Enable global interrupts */
UART_Terminal_Start() ;
UART_Start() ;
ADC_Start() ;
}
int main(void)
{
uint16_t x, y ;
init_hardware() ;
for (;;) {
ADC_StartConvert() ;
ADC_IsEndConversion(ADC_WAIT_FOR_RESULT) ;
x = ADC_GetResult16(0) ;
y = ADC_GetResult16(1) ;
snprintf(str, STR_LEN, "%04X,%04X\n", x, y) ;
UART_PutString(str) ;
CyDelay(50) ; /* 50ms, 20 samples / seconds */
}
}
======================
=== receiver ===
Note: I use my "tty_utils" utility to make receiving easier.
schematic
main.c
===================
#include "project.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "tty_utils.h"
void SYS_INIT(void)
{
UART_Terminal_Start() ;
tty_init() ; /* UART_Start() was called inside this*/
}
int main(void)
{
uint16_t x, y ;
CyGlobalIntEnable ; /* Enable global interrupts */
SYS_INIT() ;
splash("Receiver Test") ;
for (;;) {
if (get_line()) { /* receiver got a line of data */
sscanf(str, "%hX,%hX", &x, &y) ;
snprintf(str, STR_BUF_LEN, "Received: %04X %04X\n", x, y) ;
UART_Terminal_PutString(str) ;
}
}
}
===================
Note:
You need to change pins according to your system.
This time projects are compile-able, but have not been tested as I have only 1 CY8CKIT-059.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CaDu,
It may seem strange that there is a PutArray() but not a Get Array() for the UART, all UART data for Tx or Rx is by one byte at a time.
Using the GetRxBufferSize() and GetByte() API calls, you could create your own GetArray() function. I haven't tested it but here's the start of such a function. Note: This function is designed as a blocking function. If you need a non-blocking type, it would have to be significantly rewritten.
/*******************************************************************************
* Function Name: UART_GetArray
********************************************************************************
*
* Summary:
* Reads UART RX data and fills the array with the desired byte count.
* If the desired byte count not received this function may hang.
* THIS IS A BLOCKING FUNCTION.
*
* Parameters:
* uint8 rx_array[]
* uint8 rx_count desired count of received data.
* This count cannot exceed the rx_array size.
*
* Return:
* Rx status.
* If Rx status is 0 then the rx_array contains the desired data
* If Rx status is not 0 then the rx_array may contain partial data.
*
* Reentrant:
* No.
*
*******************************************************************************/
uint8 UART_GetArray(uint8 rx_array[], uint8 rx_count)
{
uint8 incoming_cnt;
uint16 rx_data;
uint8 rx_status = 0;
for(incoming_cnt = 0; incoming_cnt < rx_count; incoming_cnt++)
{
while(UART_GetRxBufferSize() == 0); // There is no data available in the Rx Buffer, then loop
// Rx data available
rx_data = UART_GetByte();
rx_array[incoming_cnt] = (uint8)(rx_data & 0xFF); // strip out incoming data and put in array
rx_status = rx_data >> 8; // strip out potential error status
if(rx_status != 0) break; // break out of for() if error occurred.
}
return(rx_status);
}
// code frag in application
#define SZ_OF_EXPECTED_RESPONSE 2
uint8 rcvd_data[SZ_OF_EXPECTED_RESPONSE];
void Your_App()
{
uint8 rx_error;
...
rx_error = UART_GetArray(rcvd_data, sizeof(rcvd_data));
if(rx_error) Fault_Recovery()
...
}
Because this is a blocking function, if you do not receive the requested number of bytes, the function will hang. You can modify the code to have a max timeout to prevent a "hang". This is probably preferred.
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I will attempt this code and give you feedback on whether it worked.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey, the code did not work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CaDu,
Sorry it didn't work. Are you willing to share your project with the forum? It's possible if we can reproduce the problem, we can solve it.
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well the code I had written for the receiver was pretty much just what you gave me.
Another question, the Rx_GetBufferSize commands should return the number of bytes being sent correct? Because whenever I read it and send it to the UART to be reprinted, it returns a 1 (Which should actually be a 2).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CaDu,
Rx_GetBufferSize() only returns the number of bytes received not transmitted. If you transmit 2 bytes on one end using PutArray(), you will receive two bytes at the other end. However, if you use Rx_GetBufferSize() often, you will get a count of 1 byte twice. Remember, the UART component is a serial data device. It sends one bit of one byte at a time. If the other end (Rx-side) is constantly reading the incoming data, it will see ONE BYTE at a time therefore giving you the Rx_GetBufferSize() = 1. To receive two bytes, you will see the Rx_GetBufferSize() = 1 twice.
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not reading the number of bytes at the receiver, I am reading them at the transmitter. That being said, how would I read the two bytes if RX is constantly replacing the current byte with another one?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
> That being said, how would I read the two bytes if RX is constantly replacing the current byte with another one?
I thought my program can take care of that situation.
But meantime, I was wondering how we could detect separation of each data?
Isn't there any delimiter or time space between the 2-bytes data?
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is no delimiter, I am sending the array from the transmitter with the following code:
#include "project.h"
#include<math.h>
#include <stdio.h>
char string[20];
uint8_t X;
uint8_t Y;
uint8_t Data_Out[3];
void init_hardware(void)
{
CyGlobalIntEnable;
UART_Start();
ADC_SAR_0_Start();
ADC_SAR_1_Start();
}
int main(void)
{
init_hardware() ;
ADC_SAR_0_StartConvert();
ADC_SAR_1_StartConvert();
for(;;)
{
X=ADC_SAR_0_GetResult8();
Y=ADC_SAR_1_GetResult8();
Data_Out[0]=X;
Data_Out[1]=Y;
//UART_WriteTxData(X);
UART_PutArray(Data_Out,2);
}
}
Your code managed to read one of the bytes, but for some reason both elements were being populated with the same byte.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
So how fast must you send data?
Your transmitter loop seems to be very fast since it does not have any delay between UART_PutArray().
As my program is using PutString() to display the value, it won't be able to catch up with your transmitter.
And IMHO, dropping a byte or two would be quite popular with radio, so the receiver needs to have a chance to re-sync.
If by accident one byte is dropped, the values will be always Y,X, until next drop, so I put delimiter X,Y,D.
As I wrote in my previous response, you are free to design any format.
But if you decide to send pure binary stream, which is continuous UART_PutArray(),
my poor capability can not come up with a solution to handle it correctly in the receiver side.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
If you don't mind modifying the line of your transmitter program
UART_PutArray(Data_Out,2);
with
snprintf(string, 20, "%04X,%04X\n", x, y) ;
UART_PutString(string) ;
CyDelay(100) ;
or
snprintf(string, 20, "%04X,%04X\n", x, y) ;
UART_PutArray(string, strlen(string)) ;
CyDelay(100) ;
Then I think that the receiver part of my previous post should work (fingers crossed).
Note: Please use P3[6] and P3[7] as receiver's rx and tx.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So, I modified my sample and made a couple of projects.
=== transmitter ===
schematic
ADC config
Note: In my experience, if I used Fee running, I got surprising value(s) time to time.
So I use Software trigger.
If you need to use a couple of ADCs, probably you need to use Hardware trigger for both ADCs
and feed trigger from another component like ControlReg to both socs.
main.c
======================
#include "project.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#define STR_LEN 32
char str[STR_LEN+1] ; /* print buffer */
void init_hardware(void)
{
CyGlobalIntEnable ; /* Enable global interrupts */
UART_Terminal_Start() ;
UART_Start() ;
ADC_Start() ;
}
int main(void)
{
uint16_t x, y ;
init_hardware() ;
for (;;) {
ADC_StartConvert() ;
ADC_IsEndConversion(ADC_WAIT_FOR_RESULT) ;
x = ADC_GetResult16(0) ;
y = ADC_GetResult16(1) ;
snprintf(str, STR_LEN, "%04X,%04X\n", x, y) ;
UART_PutString(str) ;
CyDelay(50) ; /* 50ms, 20 samples / seconds */
}
}
======================
=== receiver ===
Note: I use my "tty_utils" utility to make receiving easier.
schematic
main.c
===================
#include "project.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "tty_utils.h"
void SYS_INIT(void)
{
UART_Terminal_Start() ;
tty_init() ; /* UART_Start() was called inside this*/
}
int main(void)
{
uint16_t x, y ;
CyGlobalIntEnable ; /* Enable global interrupts */
SYS_INIT() ;
splash("Receiver Test") ;
for (;;) {
if (get_line()) { /* receiver got a line of data */
sscanf(str, "%hX,%hX", &x, &y) ;
snprintf(str, STR_BUF_LEN, "Received: %04X %04X\n", x, y) ;
UART_Terminal_PutString(str) ;
}
}
}
===================
Note:
You need to change pins according to your system.
This time projects are compile-able, but have not been tested as I have only 1 CY8CKIT-059.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code I am currently trying is the following:
/* ========================================
*
* Copyright YOUR COMPANY, THE YEAR
* All Rights Reserved
* UNPUBLISHED, LICENSED SOFTWARE.
*
* CONFIDENTIAL AND PROPRIETARY INFORMATION
* WHICH IS THE PROPERTY OF your company.
*
* ========================================
*/
#include "project.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
uint8_t Bytes_In[2];
uint8_t Data_In;
CY_ISR(RX_Handler){
int i = 0;
for(i=0; i<=1;i++){
Bytes_In= UART_GetByte();
}
UART_ClearRxBuffer();
}
void SYS_INIT(void){
UART_Start();
UART_Terminal_Start();
RX_ISR_Start();
}
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
SYS_INIT();
RX_ISR_StartEx(RX_Handler);
UART_SetRxInterruptMode(UART_RX_STS_FIFO_NOTEMPTY);
for(;;)
{
UART_Terminal_WriteTxData(Bytes_In[1]);
CyDelay(1000);
}
}
/* [] END OF FILE */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I modified your code for CY8CKIT-059.
Schematic
UART_Terminal
UART
Pins
main.c
===============
#include "project.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#define STR_LEN 32
#define NUM_TO_RECEIVE 2
uint8_t Bytes_In[NUM_TO_RECEIVE] ;
volatile int in_index = 0 ;
volatile int data_received = 0 ;
char str[STR_LEN+1] ; /* print buffer */
uint8_t Data_in ;
CY_ISR(RX_Handler)
{
while(UART_GetRxBufferSize()) {
Bytes_In[in_index] = UART_GetByte() ;
in_index++ ;
if (in_index >= NUM_TO_RECEIVE) {
data_received = 1 ;
in_index = 0 ;
break ;
}
}
UART_ReadRxStatus() ; // this clears interrupt flag
}
void SYS_INIT(void)
{
UART_Terminal_Start() ;
// UART_SetRxInterruptMode(UART_RX_STS_FIFO_NOTEMPTY); // this should come before StartEx()
RX_ISR_StartEx(RX_Handler);
UART_Start() ;
}
void cls(void)
{
UART_Terminal_PutString("\033c") ; /* reset */
CyDelay(100) ;
UART_Terminal_PutString("\033[2J") ; /* clear screen */
CyDelay(100) ;
}
void splash(void)
{
cls() ;
UART_Terminal_PutString("UART 2Bytes Test ") ;
snprintf(str, STR_LEN, "(%s %s)\n", __DATE__, __TIME__) ;
UART_Terminal_PutString(str) ;
}
int main(void)
{
CyGlobalIntEnable ; /* Enable global interrupts */
SYS_INIT() ;
splash() ;
for (;;) {
if (data_received) {
snprintf(str, STR_LEN, "%02X%02X\n", Bytes_In[0], Bytes_In[1]) ;
UART_Terminal_PutString(str) ;
data_received = 0 ;
}
}
}
===============
TeraTerm log UART (local echo on)
TeraTerm log UART Terminal
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey, thank you, I tried the code, however it does not seem to be reading the incoming data from the joystick correctly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
> Hey, thank you, I tried the code,
> however it does not seem to be reading the incoming data from the joystick correctly.
I won't be surprised as I did not know the data format your joystick generates.
In case if you connect your joystick to my program, what was the outcome?
(Note: Please configure the baud rate etc to match the device)
And/or is there data format specification of the joystick? (at least model number/name?)
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The baud rate is the same, I just changed the code on mine since the top designs were the same. The Joystick is a simple potentiometer being read into an ADC and writeen into the UART. I am able to send the data by itself (instead of arrays). It is just that I need to send both X and Y values of the ADC readings.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So if I understand correct
(1) Transmitter
(1.1) Read 2 potentiometer values (X and Y) from ADC
(1.2) Write them to UART
(2) Receiver
(2.1) read 2 data from UART
...
Then what is the data you write to UART?
I think each value should be 12bit or so, right?
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So I understand that this is a busy morning.. 😉
IMHO, you must define the format between transmitter and receiver.
Only sending stream of binary data will be very difficult for the receiver to understand.
So in the following sample I assumed the transmitter format is
<Hex Value X>,<Hex Value Y>'\n' i.e. "0120,1212\n"
This makes it easy for the receiver to detect the end of record, which is a new line char '\n'
(You can design any format as far as you can or are willing to manage.)
I modified my sample using my tty utils and added a transmitter emulator,
so the schematic is now
Pin list
main.c
==========================
#include "project.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "tty_utils.h"
#define SEND_BUF_LEN 16
char send_buf[SEND_BUF_LEN] ;
int data_sent = 0 ;
void SYS_INIT(void)
{
UART_Terminal_Start() ;
tty_init() ; /* UART_Start() was called inside this*/
transmitter_Start() ;
}
int main(void)
{
uint16_t t_x = 0 ;
uint16_t t_y = 1023 ;
uint16_t r_x, r_y ;
CyGlobalIntEnable ; /* Enable global interrupts */
SYS_INIT() ;
splash("Receiver Test") ;
for (;;) {
// emulate the transmitter
if (data_sent == 0) {
t_x = (t_x + 1) % 2048 ; /* emulated ADC value */
t_y = (t_y + 3) % 2048 ; /* emulated ADC value */
snprintf(send_buf, SEND_BUF_LEN, "%04X,%04X\n", t_x, t_y) ;
transmitter_PutString(send_buf) ;
print("Transmitted: ") ;
print(send_buf) ;
data_sent = 1 ; /* since we use only 1 cpu here, let it wait */
CyDelay(1000) ; /* to slower the terminal output */
}
// emulate the reciver
if (get_line()) { /* receiver got a line of data */
sscanf(str, "%hX,%hX", &r_x, &r_y) ;
snprintf(str, STR_BUF_LEN, "Received: %04X %04X\n", r_x, r_y) ;
UART_Terminal_PutString(str) ;
data_sent = 0 ;
}
}
}
==========================
Tera Term log
I used CY8CKIT-059, to test this program connect
P3[7] and P1[6]
P3[6] and P1[7]
I hope this can be an idea for your issue.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CaDu,
I see multiple problems with your code.
CY_ISR(RX_Handler){
int i = 0;
for(i=0; i<=1;i++){
Bytes_In= UART_GetByte(); // Problem #1: You're assuming you will read two bytes from the UART Rx. There is 100% chance with this routine you will receive
// exactly one byte of valid data and the other byte will be '\0' (null character).
// I think you are assuming that the two bytes you are sending by the transmitter will be received with one ISR from the Rx.
// If you process this correctly, you should receive two calls to this ISR. One for each byte from the transmitter.
}
UART_ClearRxBuffer(); // Note: This statement is most likely unnecessary.
}
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
SYS_INIT();
RX_ISR_StartEx(RX_Handler);
UART_SetRxInterruptMode(UART_RX_STS_FIFO_NOTEMPTY);
for(;;)
{
UART_Terminal_WriteTxData(Bytes_In[1]); // Problem #2: Based on Problem #1, the '\0' byte would be the only one pushed to the Terminal.
CyDelay(1000);
}
}
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How about the following?:
Here I am setting it to interrupt on RX, which means that for every interrupt, the index will increase, and write that byte inside the the buffer.
* ========================================
*
* Copyright YOUR COMPANY, THE YEAR
* All Rights Reserved
* UNPUBLISHED, LICENSED SOFTWARE.
*
* CONFIDENTIAL AND PROPRIETARY INFORMATION
* WHICH IS THE PROPERTY OF your company.
*
* ========================================
*/
#include "project.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#define MSG_LENGTH 2
int i = 0;
int status =1;
uint8_t Bytes_In[2];
uint8_t Bytes;
uint8_t Data_In;
uint8_t Buffer;
CY_ISR(RX_Handler){
i = 0;
Bytes_In=UART_GetByte();
i++;
if(i>=2) i = 0;
RX_ISR_ClearPending();
}
void SYS_INIT(void){
UART_Start();
UART_Terminal_Start();
RX_ISR_Start();
}
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
SYS_INIT();
RX_ISR_StartEx(RX_Handler);
for(;;)
{
Buffer=UART_GetRxBufferSize();
UART_Terminal_WriteTxData(Bytes_In[0]);
//for(i=0;i<=1158000;i++);
}
}
/* [] END OF FILE */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CaDu,
Your changes are better but still have a few issues.
uint8 new_byte = 0; // This is a flag to the main() loop to know when a new byte comes in.
CY_ISR(RX_Handler){
i = 0;
Bytes_In=UART_GetByte();
// add this next code line
new_byte = 1; // indicate that a new byte is available.
// end of added code
i++;
if(i>=2) i = 0;
RX_ISR_ClearPending();
}
#include "stdio.h" // Add this line to allow snprintf() functions
char tstr[20]; // Temporary string allocation
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
SYS_INIT();
RX_ISR_StartEx(RX_Handler);
for(;;)
{
Buffer=UART_GetRxBufferSize(); // I'm not sure what this is used for.
// Replacement code for your WriteTxData(). Using bytes might dump unprintable characters to the terminal.
// The replacement will format the bytes into human-readable hex characters.
if(new_byte > 0)
{ // A new byte is available
new_byte = 0; // reset the new byte flag.
if(i == 1)
{ // print the first byte of two bytes
snprintf(tstr, sizeof(tstr), "%02X:", Bytes_In[0]); // format the hex representation of the input byte.
UART_Terminal_PutString(tstr); // dump the formatted string to the terminal.
}
else if(i > 1)
{ // print the second byte of two bytes and place a CRLF to advance to a new line.
snprintf(tstr, sizeof(tstr), "%02X\n\r", Bytes_In[1]); // format the hex representation of the input byte.
UART_Terminal_PutString(tstr); // dump the formatted string to the terminal
}
}
}
}
Question: You are receiving a stream of data paired as two-bytes. How do you know which byte you receive is the first byte and which the second?
Are you using a a two-byte burst then there is a delay in time at the Tx end?
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
HI, about knowing which bit is the first, that I do not know how to specify yet.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CaDu,
In a stream of data where the order of data matters, you need to define a Start-Of-Header (SOH) and in some cases a End-Of-Header (EOH).
If the stream of data is ASCII bytes to a terminal, you may not need a SOH or EOH because as soon as you make the connection to both ends the stream shows up on the terminal. The human brain then deciphers the beginning and end of data.
However in your case, you have a paired 2 bytes of data where knowing what is the first byte and the other the second byte.
There many ways to define a SOH and if needed a EOH.
One simple way is on the transmit end to place a time delay (let's call it 10ms) between the previous 2-byte set and the next 2-byte set. Also on the transmit end, the 2-bytes of data have virtually no delay between the first and second bytes.
On the receiving end, you would need to look for the time gap (in this example 10ms). This is the SOH synchronization point to know when you are about to receive the first byte.
Time delay | First Byte | Second Byte | Time delay | First Byte | Second Byte | Time delay | First Byte | Second Byte | Time delay |
0x32 | 0x45 | 0xC2 | 0x02 | 0x22 | 0x28 |
In the above solution the time delay to the next set of data is the EOH to the just completed 2-byte set.
A second solution is by adding an addition byte in the data stream. You have to determine with your data if there is a byte value that neither the first byte or second byte can NEVER be. A possible example is the 0xFF byte. This byte value would be the SOH also called the SYNC value.
If this is the case you can send the 3-byte data with the first byte being the SOH, the second being the first byte of data and the third being the second byte of data.
Every time you receive the SYNC value, this is the SOH and you know how to re-SYNC the data to know when to expect the first then the second bytes of data. In this case the SOH is the implied EOH for the previous data set. Additionally the data does'nt require a time delay and the bytes can be sent potentially faster.
SOH (SYNC) | First Byte | Second Byte | SOH (SYNC) | First Byte | Second Byte | SOH (SYNC) | First Byte | Second Byte | SOH (SYNC) |
0xFF | 0x32 | 0x45 | 0xFF | 0xC2 | 0x02 | 0xFF | 0x22 | 0x28 | 0xFF |
As a last note, there are conditions in the data set where a specific EOH may be necessary. Let's assume in your case it is not.
I hope this helps. You express that the incoming data is "not correct" however you never provided examples of the incoming data along with what the expected data should be. Therefore, moto and myself are making certain assumptions as best we can.
Len
"Engineering is an Art. The Art of Compromise."