第一章:舵机控制板(PCA9685A)¶
这款舵机控制板的功能是接受上位机发送的I2C信号,通过芯片解码为十六路舵机的控制指令,进而实现舵机的扩展控制。 之所以采用这个舵机控制板进行舵机控制原因如下: 在2025年的备赛中,我们采用了机载计算机通过串口与一个单片机通信,单片机接受串口信号,收到之后解码去控制两路舵机。但是实际验证后,这种做法的风险高,时常出现控制失灵或不稳定的情况。这在比赛中是致命的。 在2026年的备赛中,我们针对以上问题进行了解决。首先我们想到使用机载计算机与飞控之间的通信是相对稳定的,于是我们想到机载计算机通过mavros与飞控通信,去控制接在飞控空闲通道上的舵机去实现投放任务,但是经过我们的研究,由于飞控固件版本问题与某些未知的问题,始终无法实现计算机对舵机的控制,于是我们更换方案。幸运的是我们今年经费充足的情况下更换了Jetson系列电脑,这个电脑的主板上带有可编程控制的GPIO接口。进一步我们尝试了直接驱动GPIO输出PWM波去控制舵机。我们确实能成功控制舵机,但是实测这个方案的稳定性也不足,时常出现控制错误的奇怪问题(比如代码控制1号舵机,但是2号舵机运动)。我们探求原因,找到是系统定时器资源有限,控制pwm时,后初始化的舵机对象会覆盖掉先初始化舵机对象的定时器资源,表现为控制混乱。于是我们就找到了这款舵机控制板,在机载计算机配置I2C输出,与这个控制板通信,得到了较为稳定可靠的舵机投放控制。下文介绍Jetson与舵机控制板的通信的具体配置方式。
第二章:Jetson I2C 与 Adafruit ServoKit 安装配置记录¶
本章整理了 Jetson 设备上检查 I2C、判断是否需要启用接口,以及安装 adafruit_servokit 的操作步骤。
1. 检查系统中已有的 I2C 总线¶
先安装常用工具:
加载 I2C 用户态设备模块:
检查系统中是否已经有 I2C 设备节点:
查看 I2C 总线列表:
如果能看到类似下面的输出,说明系统已经注册了 I2C 总线:
注意:/dev/i2c-1 中的 1 不一定等于硬件文档里的 I2C1,需要结合 Jetson 型号和 i2cdetect -l 输出判断。
2. Jetson-IO 页面中是否需要选择功能¶
如果进入 Jetson-IO 后看到类似这些选项:
这些都不是 I2C。
含义大致如下:
| 选项 | 含义 |
|---|---|
i2s2 |
音频 I2S 接口 |
pwm1 / pwm5 / pwm7 |
PWM 输出 |
spi1 / spi3 |
SPI 总线 |
uart-cts/rts |
UART 串口硬件流控 |
aud / extperiph*_clk |
音频或外设时钟相关功能 |
如果目标是使用 I2C 设备,不需要勾选这些选项。
截图里没有 i2c 选项,通常说明:
- 40-pin 上的 I2C 已经默认启用;
- 当前板子的 I2C 不是通过 Jetson-IO 这个页面切换;
- 需要通过设备树或 pinmux 配置,但这通常是自定义载板才需要。
3. 扫描 I2C 设备¶
接好 I2C 设备后,先确认接线:
| Jetson | I2C 设备 |
|---|---|
3.3V |
VCC |
GND |
GND |
SDA |
SDA |
SCL |
SCL |
然后扫描常见总线:
如果没有发现设备,可以根据 i2cdetect -l 的结果尝试其他总线,例如:
如果使用的是 Adafruit PCA9685 舵机驱动板,默认地址通常是:
扫描结果中看到 40,通常表示 PCA9685 已被识别。
4. 安装 Adafruit ServoKit¶
Python 导入名是:
但 pip 安装包名是:
直接安装:
安装完成后测试导入:
如果输出:
说明安装成功。
5. 如果 pip 报 externally-managed-environment¶
部分系统不允许直接向系统 Python 安装包,可能出现 externally-managed-environment 报错。
这种情况下建议使用虚拟环境:
python3 -m venv ~/servokit-env
source ~/servokit-env/bin/activate
pip install adafruit-blinka adafruit-circuitpython-servokit
以后运行程序前先进入虚拟环境:
6. ServoKit 简单测试程序¶
如果 I2C 能扫描到 PCA9685,例如地址为 0x40,可以创建测试脚本:
运行:
如果遇到 I2C 权限问题,可以先用 sudo 测试:
更长期的做法是把当前用户加入 I2C 相关用户组,具体组名以系统为准。
7. 常见问题¶
7.1 找不到 /dev/i2c*¶
先执行:
如果仍然没有,说明当前系统没有启用对应 I2C 控制器,或者设备树/pinmux 未配置好。
7.2 Jetson-IO 里没有 I2C 选项¶
这是常见情况。不要选择 spi、pwm、i2s 来代替 I2C。
应先用下面命令确认系统是否已有 I2C 总线:
7.3 i2cdetect 扫不到设备¶
检查以下内容:
- 设备是否供电;
SDA和SCL是否接反;- 是否共地;
- I2C 设备是否只支持 3.3V 或 5V;
- 是否有上拉电阻;
- 是否扫描了正确的 I2C bus;
- 设备地址是否和默认地址不同。
7.4 不建议直接使用 Raspberry Pi 的 dtoverlay¶
Jetson 与 Raspberry Pi 的设备树加载方式不同。
在 Jetson 上通常使用:
或根据 Jetson Linux 文档配置 DTB/DTBO 与 /boot/extlinux/extlinux.conf。
不要直接照搬:
这通常不是 Jetson 的正确操作方式。
8. 推荐执行顺序¶
完整流程建议如下:
sudo apt update
sudo apt install -y i2c-tools python3-pip python3-venv git
sudo modprobe i2c-dev
ls -l /dev/i2c*
i2cdetect -l
sudo i2cdetect -r -y 1
python3 -m pip install adafruit-blinka
python3 -m pip install adafruit-circuitpython-servokit
python3 -c "from adafruit_servokit import ServoKit; print('ServoKit OK')"
如果 pip install 报错,则改用虚拟环境: