保姆级避坑指南:在Ubuntu22.04上搞定ROS2 Humble与CH340串口通信(含驱动签名、权限、库缺失全流程)

📅 2026/7/3 9:22:39 👁️ 阅读次数 📝 编程学习
保姆级避坑指南:在Ubuntu22.04上搞定ROS2 Humble与CH340串口通信(含驱动签名、权限、库缺失全流程)

Ubuntu 22.04 ROS2 Humble 串口通信全流程避坑实战

第一次在Ubuntu 22.04上配置ROS2 Humble与CH340串口通信时,我遇到了驱动签名失败、权限不足、动态库缺失等一系列问题。经过多次尝试和排查,终于整理出这份覆盖完整流程的解决方案。本文将重点解决实际开发中最容易卡住的几个关键环节,帮助开发者快速搭建稳定的串口通信环境。

1. 环境准备与驱动安装

1.1 系统基础配置

在开始之前,建议先更新系统软件包:

sudo apt update && sudo apt upgrade -y

Ubuntu 22.04默认启用了安全启动(Secure Boot),这会导致第三方驱动无法直接加载。对于CH340这类常见USB转串口芯片,我们需要特别注意驱动签名问题。

1.2 CH340驱动安装与签名

CH340驱动安装过程中最常见的错误是"Key was rejected by service"。这是因为新版本Ubuntu对内核模块有更严格的安全要求。以下是具体解决方案:

  1. 首先安装编译依赖:

    sudo apt install build-essential linux-headers-$(uname -r) -y
  2. 下载官方驱动源码:

    git clone https://github.com/juliagoda/CH341SER.git cd CH341SER make
  3. 处理签名问题:

    sudo mkdir -p /usr/local/lib/modules/$(uname -r)/kernel/drivers/usb/serial sudo cp ch34x.ko /usr/local/lib/modules/$(uname -r)/kernel/drivers/usb/serial sudo depmod -a

如果仍然遇到签名错误,可以尝试临时禁用Secure Boot或在BIOS中将其关闭。

1.3 验证驱动加载

安装完成后,插入CH340设备,检查驱动是否加载成功:

dmesg | grep ch34x ls /dev/ttyUSB*

正常情况应该能看到类似输出:

[ 1234.567890] usbserial: USB Serial support registered for ch34x [ 1234.567891] ch34x 1-1.2:1.0: ch34x converter detected /dev/ttyUSB0

2. ROS2串口通信环境配置

2.1 安装ROS2 Humble基础环境

确保已正确安装ROS2 Humble桌面版:

sudo apt install ros-humble-desktop source /opt/ros/humble/setup.bash

2.2 安装串口通信相关包

ROS2的串口通信主要依赖serial-driver包:

sudo apt install ros-humble-serial-driver

同时安装调试工具:

sudo apt install cutecom

2.3 解决动态库缺失问题

运行程序时可能会遇到"error while loading shared libraries: libserial.so"错误。这是因为系统找不到serial库文件。解决方法如下:

临时方案(当前终端有效)

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

永久方案

echo '/usr/local/lib' | sudo tee -a /etc/ld.so.conf sudo ldconfig

验证是否生效:

ldconfig -p | grep libserial

3. 串口权限与常见冲突解决

3.1 串口设备权限管理

默认情况下,普通用户无法直接访问串口设备。不建议使用chmod 777这种不安全的方式,而是应该将用户加入dialout组:

sudo usermod -aG dialout $USER

然后重新登录使更改生效。验证权限:

ls -l /dev/ttyUSB0

正确输出应包含dialout组:

crw-rw---- 1 root dialout 188, 0 Jun 1 10:00 /dev/ttyUSB0

3.2 解决brltty服务冲突

Ubuntu 22.04默认安装的brltty服务会占用串口设备,导致无法访问。解决方法:

  1. 检查服务状态:

    systemctl status brltty-udev.service
  2. 禁用服务:

    sudo systemctl mask brltty-udev.service sudo systemctl stop brltty-udev.service
  3. 移除自动安装:

    sudo apt remove brltty

4. ROS2串口通信实战

4.1 创建工作空间与包

mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src ros2 pkg create --build-type ament_cmake serial_demo

4.2 编写串口发布节点

创建serial_publisher.cpp文件:

#include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" #include "serial/serial.h" class SerialPublisher : public rclcpp::Node { public: SerialPublisher() : Node("serial_publisher") { publisher_ = this->create_publisher<std_msgs::msg::String>("serial_data", 10); timer_ = this->create_wall_timer( std::chrono::milliseconds(500), std::bind(&SerialPublisher::timer_callback, this)); serial_.setPort("/dev/ttyUSB0"); serial_.setBaudrate(9600); serial::Timeout timeout = serial::Timeout::simpleTimeout(1000); serial_.setTimeout(timeout); try { serial_.open(); } catch (serial::IOException& e) { RCLCPP_ERROR(this->get_logger(), "无法打开串口"); } } private: void timer_callback() { auto message = std_msgs::msg::String(); if(serial_.isOpen()) { size_t bytes = serial_.available(); if(bytes > 0) { std::string result = serial_.read(bytes); message.data = result; publisher_->publish(message); RCLCPP_INFO(this->get_logger(), "收到数据: '%s'", message.data.c_str()); } } } rclcpp::TimerBase::SharedPtr timer_; rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_; serial::Serial serial_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<SerialPublisher>()); rclcpp::shutdown(); return 0; }

4.3 修改CMakeLists.txt

CMakeLists.txt中添加:

find_package(serial REQUIRED) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) add_executable(serial_publisher src/serial_publisher.cpp) target_link_libraries(serial_publisher ${rclcpp_LIBRARIES} ${std_msgs_LIBRARIES} serial::serial ) install(TARGETS serial_publisher DESTINATION lib/${PROJECT_NAME} )

4.4 编译与运行

cd ~/ros2_ws colcon build --packages-select serial_demo source install/setup.bash ros2 run serial_demo serial_publisher

5. 高级调试技巧

5.1 串口调试工具使用

推荐使用cutecom进行基础调试:

sudo cutecom

在界面中选择正确的串口设备(/dev/ttyUSB0),设置波特率等参数后,可以手动发送和接收数据。

5.2 查看系统日志

当遇到问题时,系统日志往往能提供有用信息:

journalctl -f

5.3 检查USB设备详情

lsusb -v | grep -A 3 CH340

输出示例:

Bus 001 Device 003: ID 1a86:7523 QinHeng Electronics CH340 serial converter Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10

5.4 自定义udev规则(可选)

为避免每次插拔USB设备后节点名称变化(/dev/ttyUSB*编号变化),可以创建udev规则:

  1. 创建规则文件:

    sudo nano /etc/udev/rules.d/99-ch340.rules
  2. 添加内容:

    SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyROS_CH340"
  3. 重新加载规则:

    sudo udevadm control --reload-rules sudo udevadm trigger

之后设备将固定出现在/dev/ttyROS_CH340,在代码中可以直接使用这个固定名称。