logo Mr.Robota 具身智能学习手册 EN
第十六章:专题组队学习

README 03 补充材料:基础外设脚本与按钮检测源码

本文件是README_03_快速入门与基础外设.md的补充阅读材料。正文已经完成了从开机、按钮体验到基础外设测试的主线操作,这一份补充材料则把几个最值得保留的底层脚本单独拎出来讲清楚,帮助读者把“会按、会跑”进一步过渡到“看得懂、改得动”。

需要先说明的是,下面整理的代码片段来自板端目录 /userdata/magicbox/basic_function_demo/。它们不是完整产品逻辑的全部实现,而是官方镜像为了教学和硬件验证保留下来的最小示例。因此,阅读它们的重点不是追求代码复杂度,而是理解每一种硬件外设在板端究竟是怎样被访问、初始化和控制的。

一、舵机脚本:理解 PWM 控制的最小入口

servo.py 是最容易读懂、也最适合初学者上手的一段脚本。它直接使用 Hobot.GPIO 打开两个支持 PWM 的管脚,并以 50Hz 的频率输出占空比,从而驱动两个舵机动作。核心代码如下。

pythonoutput_pin = 32
output1_pin = 33

GPIO.setmode(GPIO.BOARD)
p = GPIO.PWM(output_pin, 50)
p1 = GPIO.PWM(output1_pin, 50)
p.ChangeDutyCycle(5)
p.start(5)
p1.ChangeDutyCycle(11)
p1.start(11)

这一段代码传递了三个非常关键的信息。第一,Magicbox 上的舵机控制并不是一个“黑箱能力”,底层仍然是标准的 PWM 输出。第二,官方示例使用的是 BOARD 编号模式,因此在自己改脚本时,必须确认采用的是板级针脚编号而不是 BCM 编号。第三,舵机动作最终还是由占空比决定,后续不论是手势交互还是大模型 function call,只要它们要带动物理动作,本质上都要落回这一层控制逻辑。

这个脚本的价值并不在于“执行一次就结束”,而在于它给后续所有动作类章节建立了一个最小认知模型:上层是手势、语音或 LLM,下层始终是 PWM 控制。

二、灯带脚本:理解 WS2812B 为何走 SPI 而不是普通 GPIO

ws2812b.py 展示的是另一种非常典型的板端控制方式。WS2812B 灯珠对时序要求严格,官方脚本没有用简单的高低电平翻转来“硬怼”时序,而是把每一个 RGB 数据编码成 SPI 比特流,再通过 spidev 发出去。核心结构如下。

pythonWS2812B_BIT_PATTERNS = {
    0: [1, 0, 0],
    1: [1, 1, 0],
}

self.spi = spidev.SpiDev()
self.spi.open(1, 0)
self.spi.max_speed_hz = spi_speed
self.spi.mode = 0

这说明 Magicbox 的灯光控制并不是单纯的“设置一个颜色值”,而是通过 SPI 把编码后的时序数据整体送到灯带。脚本里还保留了一个很有教学意义的细节:WS2812B 使用的是 GRB 顺序,而不是很多初学者直觉里的 RGB 顺序。正是因为这些底层细节容易被忽略,才更值得在教程里单独讲出来。

如果你后面打算把 OpenClaw、nanobot 或自定义桌宠逻辑接到 Magicbox 上,这个脚本其实就是最自然的“灯光桥接层”。远端助手不需要懂 SPI 协议,它只需要调用一个本地脚本接口,由这层脚本负责把颜色和时序转换成设备可执行的控制命令。

三、IMU 脚本:理解姿态传感器为什么是 I2C 读取

imu.py 展示的是传感器读取的另一条典型路线。脚本通过 smbus2.SMBus(5) 打开 I2C 总线 5,与地址为 0x68 的 ICM20948 通信,然后读取加速度计和陀螺仪寄存器,再把原始值换算成 m/s² 与 rad/s。核心逻辑如下。

pythonICM20948_ADDRESS = 0x68
bus = smbus2.SMBus(5)

ax = read_i2c_word(ACCEL_XOUT_H) * accel_scale
gy = read_i2c_word(GYRO_XOUT_H + 2) * gyro_scale

这一段的意义,在于它帮助读者建立“视觉、动作、传感器”三类外设的差异认识。舵机是 PWM,灯带是 SPI,IMU 是 I2C。Magicbox 之所以适合做多模态平台,不是因为官方把所有能力都封装成一个统一 API,而是因为板端本身就把这些常见硬件接口都准备好了。真正懂了这一点,后续无论接 OpenClaw 还是自己写桌宠状态机,都不会把“感知”和“执行”混成同一种控制方式。

四、按钮脚本:它能说明硬件接法,但不能替代系统启动入口

button.py 很容易被误读。很多人看到它监控三个 GPIO 管脚,就会以为它就是整套“三键启动三种功能”的正式实现。实际上,这段脚本只完成了一个更基础的任务:等待三个按键的下降沿事件,然后在终端打印 button1 OK、button2 OK、button3 OK。核心代码如下。

pythonGPIO.setmode(GPIO.BCM)
GPIO.setup(pin1, GPIO.IN)
GPIO.setup(pin2, GPIO.IN)
GPIO.setup(pin3, GPIO.IN)

GPIO.wait_for_edge(self.pin1, GPIO.FALLING)
print("button1 OK")

这意味着它更像是“按钮硬件是否接通”的检测脚本,而不是产品级调度器。也正因为如此,这个脚本在教程中的位置应该是“辅助理解硬件通路”,而不是“系统预置应用的源码入口”。前者回答的是“按钮有没有被读到”,后者回答的是“按钮按下以后为什么会启动双目、手势或语音”。这两个问题必须分开讲,否则读者会把硬件测试脚本误当成整机控制框架。

五、这一份补充材料应该怎样使用

更高效的使用方式不是把四个脚本机械背下来,而是把它们当作四个底层接口的样板。学习完正文以后,再回头看这一份补充材料,读者应当能建立起这样一种理解:当上层应用需要动作时,通常会落到 PWM;当需要灯光反馈时,通常会落到 SPI;当需要姿态数据时,通常会落到 I2C;当需要物理按钮作为启动或切换信号时,首先要解决的是 GPIO 事件监听。

一旦这条底层认知建立起来,Magicbox 就不再只是一块“会跑 demo 的开发板”,而是一套可被二次开发、可被桥接、也可被重新编排的硬件系统。后面的双目、手势、语音和 OpenClaw 章节,都会建立在这一层理解之上。