18、网络与通信:WiFi/BT模块配置、CAN总线调试、ROS2集成、MQTT物联网通信

各位同学,今天我们来聊聊Jetson平台上的网络与通信。这部分内容,说白了就是让Orin跟外界“说话”。WiFi/BT是无线耳朵和嘴巴,CAN是工业硬连线,ROS2是机器人圈的普通话,MQTT则是物联网的轻量级信使。这四个东西凑一块儿,基本覆盖了从智能小车到边缘服务器的所有场景。

我个人习惯把这部分叫做“Jetson的感官与神经”。你想想看,一个机器人如果连不上网、收不到传感器数据、没法跟云端对话,那它就是个砖头。所以,这一章的内容,我建议你动手跟着做一遍,别光看。

本章核心脉络:从硬件接口配置 → 驱动验证 → 通信协议栈搭建 → 应用层集成。每一步都有坑,我会把踩过的坑指给你看。

Jetson 网络与通信知识体系 Jetson Orin WiFi / BT 模块 CAN 总线调试 ROS2 集成 MQTT 物联网 · AP模式 / STA模式 · BT扫描与配对 · can-utils 工具链 · 波特率 & 终端电阻 · colcon 编译 · 话题/服务/动作 · mosquitto 部署 · QoS & 遗嘱消息

18.1 WiFi / BT 模块配置

Jetson Orin 自带的 WiFi/BT 模块是 AzureWave 的 AW-CM256SM,用的是 Realtek 芯片。嗯,这里要注意:默认系统不一定装了完整的固件。我第一次拿到 Orin NX 时,WiFi 能扫到热点但连不上,折腾了半天,最后发现是缺少 rtl8852be 的 firmware。

快速检查与修复

  • 检查模块是否识别:lspci | grep -i networklsusb | grep -i bluetooth
  • 查看无线网卡状态:nmcli dev status
  • 如果缺少固件,从 linux-firmware 仓库手动复制到 /lib/firmware/rtl_bt/

配置 WiFi 我习惯用 nmcli,简单直接。举个例子,连接一个 WPA2 网络:

# 开启 WiFi 射频
sudo nmcli radio wifi on

# 扫描可用网络
nmcli dev wifi list

# 连接指定 SSID
sudo nmcli dev wifi connect "MyHomeNet" password "yourpassword"

# 配置静态 IP(如果需要)
sudo nmcli con mod "MyHomeNet" ipv4.addresses 192.168.1.100/24
sudo nmcli con mod "MyHomeNet" ipv4.gateway 192.168.1.1
sudo nmcli con mod "MyHomeNet" ipv4.dns "8.8.8.8"
sudo nmcli con mod "MyHomeNet" ipv4.method manual
sudo nmcli con up "MyHomeNet"

蓝牙部分,我踩过一个坑:Jetson 默认的 BT 服务可能被 brcmfmac 驱动占用。如果你发现 bluetoothctl 扫描不到设备,试试先重启蓝牙服务:

sudo systemctl restart bluetooth
bluetoothctl
# 进入交互后
power on
agent on
scan on
pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
connect XX:XX:XX:XX:XX:XX

我曾经遇到过的坑:WiFi 和 BT 共用天线时,同时高速传输会导致 BT 丢包。解决办法是在 /etc/modprobe.d/rtl88x2bt.conf 中调整共存优先级,或者干脆用 USB 外接 BT 适配器做隔离。

18.2 CAN 总线调试

CAN 总线在机器人底盘、工业电机控制里非常常见。Jetson Orin 的 40-pin 扩展口上直接引出了 CAN0 和 CAN1(需要电平转换芯片,比如 SN65HVD230)。

我个人习惯先用 can-utils 做环回测试,确认驱动没问题:

# 加载驱动
sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan

# 配置 CAN0 接口,波特率 500k
sudo ip link set can0 type can bitrate 500000
sudo ip link set can0 up

# 发送测试帧
cansend can0 123#DEADBEAF

# 监听所有帧(另一个终端)
candump can0

