1. 项目概述:一个会动的可穿戴小玩意儿

如果你对嵌入式开发感兴趣,但又觉得Arduino的C++语法有点劝退,或者想快速做个能戴在手上的、带点互动性的小玩意儿,那这个项目可能正合你意。今天分享的,是一个我自己捣鼓出来的“笑脸旋转腕带”。它的核心很简单:一个由Adafruit Circuit Playground Express(后面简称CPX)开发板控制的伺服电机,带动一个3D打印的笑脸卡片旋转,所有东西都集成在一个可以戴在手腕上的带子里。

这不仅仅是一个手工活。它实际上是一个微型的嵌入式系统项目,涵盖了从3D建模打印、电路连接、到用CircuitPython编写控制代码的全流程。CircuitPython是MicroPython的一个分支,由Adafruit主导维护,最大的好处就是你可以用写Python脚本的方式去操控硬件,对于有Python基础的朋友来说,上手速度飞快。项目中用到的CPX板子更是“新手友好型”的典范,板载了加速度计、光线传感器、温度传感器、蜂鸣器、RGB LED灯环等一大堆玩意儿,但这次我们只用到它最基本的GPIO(通用输入输出)功能来控制一个伺服电机。

整个制作过程,你会接触到如何为CPX烧录CircuitPython固件、如何安装必要的代码库、如何用Mu编辑器写Python脚本,以及如何将代码、电池、电机和3D打印件巧妙地整合成一个坚固且可穿戴的整体。最终成品是一个充满童趣的互动装置,你可以把它看作是一个极简的、可穿戴的“情绪表达器”或者一个有趣的电子饰品原型。无论是用于学习嵌入式开发入门,还是作为一个小礼物,都很有成就感。

2. 核心思路与物料选型解析

2.1 为什么选择CPX和CircuitPython?

在做任何硬件项目前,选对核心控制器是关键。我选择Adafruit Circuit Playground Express(CPX)主要有几个考量。

首先, 集成度高,开箱即用 。CPX板子虽小,但“五脏俱全”。它集成了ATmega32u4微控制器和一系列传感器与外设。对于这个项目,我们虽然只用到它的GPIO口和电源输出,但其板载的USB接口和内置的UF2引导程序,使得烧录固件变得像拖放文件一样简单。这省去了额外购买USB转串口芯片的麻烦,也避免了新手在驱动安装上可能遇到的坑。

其次, CircuitPython的生态与易用性 。与传统的Arduino IDE(使用C/C++)相比,CircuitPython允许你用Python进行编程。Python语法简洁,可读性强,对于控制一个伺服电机这样的任务,几行代码就能搞定。更重要的是,Adafruit为CPX及各种扩展模块(如电机、显示屏等)提供了极其完善的CircuitPython代码库( adafruit_motor , adafruit_circuitplayground 等),我们直接调用封装好的函数即可,无需从零开始操作寄存器,大大降低了开发门槛和调试时间。

最后, 社区支持与教育资源丰富 。Adafruit的官方学习网站(learn.adafruit.com)上有海量的教程和项目,几乎你遇到的任何基础问题都能找到解答。这对于独立开发者或教育场景来说,意味着更低的试错成本和更平滑的学习曲线。

注意 :市面上也有其他优秀的MicroPython开发板,如ESP32系列。但CPX在“一体化”和“教育友好”方面做得更彻底,特别适合这种快速原型制作或入门教学项目。

2.2 伺服电机的选择:连续旋转与标准舵机之辨

项目里用到的是一个 连续旋转伺服电机 ,这和常见的、能精确控制角度的标准舵机有本质区别,选型时绝对不能搞混。

标准舵机(Positional Servo) :接收一个脉冲信号(通常是20ms周期的PWM波),通过脉冲宽度来控制输出轴旋转到某个特定角度(如0-180度)。它内部有电位器反馈,形成闭环控制,所以位置是固定的。常用于机器人关节、遥控车转向。

连续旋转伺服电机(Continuous Rotation Servo) :它被“改造”过了,移除了内部的定位电位器和机械限位。你发送的PWM信号不再对应一个角度,而是对应一个旋转速度和方向。例如,1.5ms的脉冲宽度代表停止,1.3ms代表全速逆时针旋转,1.7ms代表全速顺时针旋转。它本质上变成了一个带减速箱、可正反转、且速度可控的直流电机。

对于这个“笑脸旋转”项目,我们需要的是持续的、单向的旋转动画效果,而不是让笑脸停在某个角度。因此, 连续旋转舵机是唯一正确的选择 。如果你错误地使用了标准舵机,代码发送旋转指令后,它只会转到极限位置并卡住发出“滋滋”声,不仅无法实现效果,还可能因堵转而烧毁。

