horsemann07
horsemann07

Reputation: 79

How should I frame the data and send multiple bytes over uart?

I m trying to write the code for on switch board touch sensor which communication with mcu(esp32) using the uart protocol. There we have frame of packet which we have to write to uart to get the reading. Let me share some documentation,

1.

In API frame structure following is the fixed definition of any command frame

     Every first byte of frame is fixed 0x7B (“{” in ASCII, 123 in decimal).
    Every second byte of frame is ‘command type’ byte, it informs what you need to do with rest of the data. This will act as a frame Identifier in the data received from touch panel (response frame and event frame)
    Third byte is length of frame. It is 1-byte value (L - 4) where L is total numbers of bytes of whole frame.
    Second Last byte is checksum. Checksum is a lower byte of addition of whole individual bytes of frame except First byte (Start byte), Second byte (Command type byte), 
       Second Last byte (Checksum byte itself) and Last byte is 0x7D.
    Last byte is 0x7D, it is End code to indicate the end of frame. (“}” in ASCII, 125  in decimal).

For Example, consider following frame.
Table 1.1 Frame example 1.

1st Byte    2nd Byte    3rd Byte    4th Byte    5th Byte    6th Byte
0x7B        0x03        0x02        0x05        0x07        0x7D
Start Code  Command     Length         Data        Checksum     End Code

So the checksum will be lower byte of addition of third byte and fourth byte.
0x02 + 0x05 = 0x07 so we will consider 0x07 as checksum here.


Example 2, consider following frame.
Table 1.2 Frame example 2.

1st Byte    2nd Byte    3rd Byte    4th Byte    5th Byte    6th Byte    7th Byte    8th Byte
0x7B        0x52        0x04        0x02        0xFF        0x14        0x19        0x7D
Start Code  Frame       Length      Data        Data        Data        Checksum    End Code          
            Identifier

In this example 2 the checksum will be lower byte of addition of third to sixth byte.
0x04 + 0x02 + 0xFF + 0x14 = 0x0119 so we will consider 0x19 as checksum here.

2. 

    Blink LED (All slider LED) control.
    1.Command
    
    This package is used to control blinking of LED. Hardware Version 2.0 has dedicated status LED. Which will be used to indicate status of product as on need. 
    
    Table 1.6 Blink LED command package detail.
    Status  1st Byte    2nd Byte    3rd Byte    4th Byte        5th Byte            6th Byte    8th Byte
    Start   0x7B        0x05        0x03    0x01  (Start)   (0x01 to 0xNN*)     Checksum    0x7D
    Stop    0x7B        0x05        0x03    0x00  (Stop)     0x00               Checksum    0x7D
        Start Code      Command     Length              Pulse with (x100ms)     Checksum    End Code
    
    To start status LED blinking, the start command frame is sent with required value of 4th byte as 0x01. For Example, to make status LED blinking as time duration 200ms, the value of 5th byte is 0x02. 
    And to stop status LED blinking the stop frame is sent
    
    2.Response
    Table 1.7 Blink LED response detail.
    
    1st Byte    2nd Byte    3rd Byte    4th Byte    5th Byte
    0x7B        0x55        0x01        0x01        0x7D

n 1 point, we can able to see how uart frame should be. In 2 point, I want to read and write the frame command to stop and start blinkin the led.

My question is

I did research on how frame the packet and send frame over uart but not found any useful blogs and answer.

More Info:

Language: C
Compiler: GCC 
MCU: ESP32

Hope I m able to explain it.

Thanks in advance for the help!!

Upvotes: 0

Views: 4087

Answers (1)

Codo
Codo

Reputation: 78825

Sending multiple bytes

Sending multiple bytes is straight-forward with the ESP-IDF framework. Let's assume your command frame is in an array called frame and the length (in bytes) of the frame is stored in frame_length:

uint8_t frame[] = { 0x7B, 0x03, 0x02, 0x05, 0x07, 0x7D };
int frame_length = 6;
uart_write_bytes(uart_port, frame, frame_length);

The bigger challenge is probably how to construct the frame in the first place, in particular how to calculate the checksum.

Sending multiple frames

Sending multiple frames is straight-forward as well. Just call the above function multiple times. The protocol has been carefully designed such that the receiver is able to split the stream of bytes into frames.

You should prevent however that multiple tasks sends frames concurrently. That way the communication could get mixed up.

Receiving frames

Receiving isn't a problem either. Just read frame by frame. It's a two step process:

  1. Read 3 bytes. The third byte provides the length of the frame.
  2. Read the remaining bytes.

It could look like so:

#define MAX_FRAME_LENGTH 80

uint8_t frame[MAX_FRAME_LENGTH];
int frame_length = 0;

int read_frame(uint8_t* frame) {
    uart_read_bytes(uart_port, frame, 3, portMAX_DELAY);
    uart_read_bytes(uart_port, frame + 3, frame[2] + 4, portMAX_DELAY);
    return frame[2] + 4;
}

Upvotes: 1

Related Questions