UART serial communication
Linux Serial Communication
Serial communication is one of the most common low-level communication methods in robotics and embedded projects.
In actual projects, the host computer often needs to exchange data with devices such as STM32, ESP32, Arduino, sensor modules, and debug boards via serial port. For example:
- The host computer sends motor speed commands to the STM32.
- STM32 sends encoder data back to the host computer
- Read sensor data from IMU, GPS, laser ranging module, etc.
- Using a USB to serial module for debugging
- Communicating with the lower-level controller in ROS 2 chassis control
Serial communication is characterized by simplicity, versatility, and low cost, making it especially suitable for point-to-point communication between a host computer and a microcontroller.
What is serial communication?
Serial communication usually refers to UART communication. On Linux, common USB-to-serial devices are recognized as device files like the following:
/dev/ttyUSB0
/dev/ttyUSB1
/dev/ttyACM0
The program only needs to open the corresponding device file and set parameters such as baud rate, data bits, stop bits, and parity bit, and then it can send and receive data.
Common parameters include:
| parameter | Explanation |
|---|---|
| device name | For example, /dev/ttyUSB0, /dev/ttyACM0 |
| baud rate | For example, 115200, 921600 |
| data bits | Commonly 8-bit |
| stop bit | Commonly 1 bit |
| check bit | Commonly without checksum |
| rate limiting | In typical projects, hardware flow control is often disabled. |
In robotics projects, serial ports typically do not just send plain strings; instead, they design their own binary communication protocols, such as frame header, length, command word, data area, CRC check, etc.
Common Serial Port Libraries for Linux
There are multiple options for using serial communication on Linux, common ones include:
| solution | type | Features | Suitable scenarios |
|---|---|---|---|
| termios | Linux native interface | Lowest level, few dependencies, strong generality, but the code is relatively cumbersome. | Want to deeply understand the Linux serial port mechanism |
| boost::asio | General C++ Library | Supports synchronous and asynchronous modes, has a relatively clear code structure, and offers good cross-platform capabilities. | Recommended for C++ project packaging |
| libserial | third-party serial library | Easy to use and easier to learn than termios. | Basic Serial Port Communication Project |
| serial_driver | ROS 2 Ecosystem Encapsulation | More convenient to integrate with ROS 2, but not suitable for projects that rely solely on systems other than ROS 2. | Pure ROS 2 project or reference implementation |
| pyserial | Python serial library | Very simple to use, ideal for quick testing. | Python debugging script |
These libraries are essentially designed to accomplish the opening, configuration, reading, and writing of serial ports, differing only in their level of encapsulation.
Comparison of Solutions
| solution | Advantages | Disadvantages |
|---|---|---|
| termios | Linux native, minimal dependencies, strong underlying capabilities | The configuration is cumbersome, and beginners easily make mistakes. |
| boost::asio | C++ project-friendly, convenient asynchronous communication, suitable for encapsulating drivers. | Need to understand the basic model of asio. |
| libserial | Simple and easy to use, quick to get started | Flexibility and engineering controllability are not as good as rolling your own. |
| serial_driver | Convenient integration with the ROS 2 ecosystem | After leaving ROS 2, reusability is poor. |
| pyserial | Quick debugging, good for scripts. | Not suitable as the main focus for high-performance C++ low-level drivers. |
This tutorial recommends selecting
This tutorial recommends prioritizing:
boost::asio
The reason is:
- more suitable for C++ development than directly using
termios - It can be encapsulated into a regular C++ driver for easy reuse.
- Without relying on ROS 2, it can be used with OpenCV, Qt, and ordinary C++ projects.
- Later, it can also naturally integrate
ros2_control hardware_interface. - More suitable for robot host computer and STM32 communication scenarios.
The recommended project structure is:
上层项目:ROS 2 / OpenCV / Qt / 普通 C++ 程序
↓
自己封装的 SerialDriver 类
↓
boost::asio
↓
/dev/ttyUSB0
↓
STM32 / ESP32 / 传感器
Relationship with ROS 2
Learning Linux serial communication does not mean you don't use ROS 2.
In a ROS 2 project, serial communication can be encapsulated as a normal C++ class, which is then called within a ROS 2 node or ros2_control hardware_interface.
For example:
ros2_control controller
↓
hardware_interface
↓
自己封装的 SerialDriver
↓
boost::asio
↓
STM32
The advantage of this is that the serial communication code is not tightly coupled with ROS 2. In the future, even when writing OpenCV projects, Qt host computer applications, or ordinary C++ debugging programs, you can still reuse the same serial port driver.
Chapter learning objectives
After completing this chapter, you should be able to:
- Basic Concepts of Serial Devices in Linux
- How to view and open serial port devices such as
/dev/ttyUSB0 - Serial port baud rate, data bits, stop bits, parity bit, and other basic parameters
- Sending and Receiving Serial Port Data Using C++
- Design a simple communication protocol between a host computer and a lower-level computer.
- Encapsulate serial communication into a reusable C++ class.
- Lay the foundation for future integration with ROS 2, OpenCV, and Qt projects.