物料清单与采购建议 : 除了核心的CPX和伺服电机,其他材料大多是为了实现“可穿戴”和“结构固定”而服务的。以下是详细清单和替代方案思考:

  1. 核心电子部件

    • Adafruit Circuit Playground Express:项目大脑。
    • 连续旋转伺服电机:推荐Adafruit或SparkFun的品牌产品,质量有保障。
    • 锂离子电池(3.7V)与USB充电模块:为CPX和伺服电机供电。注意伺服电机工作电压(通常4.8-6V),CPX的Vout引脚输出的是板载稳压后的3.3V,驱动小型伺服电机勉强可以,但为了动力更足,本项目通过电池直接供电是更好的选择。
    • 鳄鱼夹测试线:用于快速连接CPX和伺服电机,无需焊接,非常适合原型验证。
  2. 结构与穿戴部件

    • 3D打印外壳(CPX固定座和电池盒):这是项目的骨架。自己用Fusion 360或Tinkercad建模并不难,关键是要留出CPX的引脚孔、电池仓和伺服电机的安装位。如果没条件3D打印,也可以用厚亚克力板激光切割,甚至用高密度泡沫塑料手工雕刻,核心是提供稳固的安装平台。
    • 螺丝螺母套装(M3规格):用于将CPX牢固地固定在打印件上,同时裸露的螺母柱可以作为鳄鱼夹的接线点。
    • 黑色弹性绷带/宽橡皮筋:制作腕带的主体。弹性材料能适应不同手腕尺寸,佩戴舒适。
    • 热熔胶枪和胶棒:万能固定工具,用于粘贴伺服电机、电池盒和笑脸装饰。
    • 强力胶(如Gorilla Glue):辅助固定,用于需要更强粘合力的部位(如伺服电机与电池盒的粘结)。
  3. 装饰与辅助材料

    • 硬卡纸:制作笑脸的基板。
    • 毛绒球、塑料眼睛:装饰笑脸。
    • 美工刀、尺子:用于裁剪卡纸。

3. 软件环境搭建与核心代码剖析

3.1 三步搭建CircuitPython开发环境

这一步是项目的软件基础,看似繁琐,但按步骤来一次搞定,后续会非常顺畅。

第一步:为CPX刷入CircuitPython固件

  1. 用USB数据线连接CPX和电脑。此时电脑会识别到一个名为 CPLAYBOOT 的U盘。
  2. 访问 circuitpython.org 网站,找到Circuit Playground Express的页面,下载最新的 .uf2 固件文件。
  3. 将下载的 .uf2 文件直接拖拽或复制到 CPLAYBOOT 磁盘中。CPX会自动重启,磁盘名称会变为 CIRCUITPY 。这表明固件刷写成功,CPX现在是一个CircuitPython设备了。

第二步:安装代码编辑器——Mu Editor 虽然可以用任何文本编辑器写代码,但我强烈推荐Mu Editor。它是专为教育设计的Python编辑器,内置了串行REPL(交互式命令行)控制台,能直接与CPX对话、查看打印信息,调试极其方便。从 codewith.mu 官网下载对应你操作系统的版本安装即可。

第三步:安装必要的CircuitPython库 CircuitPython的核心固件只包含最基本的功能,要控制伺服电机,需要额外的库文件。

  1. 再次访问 circuitpython.org,找到“Libraries”页面,下载适用于你CircuitPython版本的最新“库包”(是一个.zip文件)。
  2. 解压这个zip文件,在里面找到 lib 文件夹。
  3. 我们需要两个库: adafruit_motor (用于控制电机)和 adafruit_circuitplayground (用于访问CPX板载功能)。将这两个库的整个文件夹(例如 adafruit_motor adafruit_circuitplayground )复制到CPX的 CIRCUITPY 磁盘下的 lib 文件夹中。如果 lib 文件夹不存在,就自己新建一个。

完成以上三步,你的电脑和CPX就准备好了。打开Mu Editor,选择“CircuitPython”模式,连接好CPX,你就可以开始写代码了。

3.2 笑脸旋转的代码实现与逐行解读

控制连续旋转伺服电机的代码其实非常简洁。下面是我在项目中使用的代码 code.py ,它会被CPX自动运行。

import time
import board
import pwmio
from adafruit_motor import servo

# 1. 初始化PWM输出引脚
pwm = pwmio.PWMOut(board.A2, frequency=50) # 使用A2引脚,设置PWM频率为50Hz