如果你看到自己发的帧被回显,说明硬件和驱动都正常。接下来接上真实总线,记得两端各加一个 120Ω 终端电阻。我见过不少新手因为没加电阻,总线一直报错。

调试小技巧:用 canbusload 可以实时查看总线负载率。如果负载超过 70%,建议提高波特率或优化报文发送周期。

实际项目中,我经常需要把 CAN 数据转发到 ROS2 话题。这里给一个简单的 Python 示例,用 python-can 库读取并发布:

import can
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class CanBridge(Node):
    def __init__(self):
        super().__init__('can_bridge')
        self.pub = self.create_publisher(String, 'can_rx', 10)
        self.bus = can.interface.Bus(channel='can0', bustype='socketcan')
        self.timer = self.create_timer(0.01, self.read_can)

    def read_can(self):
        msg = self.bus.recv(timeout=0)
        if msg:
            self.pub.publish(String(data=str(msg)))

rclpy.init()
node = CanBridge()
rclpy.spin(node)

18.3 ROS2 集成

ROS2 在 Jetson 上的安装,我推荐用 Debian 包,省去编译时间。但如果你需要自定义消息或使用特定分支,那就用 colcon 从源码编译。

先装基础版:

sudo apt update
sudo apt install ros-humble-desktop python3-colcon-common-extensions
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

然后创建一个工作区,写一个简单的发布订阅节点。这里我展示一个发布“Hello from Jetson”的节点:

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python jetson_hello
cd jetson_hello/jetson_hello

编辑 publisher.py

import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class HelloNode(Node):
    def __init__(self):
        super().__init__('hello_node')
        self.pub = self.create_publisher(String, 'jetson_topic', 10)
        self.timer = self.create_timer(1.0, self.timer_callback)

    def timer_callback(self):
        msg = String()
        msg.data = 'Hello from Jetson Orin'
        self.pub.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)

def main(args=None):
    rclpy.init(args=args)
    node = HelloNode()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

编译并运行:

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

性能优化建议:Jetson 上跑 ROS2 时,如果节点很多,建议开启 DDS 的共享内存传输(Fast DDS 或 Cyclone DDS 都支持),减少网络栈开销。在 fastdds.xml 中配置 <transport_descriptor>shm 即可。

18.4 MQTT 物联网通信

MQTT 是物联网场景的首选协议,轻量、支持 QoS、有遗嘱消息。Jetson 作为边缘网关,非常适合跑 MQTT Broker 或 Client。

我一般用 mosquitto 做 Broker,安装简单:

sudo apt install mosquitto mosquitto-clients
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

测试发布与订阅:

# 终端1:订阅主题
mosquitto_sub -h localhost -t "jetson/test"

# 终端2:发布消息
mosquitto_pub -h localhost -t "jetson/test" -m "Hello MQTT from Jetson"

如果需要在 Jetson 上运行 MQTT Client 并上报传感器数据,我习惯用 Python 的 paho-mqtt 库:

import paho.mqtt.client as mqtt
import time

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("jetson/cmd")

def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("broker.emqx.io", 1883, 60)
client.loop_start()

# 每5秒发布一次CPU温度
while True:
    temp = open("/sys/class/thermal/thermal_zone0/temp").read().strip()
    client.publish("jetson/temp", temp)
    time.sleep(5)

安全提醒:生产环境中,一定要启用 MQTT 的用户名/密码认证和 TLS 加密。我曾经见过有人直接把 Broker 暴露在公网上,结果被植入了挖矿脚本。配置方式:mosquitto_passwd -c /etc/mosquitto/passwd youruser,然后在 mosquitto.conf 中开启 allow_anonymous falsepassword_file

好了,这一章的内容就到这里。WiFi/BT 让你无线连接,CAN 让你硬实时控制,ROS2 让多机协作,MQTT 让数据上云。把这四个工具用好,你的 Jetson 项目基本就打通了任督二脉。


公众号:蓝海资料掘金营,微信 deep3321