SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller
Overview
In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed at beginners who are looking for a simplified guide to quickly grasp and use the SBUS protocol. Advanced technical detail are avoided for simplicity, and the practical waveform enalysis is presented to complement the understanding of the communication protocol. Using an oscilloscope to study the hardware signals can be beneficial but is optional.
Development Environment and Hardware Setup
Software
The development environment includes:
- Compiler: KEIL MDK.
- Library: STM32 standard peripheral library.
- MCU IO: Pin PC11 (USART4 RX; TX is not connected).
- MCU Peripherals:
- USART4 for receiving SBUS data.
- TIM3 for validating received data correctness.
Hardware
- Remote Controller: FS-I6S configured in SBUS output mode.
- SBUS Receiver: IA10B.
- Control Board: STM32F407-based development board.
- Supporting Circuit: A simple transistor-based inverting circuit for SBUS signal adjustment.
- Connections:
- Signal line to the input of the transistor inverter.
- Power lines (+5V and GND).
SBUS requires a polarity inversion since its signal levels differ from typical UART signals. A minimal STM32-based board like STM32F103 will suffice for implementation, provided it has serial peripherals.
SBUS Protocol
SBUS, as an extension of USART communication, transmits data in 25-byte frames. The first byte is always 0x0F, followed by 23 data bytes, and concludes with 0x00. The USART should be configured as:
- Baud rate: 100,000.
- Data bits: 8.
- Stop bits: 2.
- Parity: Even.
- No hardware flow control.
Parsing SBUS involves extracting 11-bit data segments from the middle 23 bytes. Resources on parsing methodologies are widely available online.
Waveform Analysis
Bit and Frame Timing:
- SBUS operates at 100 kHz, yielding a 10 µs bit period (oscilloscopes may show minor deviations around 11.7 µs).
- Each byte comprises 12 bits: 1 start bit, 8 data bits, 1 parity bit, and 2 stop bits.
- A complete SBUS frame has 25 bytes, consuming approximately 3 ms for transmission.
Inter-frame Interval:
- Frames are spaced by 4.68 ms intervals. To avoid data loss, program logic must complete tasks within this duration.
Implementation
Workflow
- Initialize serial (USART4) and timer (TIM3) peripherals. TIM3 is set with a 3 ms interval, accommodating one frame duration.
- Anable USART4 upon detecting a consistent high level on pin PC11, corresponding to the idle interval between frames.
- Once 25 bytes are received, verify the frame integrity using TIM3 interrupts before executing the parsing logic.
Corre Code
USART Configuration:
Setting up USART4 involves enabling interrupts to read incoming SBUS data. The following code initializes USART4:
void ConfigureUSART4(uint32_t baud_rate) {
// Set GPIO pins and configurations...
USART_InitTypeDef USART_Config;
USART_Config.USART_BaudRate = baud_rate;
USART_Config.USART_WordLength = USART_WordLength_9b;
USART_Config.USART_StopBits = USART_StopBits_2;
USART_Config.USART_Parity = USART_Parity_Even;
USART_Config.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(UART4, &USART_Config);
}
Interrupts handle received bytes and start TIM3:
void UART4_IRQHandler(void) {
if (USART_GetITStatus(UART4, USART_IT_RXNE)) {
data_buffer[data_index++] = UART4->DR;
TIM_Cmd(TIM3, ENABLE); // Start timer for 3 ms cycle when data is received
}
USART_ClearITPendingBit(UART4, USART_IT_RXNE);
}
TIM3 Configuration:
TIM3 verifies data integrity and triggers frame parsing upon successful reception:
void TIM3_IRQHandler(void) {
TIM_Cmd(TIM3, DISABLE); // Stop timer upon interrupt
if (data_index == 25) {
ParseSBUSData(data_buffer);
} else {
++receive_error_flag; // Count incomplete frames
}
}
SBUS Parsing:
The parsing function extracts channel values (11-bit) from the SBUS data frame:
void ParseSBUSData(uint8_t buffer[]) {
channels[0] = (buffer[1] | (buffer[2] << 8)) & 0x07FF;
channels[1] = ((buffer[2] >> 3) | (buffer[3] << 5)) & 0x07FF;
// Repeat for other channels...
}
Summary
The implementation successfully proceses SBUS data into channel array channels[], where individual indexes correspond to specific controls on the Fus remote. For example:
#define RightStickHorizontal channels[0] // Neutral: 1033; Left: 242; Right: 1804
Adjustments may be required based on the MCU used and remote control calibration offsets. Analytical testing tools like oscilloscope snapshots are invaluable during debugging.
External reference: Visit this link for visual explanations and examples.