# 2. 创建伺服电机对象
# 对于连续旋转舵机,我们需要指定最小和最大脉冲宽度(单位:微秒)
# 这些值可能需要根据你的具体舵机进行微调
my_servo = servo.ContinuousServo(pwm, min_pulse=750, max_pulse=2250)

# 3. 主循环:让笑脸持续旋转
while True:
    print("Spinning clockwise...") # 在串口输出信息,便于调试
    my_servo.throttle = 1.0  # 全速顺时针旋转(取值范围:-1.0 到 1.0)
    time.sleep(5.0)           # 旋转5秒钟

    print("Stopping...")
    my_servo.throttle = 0.0  # 停止
    time.sleep(2.0)           # 停止2秒钟

    print("Spinning counter-clockwise...")
    my_servo.throttle = -1.0 # 全速逆时针旋转
    time.sleep(5.0)

    print("Stopping...")
    my_servo.throttle = 0.0
    time.sleep(2.0)

代码关键点解析

  • pwmio.PWMOut :这是产生PWM(脉冲宽度调制)信号的核心。 board.A2 指定了使用CPX上的A2引脚作为信号输出端。 frequency=50 设置了PWM频率为50Hz,这是标准舵机通信的常见频率(周期20ms)。
  • servo.ContinuousServo :从 adafruit_motor 库中创建连续旋转舵机对象。 min_pulse max_pulse 参数至关重要,它们定义了对应“全速逆时针”和“全速顺时针”的脉冲宽度(单位微秒)。 750和2250是典型值,但不同品牌、甚至同品牌不同个体舵机都可能存在差异。如果发现舵机不转或转速不理想,调整这两个值是首要的调试步骤。
  • throttle 属性 :这是控制连续旋转舵机的“油门”。 1.0 代表一个方向的全速, -1.0 代表反方向的全速, 0.0 代表停止。它是一个浮点数,所以你也可以设置 0.5 来获得半速旋转。
  • time.sleep() :控制每个动作的持续时间。这里的循环让笑脸顺时针转5秒,停2秒,再逆时针转5秒,如此往复。你可以轻松修改这些数字来改变动画模式。

实操心得 :在将代码保存到CPX(文件会自动命名为 code.py )后,有时伺服电机可能不立即动作。一个常见的检查方法是:打开Mu Editor的“串行”控制台,查看是否有 print 语句的输出。如果有输出但电机不动,首先检查接线,然后尝试微调 min_pulse / max_pulse 值,例如尝试 (1300, 1700) 。另外,确保电池电量充足,伺服电机在低压下可能无法启动。

4. 硬件组装与机械结构详解

4.1 3D打印件的设计与固定要点

3D打印件是整个设备的骨架,其设计直接影响稳固性和美观度。我使用Tinkercad进行在线建模,主要设计了两部分:

  1. CPX固定座 :一个浅盘状结构,四周有立柱。关键点在于,立柱的位置必须与CPX板上的螺丝孔精确对应(CPX有多个GND和Vout孔,我们利用其中三个)。立柱内部需要预埋螺母(采用“热熔螺母”或“打印过程中嵌入”的方式),或者设计成通孔,方便从背面用螺丝固定。固定座底部还预留了通道,用于走线和容纳橡胶绑带。
  2. 电池盒 :一个简单的方盒,一侧开口用于放入电池和引出电线,另一侧设计一个平面,用于粘贴伺服电机。盒体需要紧密包裹电池,防止晃动,但也不能太紧导致难以放入。

打印参数建议

  • 材料 :PLA即可,它易于打印、强度足够且环保。
  • 层高 :0.2mm,在打印速度和表面光洁度间取得平衡。
  • 填充率 :20%-25%。不需要太高填充,节省材料和时间,但关键受力部位(如螺丝柱)可以在切片软件中设置局部加强。
  • 支撑 :对于CPX固定座的悬空部分(如下方走线槽的顶板),需要生成支撑。打印完成后需小心去除。

固定CPX :将M3螺丝穿过CPX板上的孔(我们使用GND、Vout和A2附近的孔),拧入打印件预埋的螺母中。 务必确保螺丝拧紧,使CPX与打印件之间没有晃动,同时裸露的螺丝头部将成为后续连接鳄鱼夹的接线点。

4.2 电路连接:从混乱到有序的布线艺术

