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和伺服电机,其他材料大多是为了实现“可穿戴”和“结构固定”而服务的。以下是详细清单和替代方案思考:
核心电子部件:
- Adafruit Circuit Playground Express:项目大脑。
- 连续旋转伺服电机:推荐Adafruit或SparkFun的品牌产品,质量有保障。
- 锂离子电池(3.7V)与USB充电模块:为CPX和伺服电机供电。注意伺服电机工作电压(通常4.8-6V),CPX的Vout引脚输出的是板载稳压后的3.3V,驱动小型伺服电机勉强可以,但为了动力更足,本项目通过电池直接供电是更好的选择。
- 鳄鱼夹测试线:用于快速连接CPX和伺服电机,无需焊接,非常适合原型验证。
结构与穿戴部件:
- 3D打印外壳(CPX固定座和电池盒):这是项目的骨架。自己用Fusion 360或Tinkercad建模并不难,关键是要留出CPX的引脚孔、电池仓和伺服电机的安装位。如果没条件3D打印,也可以用厚亚克力板激光切割,甚至用高密度泡沫塑料手工雕刻,核心是提供稳固的安装平台。
- 螺丝螺母套装(M3规格):用于将CPX牢固地固定在打印件上,同时裸露的螺母柱可以作为鳄鱼夹的接线点。
- 黑色弹性绷带/宽橡皮筋:制作腕带的主体。弹性材料能适应不同手腕尺寸,佩戴舒适。
- 热熔胶枪和胶棒:万能固定工具,用于粘贴伺服电机、电池盒和笑脸装饰。
- 强力胶(如Gorilla Glue):辅助固定,用于需要更强粘合力的部位(如伺服电机与电池盒的粘结)。
装饰与辅助材料:
- 硬卡纸:制作笑脸的基板。
- 毛绒球、塑料眼睛:装饰笑脸。
- 美工刀、尺子:用于裁剪卡纸。
3. 软件环境搭建与核心代码剖析
3.1 三步搭建CircuitPython开发环境
这一步是项目的软件基础,看似繁琐,但按步骤来一次搞定,后续会非常顺畅。
第一步:为CPX刷入CircuitPython固件
- 用USB数据线连接CPX和电脑。此时电脑会识别到一个名为
CPLAYBOOT的U盘。 - 访问 circuitpython.org 网站,找到Circuit Playground Express的页面,下载最新的
.uf2固件文件。 - 将下载的
.uf2文件直接拖拽或复制到CPLAYBOOT磁盘中。CPX会自动重启,磁盘名称会变为CIRCUITPY。这表明固件刷写成功,CPX现在是一个CircuitPython设备了。
第二步:安装代码编辑器——Mu Editor虽然可以用任何文本编辑器写代码,但我强烈推荐Mu Editor。它是专为教育设计的Python编辑器,内置了串行REPL(交互式命令行)控制台,能直接与CPX对话、查看打印信息,调试极其方便。从 codewith.mu 官网下载对应你操作系统的版本安装即可。
第三步:安装必要的CircuitPython库CircuitPython的核心固件只包含最基本的功能,要控制伺服电机,需要额外的库文件。
- 再次访问 circuitpython.org,找到“Libraries”页面,下载适用于你CircuitPython版本的最新“库包”(是一个.zip文件)。
- 解压这个zip文件,在里面找到
lib文件夹。 - 我们需要两个库:
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的“串行”控制台,查看是否有min_pulse/max_pulse值,例如尝试(1300, 1700)。另外,确保电池电量充足,伺服电机在低压下可能无法启动。
4. 硬件组装与机械结构详解
4.1 3D打印件的设计与固定要点
3D打印件是整个设备的骨架,其设计直接影响稳固性和美观度。我使用Tinkercad进行在线建模,主要设计了两部分:
- CPX固定座:一个浅盘状结构,四周有立柱。关键点在于,立柱的位置必须与CPX板上的螺丝孔精确对应(CPX有多个GND和Vout孔,我们利用其中三个)。立柱内部需要预埋螺母(采用“热熔螺母”或“打印过程中嵌入”的方式),或者设计成通孔,方便从背面用螺丝固定。固定座底部还预留了通道,用于走线和容纳橡胶绑带。
- 电池盒:一个简单的方盒,一侧开口用于放入电池和引出电线,另一侧设计一个平面,用于粘贴伺服电机。盒体需要紧密包裹电池,防止晃动,但也不能太紧导致难以放入。
打印参数建议:
- 材料:PLA即可,它易于打印、强度足够且环保。
- 层高:0.2mm,在打印速度和表面光洁度间取得平衡。
- 填充率:20%-25%。不需要太高填充,节省材料和时间,但关键受力部位(如螺丝柱)可以在切片软件中设置局部加强。
- 支撑:对于CPX固定座的悬空部分(如下方走线槽的顶板),需要生成支撑。打印完成后需小心去除。
固定CPX:将M3螺丝穿过CPX板上的孔(我们使用GND、Vout和A2附近的孔),拧入打印件预埋的螺母中。务必确保螺丝拧紧,使CPX与打印件之间没有晃动,同时裸露的螺丝头部将成为后续连接鳄鱼夹的接线点。
4.2 电路连接:从混乱到有序的布线艺术
电路连接的原则是:安全第一,可靠第二,整洁第三。使用鳄鱼夹虽然方便,但也容易变得杂乱。以下是清晰的接线逻辑:
- 伺服电机线序识别:标准的3线伺服电机,线色通常是:棕色(GND/地)、红色(VCC/电源正极)、橙色或黄色(Signal/信号线)。务必确认你的电机线序。
- 电源连接:将电池的正极(红线)和负极(黑线)连接到CPX的
Vout和GND引脚。注意:CPX的Vout输出是3.3V,而伺服电机通常需要4.8V以上才能正常工作。因此,更推荐的做法是,将电池的正极同时接到CPX的Vout引脚和伺服电机的VCC(红线)。这样,CPX和伺服电机共享电池电源,且CPX内部的稳压电路不会因为伺服电机的大电流需求而过载。电池的负极则同时接到CPX的GND和伺服电机的GND(棕线)。 - 信号连接:伺服电机的信号线(橙线)连接到CPX的
A2引脚。这是我们代码中指定的控制引脚。
如何实现“可穿戴”布线:
- 将伺服电机的三根线适当延长(可以用杜邦线焊接,或直接使用带延长线的舵机)。
- 使用黑色弹性绷带,像包扎伤口一样,紧密地缠绕在这束电线上。从头到尾缠绕,两端用热熔胶或线扎固定。这既保护了电线,又形成了腕带的主体,弹性也保证了佩戴舒适。
- 腕带的一端固定在伺服电机外壳上(用胶或绑带),另一端则准备一个可调节的活扣,用于连接CPX固定座上的橡胶绑带。
4.3 总装与穿戴结构集成
这是将各个模块集成为一体的过程,顺序很重要:
- 粘结伺服电机与电池盒:在电池盒的指定平面和伺服电机底部涂抹足够多的热熔胶或强力胶,用力按压至少1-2分钟,确保粘牢。这是主要的受力点之一,务必牢固。
- 集成CPX模块与电池盒:用一根宽厚的橡胶绑带,将CPX固定座和电池盒(连同已粘好的伺服电机)紧紧地绑在一起。绑成“8”字形或绕两圈,确保两者不会相对滑动。这个橡胶绑带也构成了腕带与主体之间的主要连接点。
- 连接腕带:将制作好的弹性腕带(包裹着电线的那部分)的一端,塞入或绑在伺服电机与电池盒/CPX固定座之间的缝隙中,用胶加固。腕带的另一端(带活扣的)则穿过CPX固定座下方的橡胶绑带,实现可调节的佩戴闭环。
- 最终电路接线:
- 将电池放入电池盒,电线从预留孔引出。
- 将腕带中引出的伺服电机三根线,用鳄鱼夹分别连接到CPX固定座上对应的螺丝头:伺服电机GND(棕)->CPX GND螺丝;伺服电机VCC(红)->CPX Vout螺丝(同时也是电池正极);伺服电机Signal(橙)->CPX A2螺丝。
- 将电池的正负极也通过鳄鱼夹连接到对应的
Vout和GND螺丝上。这样,所有电源和信号都在螺丝柱处汇合。
- 装饰与最终测试:用卡纸剪一个圆,贴上眼睛和红色毛球做成笑脸,用热熔胶牢固地粘在伺服电机的输出轴上。粘之前,可以先让伺服电机转一下,确保笑脸的重心大致在中心,避免旋转时抖动过大。最后,插上电池,观察笑脸是否开始按代码设定的规律旋转。
避坑技巧:在最终粘合所有东西之前,务必进行“裸板测试”。即在不安装到打印件、不缠绕腕带的情况下,用鳄鱼夹直接连接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打印、传动)和艺术设计的结合。可以引导学生修改代码参数(如速度、方向、响应条件),观察物理现象的变化,深入理解因果关系。
这个项目的魅力在于,它用一个简单的动效,串联起了从数字代码到物理运动的完整链条。当你第一次看到自己编写的几行代码,驱动着一个实实在在的物体在手腕上旋转起来时,那种创造的快乐和成就感,是纯软件项目难以比拟的。它不只是一个玩具,更是一个通向更广阔硬件创作世界的敲门砖。