Protocols and Data Flows
From the Detailed Configuration Methods section, we know that serial port 3 on LQ 3 series products supports SBUS protocol input and output. However, the configuration method pr…
2 min read · English documentationProtocols and Data Flow
Serial-to-SBUS Protocol Conversion
From the Detailed Configuration Methods section, we know that serial port 3 on LQ-3 series products supports SBUS protocol input and output. However, the configuration method provided there covers SBUS-to-SBUS operation. This section explains how to use serial-to-SBUS protocol conversion.
Configuration steps:
-
First, connect serial port 3 of the primary LQ-3 device to a computer's serial port and open a serial terminal application. Set the baud rate of serial port 3 to 115200, the data bits to 8, parity to none, and the stop bits to 1.
-
Set the destination IP address to the IP address of the secondary device to which you want to transmit data. Set the port to a custom value. For example, if your IP address is 192.168.1.201 and the port is 8004, configure the webpage as follows:

- After connecting the secondary device to the computer as described above, configure serial port 3 for SBUS, set the baud rate to 115200, the data bits to 8, parity to none, and the stop bits to 1. Enable the server and set its port to the same port used by the sender.

When converting serial data to the SBUS protocol, the data must comply with the SBUS protocol data-frame requirements. You can learn about the SBUS frame format at this link: https://blog.csdn.net/weixin_74923758/article/details/144460760. Then connect the serial port to the transmitting end of the primary device, and the receiving end of the secondary device will output the SBUS signal normally.
Conversion Example
We provide customers with a code example that converts data frames from a common remote controller serial protocol into standard SBUS frames. Customers only need to pass a remote controller signal containing serial-frame data that conforms to the format shown below through the sbus_encoder function to obtain an SBUS data frame recognizable by the LQ module. The SBUS data suitable for the flight controller can then be obtained through LQ3's SBUS conversion interface.
| Byte No. | Data | Field | Data Type | Detailed Description |
|---|---|---|---|---|
| 1 | 0x0F | Frame header | uint16_t | Start bit |
| 2-33 | ~ | Main data section | uint16_t | As shown in detail below |
| 34 | 0x0C | Reserved | uint16_t | Reserved; fixed at 0x0C |
| 35 | 0x33 | Checksum | uint16_t | XOR checksum of the remaining 33 bytes, excluding the frame header |
/*----------Required header files----------*/
#include <stdio.h>
#include <stdint.h>
/*----------Protocol conversion functions----------*/
/**
* @brief Calculate the BCC checksum (XOR checksum)
* @param data Pointer to the data to be checked
* @param length Length of the data to be checked
* @return uint8_t Calculated BCC checksum
*/
static uint8_t getBcc(uint8_t *data, uint16_t length)
{
uint8_t i;
uint8_t bcc = 0; // Initial value
while (length--)
{
bcc ^= *data++;
}
return bcc;
}
/**
* @brief SBUS data decoding function - Decode a 25-byte SBUS packet into 35-byte raw channel data
* @param indata Pointer to the input SBUS packet (25 bytes)
* @param inlen Input data length (should be 25)
* @param outdata Pointer to the output decoded data (35 bytes)
* @param outlen Pointer to the output data length
* @return void
*
* @note Input data format: 25-byte SBUS packet
* Output data format: 35-byte decoded data (including the start bit, 16 channels of data, end bit, and BCC checksum)
*/
static void sbus_decoder(uint8_t* indata, uint16_t inlen, uint8_t* outdata, uint8_t* outlen)
{
if ((inlen != 25) || (indata[0] != 0x0f) || (indata[inlen - 1] != 0x00)) return ;
uint8_t n = 0;
uint16_t val = 0;
outdata[n++] = 0x0f;
val = ((indata[1] | indata[2] << 8) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[2] >> 3 | indata[3] << 5) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[3] >> 6 | indata[4] << 2 | indata[5] << 10) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[5] >> 1 | indata[6] << 7) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[6] >> 4 | indata[7] << 4) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[7] >> 7 | indata[8] << 1 | indata[9] << 9) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[9] >> 2 | indata[10] << 6) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[10] >> 5 | indata[11] << 3) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[12] | indata[13] << 8) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[13] >> 3 | indata[14] << 5) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[14] >> 6 | indata[15] << 2 | indata[16] << 10) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[16] >> 1 | indata[17] << 7) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[17] >> 4 | indata[18] << 4) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[18] >> 7 | indata[19] << 1 | indata[20] << 9) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[20] >> 2 | indata[21] << 6) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
val = ((indata[21] >> 5 | indata[22] << 3) & 0x07FF);
outdata[n++] = val >> 8; outdata[n++] = val & 0x00ff;
outdata[n++] = 0x0c;
uint8_t xorr = getBcc(&outdata[1], n - 1);
outdata[n++] = xorr;
*outlen = n;
}
/**
* @brief SBUS data encoding function - Encode 35-byte raw channel data into a 25-byte SBUS packet
* @param indata Pointer to the input raw data (35 bytes)
* @param inlen Input data length (should be 35)
* @param packet Pointer to the output SBUS packet (25 bytes)
* @param outlen Pointer to the output data length
* @return void
*
* @note Input data format: 35-byte raw data (including the start bit, 16 channels of data, end bit, and BCC checksum)
* Output data format: 25-byte SBUS packet
* Channel data range: 880-2160 corresponds to 0-2047 (11 bits)
*/
static void sbus_encoder(uint8_t* indata, uint16_t inlen, uint8_t* packet, uint8_t* outlen)
{
if ((inlen != 35) || (indata[0] != 0x0f) || (indata[inlen - 2] != 0x0c)) return ;
uint8_t xorr = getBcc(&indata[1], inlen - 2);
if (xorr != indata[inlen - 1]) return ;
uint16_t channels[16];
uint8_t* data = &indata[1];
for (int i = 0; i < 16; i++)
{
channels[i] = ((uint16_t)data[i * 2] << 8) | ((uint16_t)data[i * 2 + 1]);
channels[i] = (uint16_t)((float)(channels[i] - 880) / 0.625f);
}
packet[0] = 0x0F;
packet[1] = (unsigned char)((channels[0] & 0x07FF));
packet[2] = (unsigned char)((channels[0] & 0x07FF) >> 8 | (channels[1] & 0x07FF) << 3);
packet[3] = (unsigned char)((channels[1] & 0x07FF) >> 5 | (channels[2] & 0x07FF) << 6);
packet[4] = (unsigned char)((channels[2] & 0x07FF) >> 2);
packet[5] = (unsigned char)((channels[2] & 0x07FF) >> 10 | (channels[3] & 0x07FF) << 1);
packet[6] = (unsigned char)((channels[3] & 0x07FF) >> 7 | (channels[4] & 0x07FF) << 4);
packet[7] = (unsigned char)((channels[4] & 0x07FF) >> 4 | (channels[5] & 0x07FF) << 7);
packet[8] = (unsigned char)((channels[5] & 0x07FF) >> 1);
packet[9] = (unsigned char)((channels[5] & 0x07FF) >> 9 | (channels[6] & 0x07FF) << 2);
packet[10] = (unsigned char)((channels[6] & 0x07FF) >> 6 | (channels[7] & 0x07FF) << 5);
packet[11] = (unsigned char)((channels[7] & 0x07FF) >> 3);
packet[12] = (unsigned char)((channels[8] & 0x07FF));
packet[13] = (unsigned char)((channels[8] & 0x07FF) >> 8 | (channels[9] & 0x07FF) << 3);
packet[14] = (unsigned char)((channels[9] & 0x07FF) >> 5 | (channels[10] & 0x07FF) << 6);
packet[15] = (unsigned char)((channels[10] & 0x07FF) >> 2);
packet[16] = (unsigned char)((channels[10] & 0x07FF) >> 10 | (channels[11] & 0x07FF) << 1);
packet[17] = (unsigned char)((channels[11] & 0x07FF) >> 7 | (channels[12] & 0x07FF) << 4);
packet[18] = (unsigned char)((channels[12] & 0x07FF) >> 4 | (channels[13] & 0x07FF) << 7);
packet[19] = (unsigned char)((channels[13] & 0x07FF) >> 1);
packet[20] = (unsigned char)((channels[13] & 0x07FF) >> 9 | (channels[14] & 0x07FF) << 2);
packet[21] = (unsigned char)((channels[14] & 0x07FF) >> 6 | (channels[15] & 0x07FF) << 5);
packet[22] = (unsigned char)((channels[15] & 0x07FF) >> 3);
packet[23] = 0x03;
packet[24] = 0X00;
*outlen = 25;
}