电路连接的原则是: 安全第一,可靠第二,整洁第三 。使用鳄鱼夹虽然方便,但也容易变得杂乱。以下是清晰的接线逻辑:

  1. 伺服电机线序识别 :标准的3线伺服电机,线色通常是: 棕色(GND/地) 红色(VCC/电源正极) 橙色或黄色(Signal/信号线) 。务必确认你的电机线序。
  2. 电源连接 :将电池的正极(红线)和负极(黑线)连接到CPX的 Vout GND 引脚。 注意 :CPX的 Vout 输出是3.3V,而伺服电机通常需要4.8V以上才能正常工作。因此,更推荐的做法是,将电池的正极 同时 接到CPX的 Vout 引脚 伺服电机的 VCC (红线)。这样,CPX和伺服电机共享电池电源,且CPX内部的稳压电路不会因为伺服电机的大电流需求而过载。电池的负极则同时接到CPX的 GND 和伺服电机的 GND (棕线)。
  3. 信号连接 :伺服电机的信号线(橙线)连接到CPX的 A2 引脚。这是我们代码中指定的控制引脚。

如何实现“可穿戴”布线

  • 将伺服电机的三根线适当延长(可以用杜邦线焊接,或直接使用带延长线的舵机)。
  • 使用黑色弹性绷带,像包扎伤口一样,紧密地缠绕在这束电线上。从头到尾缠绕,两端用热熔胶或线扎固定。这既保护了电线,又形成了腕带的主体,弹性也保证了佩戴舒适。
  • 腕带的一端固定在伺服电机外壳上(用胶或绑带),另一端则准备一个可调节的活扣,用于连接CPX固定座上的橡胶绑带。

4.3 总装与穿戴结构集成

这是将各个模块集成为一体的过程,顺序很重要:

  1. 粘结伺服电机与电池盒 :在电池盒的指定平面和伺服电机底部涂抹足够多的热熔胶或强力胶,用力按压至少1-2分钟,确保粘牢。这是主要的受力点之一,务必牢固。
  2. 集成CPX模块与电池盒 :用一根宽厚的橡胶绑带,将CPX固定座和电池盒(连同已粘好的伺服电机)紧紧地绑在一起。绑成“8”字形或绕两圈,确保两者不会相对滑动。这个橡胶绑带也构成了腕带与主体之间的主要连接点。
  3. 连接腕带 :将制作好的弹性腕带(包裹着电线的那部分)的一端,塞入或绑在伺服电机与电池盒/CPX固定座之间的缝隙中,用胶加固。腕带的另一端(带活扣的)则穿过CPX固定座下方的橡胶绑带,实现可调节的佩戴闭环。
  4. 最终电路接线
    • 将电池放入电池盒,电线从预留孔引出。
    • 将腕带中引出的伺服电机三根线,用鳄鱼夹分别连接到CPX固定座上对应的螺丝头: 伺服电机GND(棕) -> CPX GND螺丝 伺服电机VCC(红) -> CPX Vout螺丝 (同时也是电池正极); 伺服电机Signal(橙) -> CPX A2螺丝
    • 将电池的正负极也通过鳄鱼夹连接到对应的 Vout GND 螺丝上。这样,所有电源和信号都在螺丝柱处汇合。
  5. 装饰与最终测试 :用卡纸剪一个圆,贴上眼睛和红色毛球做成笑脸,用热熔胶牢固地粘在伺服电机的输出轴上。粘之前,可以先让伺服电机转一下,确保笑脸的重心大致在中心,避免旋转时抖动过大。最后,插上电池,观察笑脸是否开始按代码设定的规律旋转。

避坑技巧 :在最终粘合所有东西之前,务必进行“裸板测试”。即在不安装到打印件、不缠绕腕带的情况下,用鳄鱼夹直接连接CPX、电池和伺服电机,运行代码,确保电机能正常响应。这能排除结构装配对电路造成的潜在影响。

5. 调试、优化与创意扩展

5.1 常见问题排查速查表

即使按照教程操作,也可能会遇到一些小问题。下面这个表格整理了常见故障现象、可能原因和解决方法:

