1. 项目概述一个能走会跳的桌面伙伴几年前我第一次接触Otto机器人时就被它那种用最简单结构实现拟人化动作的设计哲学吸引了。它不像那些动辄十几个舵机、结构复杂的机器人Otto用四个舵机——两条腿、两只脚——就实现了行走、跳舞甚至避障把机器人的入门门槛拉低到了每个爱好者都能轻松尝试的程度。这次我决定用当下性价比和性能都相当出色的Raspberry Pi Pico作为它的大脑再搭配上PCA9685这颗多路PWM驱动芯片来一次从零开始的搭建。这个组合的好处很明显Pico负责逻辑和传感器数据处理PCA9685则解放了Pico的GPIO让它能同时、稳定地驱动多个舵机而不用担心引脚不够或信号冲突。最终做出来的这个小家伙不仅能稳稳当当地走路还能跟着节奏摇摆遇到障碍物还会聪明地转身整个过程就像在组装一个会动的乐高充满了动手的乐趣和看到代码“活”过来的成就感。无论你是刚对机器人产生兴趣的学生还是想找个周末项目练手的硬件爱好者这个指南都会带你一步步走完硬件组装、电路焊接和软件编程的全过程。2. 核心硬件选型与设计思路解析2.1 主控与驱动为什么是Pico PCA9685选择Raspberry Pi Pico作为主控核心看中的是它的RP2040双核ARM Cortex-M0处理器和丰富的GPIO资源。对于Otto机器人这种需要实时处理传感器数据超声波测距并生成控制信号的项目Pico的性能绰绰有余。更重要的是其Arduino兼容生态非常成熟这意味着我们可以用熟悉的Arduino IDE进行开发省去了学习新开发环境的成本。但Pico直接驱动多个舵机存在两个问题一是GPIO数量虽然Pico引脚不少但我们需要预留接口给超声波传感器和其他可能的扩展二是PWM信号质量。SG90这类舵机对PWM信号的稳定性要求较高如果由主控直接生成多路PWM在代码复杂时可能会因CPU负载导致信号抖动进而引起舵机抖动或发热。这时PCA9685芯片的价值就凸显出来了。这是一款基于I2C通信的16通道PWM伺服驱动器。你只需要用Pico的两个GPIOSDA和SCL通过I2C协议与它通信告诉它每个通道的舵机应该转到什么角度剩下的波形生成工作就完全由PCA9685独立完成。它内部有独立的振荡器和分频器能产生非常稳定、精确的50Hz PWM信号对应舵机控制的标准周期彻底解放了主控也让舵机运行得更平稳、更安静。2.2 执行机构与结构四自由度设计的巧妙之处Otto机器人的运动核心是四个SG90微型舵机。这种舵机价格低廉、扭矩适中1.6kg/cm左右非常适合桌面级机器人的关节驱动。它的运动原理是通过内部的控制电路、电机和齿轮组将输入PWM信号的脉冲宽度通常在0.5ms到2.5ms之间线性地转换为输出轴的绝对角度通常为0-180度。机器人的结构设计采用了经典的四自由度4-DOF双足方案两个舵机控制髋关节左右腿负责机器人的左右摆动和前后迈步另外两个舵机控制膝关节左右脚负责抬脚和落脚动作。这个结构虽然简单但通过四个舵机的时序配合足以模拟出步行、旋转、舞蹈等多种步态。3D打印的机身不仅轻量化而且为舵机、线缆和主板提供了精确的安装位和走线通道这是保证动作流畅性的物理基础。在材料选择上PLA或PETG都是不错的选择它们有足够的强度且易于打印。2.3 感知与供电让机器人拥有“视觉”和“活力”为了让Otto能与环境互动我们为其加装了HC-SR04超声波传感器。它通过发射超声波并接收回波计算时间差来测量距离。其探测范围在2cm到400cm之间精度对于桌面避障完全足够。我们将它安装在机器人身体前方作为其“眼睛”。供电方案需要仔细考量。四个舵机在运动时尤其是启动瞬间电流需求可能超过1A。普通的USB供电5V/0.5A或1A可能无法满足会导致Pico重启或舵机无力。因此采用独立的9V电池供电是更可靠的选择。这里使用LM7805线性稳压器将9V降压至稳定的5V。需要注意的是LM7805在压差较大9V-5V4V时会产生较多热量因此建议为其加装一个小型散热片。这个5V电源同时为PCA9685和所有舵机供电而Pico的3.3V引脚则单独为超声波传感器供电以避免大电流负载对敏感的逻辑传感器造成电压波动干扰。3. 硬件组装与电路连接实操详解3.1 机械结构组装精度决定动作的流畅度拿到3D打印的零件后第一步不是急着组装而是先进行“假组”。用手将舵机尝试放入腿部和身体的安装槽内检查配合是否过紧或过松。如果过紧需要用美工刀或小锉刀仔细修整孔槽内部确保舵机外壳能平整放入且输出轴能对准结构上的孔位。这是一个需要耐心的过程因为任何一点卡滞都会在运行时转化为额外的负载导致舵机堵转、发热甚至损坏。安装舵机时务必先不要上螺丝。将舵机通过杜邦线临时连接到PCA9685或一个舵机测试器上通过发送90度中位信号确认舵机处于零点位置。然后再将舵机的输出盘舵盘安装到机器人的关节连接处。这个步骤至关重要它确保了在软件初始化时所有舵机都处于一个已知的、机械中立的物理位置。如果跳过这一步直接固定很可能导致机器人的初始姿态就是歪斜的后续所有动作都会基于这个错误零点进行计算轻则动作怪异重则可能因为关节极限位置冲突而损坏结构。固定舵机建议使用配套的短螺丝。在拧紧螺丝时力度要均匀适中以舵机不再晃动为准切忌过度用力导致塑料壳体开裂。完成腿部与身体的连接后用手轻轻转动各个关节感受是否有不顺畅的阻力点。同时将所有舵机线缆顺着3D打印件上设计的线槽进行规整并用扎带或胶带固定避免在运动过程中线缆被关节夹住或拉扯。3.2 核心电路焊接构建可靠的电气骨架为了系统的可靠性强烈建议使用一块洞洞板或定制PCB来搭建核心电路而不是只用杜邦线插接。插接方式在机器人运动振动下容易松脱。焊接的步骤可以遵循以下顺序电源模块焊接首先焊接LM7805稳压电路。将LM7805固定在洞洞板上输入脚IN连接9V电池扣的正极红线接地脚GND连接电池扣的负极黑线和整个电路的GND总线。输出脚OUT输出5V这里需要连接一个100μF以上的电解电容正极接OUT负极接GND进行滤波以平滑舵机动作引起的电压波动。5V输出将作为PCA9685的VCC和舵机的电源正极。控制模块焊接焊接PCA9685模块。通常PCA9685模块本身已集成稳压和滤波电路。我们只需焊接排针并将其连接到主板VCC接刚才的5VGND接公共地SCL和SDA分别接Pico的GP2和GP3。请注意PCA9685模块上可能还有一个V或Vin引脚那是直接给舵机供电的输入口通常需要接5V-6V。根据模块设计有时需要将VCC和V用跳线帽短接意味着逻辑和舵机共用一路5V电。在我们的方案中直接将LM7805输出的5V同时接到模块的VCC和V即可。主控与传感器焊接焊接Raspberry Pi Pico的排针。将Pico的GND接入公共地VSYS或VBUS引脚可以接5V为其供电。然后连接传感器超声波传感器的VCC接Pico的3.3V输出引脚而非5VGND接公共地Trig引脚接GP6Echo引脚接GP7。舵机线缆焊接将四个舵机的三根线红-电源正棕-地橙-信号焊接延长并统一连接到主板。所有舵机的红线并接到5V电源总线棕线并接到GND总线。信号线则分别连接到PCA9685的通道0、1、2、3。建议使用不同颜色的导线区分并在末端贴上标签便于后续调试。焊接完成后先不要安装电池。用USB线连接Pico和电脑使用万用表测量5V和3.3V输出是否正常检查各电源与地之间有无短路。3.3 系统集成与上电前检查将所有模块通过排线或焊接好的导线连接起来。连接关系总结如下表组件连接至引脚/通道说明PCA9685 VCCLM7805 5V输出-模块逻辑供电PCA9685 VLM7805 5V输出-舵机供电输入与VCC短接PCA9685 GND公共GND-接地PCA9685 SCLRaspberry Pi PicoGP2I2C时钟线PCA9685 SDARaspberry Pi PicoGP3I2C数据线舵机0 (左腿)PCA9685Channel 0信号线橙舵机1 (右腿)PCA9685Channel 1信号线橙舵机2 (左脚)PCA9685Channel 2信号线橙舵机3 (右脚)PCA9685Channel 3信号线橙所有舵机 红/棕电源总线 / GND总线-并联连接HC-SR04 VCCRaspberry Pi Pico3.3V OUT传感器逻辑供电HC-SR04 GND公共GND-接地HC-SR04 TrigRaspberry Pi PicoGP6触发引脚HC-SR04 EchoRaspberry Pi PicoGP7回波引脚注意首次上电前请务必进行“三检查”一查电源正负极是否接反特别是电池扣和LM7805二查有无焊锡短路特别是PCA9685和Pico引脚密集处三查舵机信号线是否接对了通道。确认无误后可以先不装电池仅通过USB给Pico供电观察各模块指示灯是否正常PCA9685通常有电源灯。然后再连接9V电池此时应听到舵机轻微归位的声音如果已上传初始化代码。4. 软件开发环境配置与核心代码剖析4.1 Arduino IDE环境搭建与库安装虽然Raspberry Pi Pico可以用MicroPython或C SDK开发但为了利用丰富的Arduino生态特别是伺服控制库我们选择Arduino IDE。配置步骤如下打开Arduino IDE进入“文件”-“首选项”。在“附加开发板管理器网址”中添加以下URLhttps://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json。这个地址包含了社区维护的RP2040Pico芯片支持包。点击“确定”后进入“工具”-“开发板”-“开发板管理器”。在搜索框中输入“pico”你会找到“Raspberry Pi Pico/RP2040 by Earle F. Philhower, III”。点击并安装这个开发板支持包。安装完成后在“工具”-“开发板”列表中选择“Raspberry Pi Pico”。接下来安装必要的库。进入“工具”-“管理库...”搜索“Adafruit PWM Servo Driver Library”并安装。这个库封装了与PCA9685通信的所有底层细节让我们可以用简单的函数控制舵机角度。同样在库管理中搜索“Ultrasonic”或“HCSR04”安装一个常用的超声波传感器库例如“Ultrasonic by Erick Simões”。这能简化距离测量的代码。连接Pico到电脑时需要先按住Pico上的“BOOTSEL”按钮不放再插入USB线然后松开按钮。这时电脑会识别出一个名为“RPI-RP2”的U盘。在Arduino IDE中选择对应的串口端口如COMx或/dev/ttyACM0就可以开始上传程序了。4.2 舵机控制原理与PCA9685库的使用舵机的控制本质是发送一个周期为20ms50Hz脉冲宽度在0.5ms到2.5ms之间的PWM信号。脉冲宽度对应着0到180度的角度。PCA9685库将这个过程抽象得非常简单。首先需要在代码开始定义PCA9685对象并设置I2C地址默认0x40#include Wire.h #include Adafruit_PWMServoDriver.h Adafruit_PWMServoDriver pwm Adafruit_PWMServoDriver();在setup()函数中初始化I2C通信并设置PWM频率void setup() { Serial.begin(115200); pwm.begin(); pwm.setPWMFreq(50); // 针对舵机设置为50Hz }库函数setPWMFreq(50)非常关键它配置了PCA9685内部振荡器使其输出符合舵机要求的50Hz基准频率。接下来是核心如何将角度值0-180转换为PCA9685能理解的“脉宽计数”值。PCA9685内部有一个12位的计数器0-4095对应一个完整的PWM周期20ms。我们需要计算给定脉宽单位微秒对应的计数值。库提供了一个思路但我们需要根据自己舵机的实际参数进行校准。通常我们会定义两个常量SERVOMIN和SERVOMAX对应0.5ms和2.5ms的计数值#define SERVOMIN 102 // 0.5ms脉宽对应的计数值 (0.5ms / 20ms * 4096 ≈ 102) #define SERVOMAX 512 // 2.5ms脉宽对应的计数值 (2.5ms / 20ms * 4096 ≈ 512)但实际上不同品牌甚至不同批次的舵机其中位点和行程终点可能略有偏差。因此更健壮的做法是定义一个转换函数并允许微调int angleToPulse(int ang, int trim) { // 将角度(0-180)映射到脉宽(500-2500微秒)再计算计数值并加上微调值 int pulse map(ang, 0, 180, SERVOMIN, SERVOMAX); return pulse trim; }这里的trim参数就是每个舵机的微调值用于补偿机械安装的误差。例如如果理论上90度时机器人腿应该是垂直的但实际却偏左就可以给这个舵机设置一个负的trim值如-5来修正。控制舵机时使用pwm.setPWM(channel, 0, pulseValue)函数。channel是通道号0-15第二个参数通常为0第三个参数就是计算出的pulseValue。4.3 运动引擎与步态算法实现让机器人动起来不仅仅是让单个舵机动而是需要四个舵机按照特定的时序和角度协同工作形成步态。我们可以将复杂的动作分解为一系列关键帧Pose然后让舵机在这些关键帧之间平滑移动。首先定义机器人的初始站立姿态所有舵机90度void homePosition() { pwm.setPWM(LEFT_LEG, 0, angleToPulse(90, trim_LL)); pwm.setPWM(RIGHT_LEG, 0, angleToPulse(90, trim_RL)); pwm.setPWM(LEFT_FOOT, 0, angleToPulse(90, trim_LF)); pwm.setPWM(RIGHT_FOOT, 0, angleToPulse(90, trim_RF)); delay(500); }一个简单的向前走步态可以这样分解准备重心移到右腿左腿舵机微抬右脚舵机微压。迈左腿左腿舵机向前摆动左脚舵机抬起。落脚左脚舵机放下重心前移。回位左腿舵机回摆到垂直位置同时右腿开始准备下一个周期。代码实现上可以编写一个walk(int steps, int speed)函数其中speed参数控制每个动作帧之间的延迟时间。通过精心设计每个舵机在步态周期中多个时间点的角度值并利用循环和延时进行切换就能产生连续的行走动画。舞蹈动作则是更复杂的、非周期性的角度序列组合可以预先编好一组角度数组然后按顺序执行。4.4 避障逻辑与传感器集成避障功能让Otto从预编程的玩具升级为能简单交互的自主机器人。逻辑很简单持续测量前方距离如果小于安全阈值比如15厘米就触发一个避障动作。使用超声波库可以很方便地获取距离#include Ultrasonic.h Ultrasonic ultrasonic(TRIG_PIN, ECHO_PIN); // 定义引脚 long getDistance() { return ultrasonic.read(); // 返回厘米值 }在主循环loop()中void loop() { long dist getDistance(); Serial.print(Distance: ); Serial.println(dist); if (dist 0 dist 15) { // 有效距离且在障碍范围内 avoidObstacle(); } else { walk(1, 200); // 否则正常走一步 } delay(100); // 每次测量间隔 } void avoidObstacle() { // 停止行走 homePosition(); delay(200); // 例如向右转90度 turnRight(90); delay(500); }avoidObstacle()函数可以设计得更智能比如先后退一步然后随机向左或向右转一个角度再继续前进这样能更好地摆脱困境。5. 系统调试、优化与问题排查实录5.1 上电调试与舵机校准首次上电运行建议按以下顺序调试单独测试舵机上传一个简单的测试程序依次让每个舵机从0度转到180度再转回来。观察运动是否平滑有无异响齿轮打齿声、抖动或发热严重现象。如果某个舵机不动检查信号线连接、通道号是否正确以及PCA9685的I2C地址是否匹配默认0x40如果模块有地址跳线则需注意。机械零点校准运行homePosition()函数让机器人进入理论站立姿态。从侧面和正面观察机器人的身体是否垂直双腿是否平行。如果不正不要强行掰动舵机而是去修改代码中对应舵机的trim微调值。例如如果左腿向外撇说明初始角度大于90度就给trim_LL一个负值如-10然后重新上传代码直到姿态端正为止。这个步骤可能需要反复几次。运动范围限制为了防止舵机旋转角度过大损坏机械结构需要在软件中设置安全角度范围。例如腿舵机可能只允许在60度到120度之间运动。在angleToPulse函数中或设置角度值之前用constrain(angle, minAngle, maxAngle)函数进行限制。5.2 常见问题与解决方案速查表在制作过程中你很可能遇到以下问题。这里整理了常见症状、可能原因和解决办法问题现象可能原因排查与解决思路上电后舵机乱转或抖动不归位1. 初始脉冲信号错误2. 电源功率不足3. PCA9685频率设置不对1. 检查代码中SERVOMIN/MAX值用示波器或逻辑分析仪检查PCA9685输出波形脉宽。2. 用万用表测量给PCA9685供电的5V电压在舵机动作时是否跌落到4.5V以下。考虑更换容量更大的电池或使用开关稳压模块。3. 确认pwm.setPWMFreq(50)已执行。机器人行走时向一边歪斜或打转1. 左右舵机机械安装不对称2. 左右舵机性能有差异死区不同3. 地面摩擦力不均1. 重新校准机械零点确保双腿完全对称。2. 在代码中为左右腿的相同动作设置不同的角度补偿值进行软件校准。3. 在平整、摩擦力均匀的桌面上测试。动作卡顿、不流畅1. 代码中delay()时间过长或逻辑复杂2. 电源响应速度慢3. 机械结构有干涉1. 优化代码使用非阻塞定时如millis()代替长延时delay()让主循环能快速响应传感器。2. 在LM7805的输入和输出端并联更大的电容如220μF0.1μF。3. 检查所有关节转动是否顺畅线缆是否绊住。超声波传感器读数不稳定或总是01. 供电电压不对应接3.3V2. Echo引脚电压问题3. 传感器前方有吸音材料1. 确认VCC接Pico的3.3V而非5V。2. HC-SR04的Echo引脚输出是5V电平直接接Pico的GPIO有风险。建议在Echo引脚和Pico GPIO之间串联一个1kΩ电阻分压或者使用电平转换模块。3. 确保传感器对准坚硬、平整的物体进行测试。Pico程序上传失败1. 未进入BOOTSEL模式2. 驱动问题或端口被占用3. 开发板选择错误1. 严格按照“按住BOOTSEL再插USB”的操作。2. 尝试更换USB线或电脑USB口。在设备管理器中检查端口状态。3. 确认Arduino IDE中开发板选择为“Raspberry Pi Pico”并选择了正确的端口。5.3 性能优化与扩展思路当基本功能实现后可以考虑以下优化和扩展让你的Otto更强大、更智能电源优化LM7805效率较低。可以更换为DC-DC降压模块如MP1584EN它效率高、发热小能提供更稳定的电流让舵机力量更足。步态优化基础的步态可能不稳。可以引入逆运动学简单计算让机器人的重心轨迹更平滑。或者使用更高级的算法如零力矩点预观控制但这需要更强的处理器和数学基础。增加交互功能声音添加一个无源蜂鸣器让机器人跳舞时播放简单的旋律。灯光在PCA9685空闲通道上连接LED并用PWM控制亮度作为眼睛或装饰。蓝牙/Wi-Fi控制为Pico添加ESP-01SESP8266模块通过手机APP或网页远程控制机器人或上传新的舞蹈动作。结构强化如果经常摔倒可以考虑用更坚固的材料如ABS重新打印关键承重部件或者在脚底增加橡胶垫片增大摩擦力。这个项目最迷人的地方在于它像一个活的脚手架。当你完成了这个基础版本你获得的不仅仅是一个会动的玩具而是一套完整的、可扩展的嵌入式机器人开发平台。你可以替换更强的舵机让它负重可以加装摄像头做视觉识别可以改写算法实现更复杂的步态。每一次调试和解决问题的过程都是对硬件接口、控制算法和系统调试能力的扎实训练。我自己的第一个Otto在桌面上成功走出第一步时那种喜悦感至今难忘。希望你在制作过程中也能享受到这种从代码到物理世界反馈的纯粹乐趣。如果在连接PCA9685时发现舵机反应迟钝不妨检查一下I2C总线的上拉电阻模块内部通常已集成但如果线缆较长在Pico的GP2和GP3引脚到3.3V之间各加一个4.7kΩ的上拉电阻通信稳定性会大大提升。