现象 可能原因 排查与解决方法
上电后无任何反应 1. 电池电量耗尽或未接好。
2. CPX未正确启动。
3. 主电源回路断路。
1. 检查电池电压,确保正负极连接正确、牢固。
2. 按一下CPX上的复位键,看板载LED是否闪烁。
3. 用万用表通断档,从电池正极到CPX Vout,再到伺服电机VCC,最后回到电池负极,逐段检查线路。
CPX正常工作(LED亮),但伺服电机不转 1. 伺服电机接线错误(信号、电源、地接反)。
2. 代码未运行或引脚定义错误。
3. 伺服电机脉冲参数不匹配。
4. 电源功率不足。
1. 再次确认线序 :棕-GND,红-VCC,橙-Signal。
2. 打开Mu串行控制台,看是否有 print 输出。检查 code.py 是否在 CIRCUITPY 根目录。
3. 重点调整 :修改代码中的 min_pulse max_pulse 值,尝试 (1300, 1700) (1000, 2000) 等范围。
4. 尝试用USB供电(5V)替代电池,看是否转动。如果USB可以但电池不行,说明电池电量不足或内阻过大。
伺服电机抖动、异响或只向一个方向转 1. 脉冲宽度参数设置不当,导致“停止”信号不在电机的中立点。
2. 电源电压不稳定或不足。
3. 机械负载过重或卡住。
1. 微调 min_pulse max_pulse 。目标是找到使 throttle = 0 时电机完全静止的值。这需要耐心反复测试。
2. 检查所有接线点是否虚接,尤其是鳄鱼夹接触是否良好。更换电量更足的电池。
3. 检查笑脸是否粘歪,导致旋转不平衡。确保伺服电机输出轴转动顺畅。
笑脸旋转速度不稳定或时转时停 1. 电池在负载下电压骤降。
2. 鳄鱼夹接触电阻过大,时通时断。
3. 代码逻辑问题。
1. 使用容量更大的锂电池或并联电池。
2. 强烈建议 :在原型验证成功后,将关键电源连接点(电池到CPX、CPX到伺服电机)进行焊接,替代鳄鱼夹,可靠性大幅提升。
3. 检查代码中是否有异常长的 time.sleep 或复杂计算导致响应慢。
腕带佩戴不舒服或容易松脱 1. 弹性绷带太细或弹性不足。
2. 连接点(活扣、粘结处)不牢固。
1. 更换更宽、弹性更好的绷带,或在内部加一层柔软的绒布衬里。
2. 使用更可靠的机械连接,如塑料插扣,替代简单的打结或橡胶绑带。关键粘结处用环氧树脂AB胶加固。

5.2 项目优化与创意扩展思路

这个基础项目就像一个乐高底座,有巨大的扩展潜力。这里分享几个我尝试过或构思过的升级方向:

1. 交互升级:从自动到互动

  • 拍手启动 :利用CPX板载的声音传感器。修改代码,当检测到音量超过阈值(如拍手)时,才启动伺服电机旋转一段时间。
    from adafruit_circuitplayground import cp
    while True:
        if cp.sound_level > 100: # 阈值需要根据环境调整
            my_servo.throttle = 1.0
            time.sleep(3)
            my_servo.throttle = 0.0
    
  • 倾斜控制 :利用CPX的加速度计。将手腕的倾斜角度映射到伺服电机的旋转速度上,实现“手势控制”旋转。
    while True:
        x, y, z = cp.acceleration
        # 将X轴加速度映射到油门值(需校准)
        throttle = y / 10 # 简单映射,需限制在-1到1之间
        my_servo.throttle = max(-1.0, min(1.0, throttle))
        time.sleep(0.1)
    
  • 光控旋转 :利用光线传感器,在黑暗环境中停止旋转,在光亮环境下开始旋转,制作一个“光敏向日葵”。

2. 视觉与效果升级

  • LED灯效同步 :让CPX板载的10个NeoPixel RGB LED与旋转同步。例如,旋转时LED呈现追逐流光效果,停止时全部变为绿色。
  • 更换“表情盘” :不要局限于一个笑脸。可以打印多个圆盘,画上不同表情(开心、难过、惊讶),通过卡扣方式快速更换,让腕带能表达不同“情绪”。

3. 结构与应用场景扩展

  • 宠物项圈 :将尺寸放大,结构加强,固定在宠物项圈上。结合加速度计,当宠物剧烈奔跑或摇头时,笑脸开始旋转,成为一个有趣的宠物活动指示器。
  • 自行车装饰 :将设备固定在自行车车把或辐条上。利用加速度计检测自行车是否在移动,移动时笑脸旋转,停车时静止,增加骑行趣味。
  • 教学教具 :这是一个绝佳的STEAM教学项目。它直观地展示了编程(Python)、电子(电路、PWM)、机械(3D打印、传动)和艺术设计的结合。可以引导学生修改代码参数(如速度、方向、响应条件),观察物理现象的变化,深入理解因果关系。

这个项目的魅力在于,它用一个简单的动效,串联起了从数字代码到物理运动的完整链条。当你第一次看到自己编写的几行代码,驱动着一个实实在在的物体在手腕上旋转起来时,那种创造的快乐和成就感,是纯软件项目难以比拟的。它不只是一个玩具,更是一个通向更广阔硬件创作世界的敲门砖。

更多推荐