ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

舵机控制全攻略:从PWM原理到STM32实战与总线舵机

舵机控制全攻略:从PWM原理到STM32实战与总线舵机 搞硬件的人基本都绕不开“舵机”这个小东西。它个头不大价格亲民但能干的活却出奇地多——从玩具车转向到机器人手臂从摄像头云台到仿生手指背后全是舵机在默默出力。我这几年从Arduino玩到STM32再到树莓派Pico和总线舵机发现很多新手一上来就卡在“舵机怎么用”这个问题上要么不懂PWM控制原理要么把模拟舵机和总线舵机混为一谈要么一通电就抖成筛子。这篇文章我把舵机从原理到选型、从7大应用场景到各主流平台的控制方案全部捋一遍再附带一个能实际跑起来的目标追踪云台小项目希望对正在踩坑的你有点帮助。1. 舵机的控制原理是地基搞懂了后面全是套路1.1 拆开一台舵机看核心三件套很多人把舵机当成一个“能转指定角度的电机”这个理解大方向没错但不完整。拿最常见的SG90来说拆开外壳你会看到三样东西一个直流电机、一组减速齿轮、一个电位器再加一小块控制电路板。电机负责转齿轮负责把转速降下来、把扭矩提上去电位器则跟随输出轴一起转动实时感知当前角度。这里的巧妙之处在于舵机内部其实有一个“小闭环”。控制电路会持续比较你给的期望角度和电位器反馈的实际角度两者不一致就驱动电机转动直到角度对齐为止。也就是说舵机内部已经帮你把“位置环”做完了你只需要告诉它“转到哪里”它自己会埋头干到那个位置。这也是为什么大家常说舵机控制简单——它把最麻烦的电机控制细节全都封装在那一小块电路板上了。1.2 PWM控制50Hz频率下的脉宽秘密既然舵机内部闭环那你和舵机之间的通信方式是什么呢最主流的是PWM脉冲宽度调制。以SG90这类模拟舵机为例标准控制信号是50Hz也就是周期20ms其中高电平脉冲的宽度决定了舵机目标角度。关键映射关系大概是这样的0.5ms脉宽对应0°1.0ms对应45°1.5ms对应90°2.0ms对应135°2.5ms对应180°。换句话说脉宽每增加约11.1微秒角度就增加1°。这个线性关系是你后续所有计算的基础。有好多人上来就问“为什么我给了50Hz但舵机还是乱动”其实往往是因为脉冲宽度不对。STC系列单片机的定时器算出来容易有误差Arduino的Servo库会自动生成50Hz信号但如果你自己用延时函数写PWM就很容易写出“频率对、占空比错”的信号。这里我的建议是能用库就用库实在要手写一定要用示波器或逻辑分析仪先确认波形再上舵机。注意不是所有舵机都必须卡死在50Hz。部分数字舵机支持更高频率比如200Hz甚至300Hz。高频带来的好处是响应更快、噪音更小但前提是舵机本身支持。SG90这类廉价舵机老老实实用50Hz就行太高反而可能过热。1.3 模拟、数字、总线三种舵机到底差在哪根据信号类型和内部电路舵机大致可以分成三类。模拟舵机最传统控制信号是标准PWM内部靠比较器驱动电机。它结构简单、价格便宜但有一个缺点当脉宽和反馈角度接近目标时电机会进入“微颤”状态这也是舵机嗡嗡声的主要来源。数字舵机内部多了个微处理器可以把输入的PWM信号转换为更高频率的内部驱动信号比如300Hz以上响应速度更快、中立位更稳、保持力更强。价格比模拟舵机贵一些但用在机械臂或者对精度有要求的场合很值。总线舵机是近年来越来越火的类型代表品牌有飞特、大疆的RS系列等。它不再用PWM控制而是走串口总线通常是半双工串口或RS485一根线有的是四根线串起多个舵机每个舵机有独立ID主控用指令帧控制任意一个舵机。好处非常明显多关节机器人不必再拉一束PWM线还能实时读取舵机的位置、温度、电压真正做到闭环控制。后面我会专门展开讲。2. 7大应用场景逐个拆解从入门到进阶都有活干2.1 场景一摄像头云台与目标追踪这是我个人玩得最多的场景也是新手最容易出效果的。把两个舵机叠在一起构成二维云台底部的水平舵机负责左右旋转Yaw上面的舵机负责俯仰Pitch摄像头上方一放就能随意调整视角。配合视觉算法就变成了“自动追踪云台”。网上很火的“基于STM32与OpenCV的多模式舵机云台目标追踪”就是这个套路——OpenCV在上位机识别目标人脸、色块、二维码等计算出目标中心与画面中心的偏差再把这个偏差转成坐标指令发给下位机下位机驱动云台把目标追到画面中央。这里有个容易被忽略的点云台重心。如果你把摄像头装得太靠前舵机在某个角度会因重力矩过大而抖动或丢步。我的经验是尽量缩短力臂或者在背面加配重让舵机在大部分角度范围内承担的静力矩尽量均衡。另外两个舵机的扭矩可以选不一样底座的舵机扭矩建议选大一号因为它在最恶劣角度要同时扛住整个上方的重量。2.2 场景二机械臂与机器人关节机械臂是舵机应用最经典的场景之一。从最简单的两轴捡小件机械臂到六轴桌面级机械臂本质上都是“多个舵机串联成关节链”。每个舵机就是一个旋转关节控制不同关节的转角机械臂末端就能在三维空间中运动。做机械臂时要注意“舵机堆叠”带来的问题越靠近底座的关节承受的负载越大所以底座舵机要选大扭矩型号末端舵机可以小一点。很多人一开始在桌面机械臂上全用SG90结果一抬重物底座舵机就咔咔响这就是典型选型失误。另一个痛点是“舵机开环控制”的局限。普通舵机虽然内部有反馈但对外部负载扰动没有什么感知能力比如受到外力推动时它只会按自己的控制逻辑响应不会记录“被推了多少度”。如果你的机械臂需要精确知道每个关节的实时位置要么上总线舵机读反馈要么额外加编码器要么用视觉做外部闭环。2.3 场景三仿生机器人仿生手、足式机器人仿生类作品这几年在创客圈特别火尤其是仿生手臂。用五到六个微型舵机分别拉动“手指”的腱绳就能实现手指的弯曲和抓取。再配上肌电传感器或数据手套就成了简易的意念控制、手势复现系统。这类项目对舵机的核心要求是体积小、重量轻、扭矩不能太小。常见的SG90就是首选因为它便宜且还能带动手指结构。但如果手部要做大力抓握可以考虑MG90S或者金属齿轮版本的微型舵机齿轮更耐磨堵转寿命也更好。足式机器人四足、六足也一样每条腿至少要两个舵机髋关节膝关节六足就是12个这时候PWM舵机的劣势就显现出来了——你起码得找一块多路PWM驱动板而且线束一大堆。很多进阶玩家因此转投总线舵机一根线就能把所有腿部关节串联起来代码上也清爽很多。2.4 场景四智能小车转向与功能机构在智能小车项目中舵机最常见的角色是“转向舵机”。使用前轮转向结构的小车把舵机臂连到转向拉杆上舵机转动带动前轮偏转就能控制方向。这个场景里要特别注意舵机臂的长度和安装角度。舵机臂太短转向力臂小、转向不灵活太长呢反应又太慢还占空间。另外舵机中位角要和小车直行状态对齐不然车子会一直偏着跑。更省事的方案是用N20电机加编码器做差速转向但那是另一个故事了用舵机做转向结构简单、调试直观在自由度不高的竞速小车里反而更稳。舵机还能用在车上做各种“功能动作”比如机械爪的开合、雷达支架的旋转、挡板的升降。这些用途不需要很高的精度重点在于安装结构要留有余量方便调中位。多个舵机同时动作时建议给每个功能都设置独立的限位开关或挡块防止舵机超行程堵转。2.5 场景五航模与船模舵面控制航模可能是舵机最初的“主场”。固定翼飞机上副翼、升降舵、方向舵全靠舵机驱动船上舵叶的偏转也是舵机来干。这类应用要求舵机有较高的响应速度和可靠性因为空中可没机会给你断电重启。航模舵机一般用数字舵机比较多因为数字舵机的响应频率高对舵面动作的跟手性更好。选型时除了看扭矩还要看速度单位是秒/60°比如0.1秒/60°就比0.2秒/60°反应快一倍。飞行中舵机一旦出现卡顿或抖动不要犹豫直接换掉这是安身立命的经验。大家玩Arduino时喜欢给舵机供电都用5V但航模舵机一般接受4.8V到6V甚至更高很多人用独立BEC电池消除电路给舵机供6V能明显感觉到舵机更有劲。但注意主控的供电和舵机的供电一定要隔离好共地不共源。2.6 场景六教育实验与竞赛平台舵机在学校实验室和各类电子设计竞赛中出现的频率极高。比如“基于STM32CubeMX的舵机控制实验”几乎是学习STM32定时器PWM输出的必修课树莓派Pico控制舵机也是很多创客入门MicroPython的首选练习。这类场景下的舵机项目往往不是追求性能极限而是追求“原理清晰、实验可复现”。我个人觉得把PWM控制舵机作为嵌入式教学案例确实很好——它既涉及定时器配置、占空比计算又有直观的物理效果学生一看就懂自己写对了没有。竞赛里比较常见的是“舵机摄像头”的小车方案比如巡线、巡球、搬运等动作。这种比赛对舵机的调试效率和稳定性要求高我建议在赛前把所有舵机的线序、中位值、左右限位整理成一张表贴在小车底盘上省得现场手忙脚乱。2.7 场景七总线舵机与多关节系统如果你做的东西关节特别多比如六足机器人、人形机器人、多自由度机械臂那总线舵机几乎是唯一正确的选择。总线舵机通过一根串口总线串联每个舵机有自己的ID和寄存器你发一条指令总线上的总线舵机能同时响应并汇报自身状态。以飞特舵机为例它支持半双工串口通信常见波特率有1Mbps、500kbps等。在使用STM32控制时你只需把对应串口的TX和RX接到舵机总线上注意方向控制引脚然后按它的协议打包指令帧就能控制角度、速度、扭矩还能读取温度、电压、电流。相比PWM方案代码量反而简单了——不用再为每个舵机写PWM计算只需要组帧和解析帧。总线舵机也有坑它对供电质量要求更高电流冲击大一点接地处理不好就容易死机或者舵机乱动。还有总线上一旦有一个舵机ID冲突整条总线的通信都会紊乱。所以每次接线后先单独给每个舵机设置好唯一ID再做联调这是我撞了三次墙才记住的教训。3. 主控方案实操Arduino、STM32、树莓派Pico全都能玩3.1 Arduino控制舵机最简单的“Hello World”Arduino控制舵机是门槛最低的方案官方Servo库封装好了50Hz信号你只需要关心角度值。代码如下#include Servo.h Servo myServo; void setup() { myServo.attach(9); // 信号线接9号引脚 } void loop() { myServo.write(0); // 转到0° delay(1000); myServo.write(90); // 转到90° delay(1000); myServo.write(180); // 转到180° delay(1000); }这段代码里myServo.write()的参数是角度Servo库会自动把角度换算成对应的脉冲宽度。注意并不是所有引脚的PWM硬件特性都一样Servo库底层可以用软件方式在任意数字引脚生成信号所以9号引脚只是个约定不是限制。如果项目里有多个舵机直接创建多个Servo对象就行。但Arduino UNO的中断资源有限软件PWM也很占CPU一般建议最多接8到12个舵机再多就要考虑舵机控制板或者换主控平台。3.2 STM32CubeMX配置PWM控制舵机从配置到代码STM32上控制舵机核心是配置一个定时器的PWM输出通道。用STM32CubeMX可以大大减少配置工作量具体步骤如下。第一步时钟配置。把定时器时钟挂在APB1或APB2总线上注意看定时器时钟频率是多少后面计算分频要用。以STM32F103为例APB1定时器时钟通常是72MHz。第二步配置定时器。以TIM2为例在CubeMX里把TIM2的Channel1设置为PWM Generation CH1。定时器周期和预分频这样算目标PWM频率是50Hz我们需要将72MHz的时钟分频到50Hz即总的分频系数是72MHz / 50Hz 1,440,000。如果预分频器PSC设为143即实际分频144那么计数器时钟就是72MHz / 144 500kHz。这时ARR应设为500kHz / 50Hz - 1 9999。这样一个计数周期就是20msARR为9999时脉宽分辨率是20ms / 10000 2微秒。第三步设置初始占空比。脉宽2ms对应180度那CCR值就是2ms / 2us 10001.5ms对应90度CCR 750。改角度就是修改CCR值。第四步在代码里用__HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, pulse)更新角度。例如__HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, 500); // 1ms 0° HAL_Delay(1000); __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, 750); // 1.5ms 90° HAL_Delay(1000); __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, 1000); // 2ms 180°这里还有一个很实用的写法写一个角度到CCR的转换函数避免每次手算uint32_t angle_to_ccr(float angle) { // 0° - 500 (1ms), 180° - 1000 (2ms) return (uint32_t)(500 angle * 500.0f / 180.0f); }很多人在CubeMX里把ARR写成999而PSC写149结果发现频率不对舵机狂抖就是因为分频没算对。详见上面的计算思路改定时器参数时务必用示波器确认一下输出频率。3.3 树莓派PicoMicroPython控制舵机树莓派Pico控制舵机有两种路径MicroPython和C/C SDK。MicroPython上手最快自带machine.PWM模块但需要注意Pico的PWM频率和分辨率设置。from machine import Pin, PWM servo PWM(Pin(15)) servo.freq(50) def set_angle(angle): # 0° - 0.5ms, 180° - 2.5ms duty int(angle / 180 * 2000 500) # 单位脉冲宽度对应的计数值 servo.duty_u16(duty)这里有个坑duty_u16()的范围是0到65535对应的是整个PWM周期内的占空比。在50Hz周期20ms下0.5ms到2.5ms脉宽对应占空比为2.5%到12.5%所以duty_u16的值应在约1638到8191之间。上面的set_angle函数算出来的duty值就是在这个区间的近似值。如果Pico要用C语言官方Pico SDK里也提供PWM API逻辑类似只是要自己配置wrap值和时钟分频代码量会多一些但对实时性和资源占用更友好。3.4 总线舵机怎么控制以飞特舵机为例总线舵机的控制逻辑和PWM完全不同。以飞特舵机为例它使用串口总线常见规格有串行总线舵机通过TTL半双工通信。控制流程分三步。第一步是接线。总线舵机一般四根线电源正、电源负、信号线数据、有些还有地线隔离。和STM32接线时信号线要接到串口的TX和RX并用一个GPIO控制方向切换。如果你用的是USB转TTL模块注意模块的TX、RX要和舵机总线交叉连接。第二步是准备指令帧。飞特舵机的协议格式一般是帧头0x4C 0x43、ID、指令长度、指令类型、参数、校验和。例如控制ID为1的舵机转到30度、速度为0参数里填入角度值和速度值校验和用累加取低字节计算。我记得具体地址位是角度寄存器地址是0x2A写入两个字节高位在前低位在后。第三步是STM32端实现。下面是一段简化示例的伪码思路uint8_t sendBuf[10]; sendBuf[0] 0x4C; // 帧头1 sendBuf[1] 0x43; // 帧头2 sendBuf[2] 0x01; // 舵机ID sendBuf[3] 0x04; // 数据长度 sendBuf[4] 0x03; // 指令写寄存器 sendBuf[5] 0x2A; // 起始地址 sendBuf[6] angle 8; // 角度高字节 sendBuf[7] angle 0xFF; // 角度低字节 sendBuf[8] speed; // 速度 sendBuf[9] checksum(sendBuf); // 校验和实际项目中你需要把发送缓冲区的数据通过串口发出去同时控制方向引脚为发送模式发完再切回接收模式。飞特舵机还支持读取状态比如发送读取指令后接收返回帧就能拿到温度、电压、电流等数据这对做闭环上位机特别有用。3.5 舵机控制板PCA9685到底解决什么问题当你用Arduino UNO接8个以上的舵机或者需要同时刷新多个舵机角度时单靠主控的定时器资源会很吃力。这时PCA9685这类I2C舵机控制板就派上用场了。PCA9685是一块16通道PWM驱动芯片通过I2C接口控制。它内部自带振荡器可以精确产生50Hz的PWM信号每个通道的脉宽独立可调。它的好处是主控只需要发几条I2C指令几百个舵机的PWM生成全部由它独立完成不占用主控定时器资源。使用方式也不复杂。Arduino下用Adafruit_PWMServoDriver库设置脉冲长度范围比如#include Adafruit_PWMServoDriver.h Adafruit_PWMServoDriver pwm Adafruit_PWMServoDriver(); void setup() { pwm.begin(); pwm.setPWMFreq(50); } void setServoAngle(uint8_t ch, float angle) { uint16_t pulse map(angle, 0, 180, 102, 512); // 脉宽映射 pwm.setPWM(ch, 0, pulse); }这里的102和512是PCA9685内部12位分辨率0到4095下对应0.5ms和2.5ms的计数值。如果你用20ms周期分辨率是4096 / 20ms约等于每微秒0.2048个计数值那0.5ms是约1022.5ms是约512。很多库内部已经封装了这个范围直接设置即可但理解底层才能解决“某几个通道角度偏大/偏小”这类校准问题。PCA9685还有一个好处是它可以外接独立电源给舵机供电逻辑部分和电源部分分离这让系统运行更稳定。不过注意共地否则I2C信号会乱。4. 实战项目基于STM32与OpenCV的多模式舵机云台目标追踪4.1 系统架构上位机视觉下位机执行前面聊了这么多基础现在把它们用起来。我做一个很经典的项目基于STM32和OpenCV的多模式目标追踪云台。系统分两层上位机跑OpenCV视觉识别下位机用STM32控制云台。视觉部分主要负责检测目标类别和坐标把偏移量实时发送给STM32STM32再根据偏移量更新云台舵机的目标角度让目标尽量保持在画面中心。为什么不做成纯单片机方案因为OpenCV的人脸识别、色块追踪等算法在嵌入式Linux之外的地方跑起来太吃力。用电脑或树莓派做视觉用STM32做实时控制是一种成熟的分工。STM32硬实时性比Linux下的Python强很多舵机刷新率也更稳定两相结合体验非常好。4.2 硬件准备与接线我的硬件清单如下两个SG90或MG90S舵机水平俯仰当然用MG90S更好金属齿轮耐用很多STM32F103C8T6最小系统板USB-TTL模块连电脑和STM32通信用摄像头随便一个USB摄像头即可5V/2A以上舵机电源我用的是带USB口的充电宝输出能力要足接线时STM32的PA9USART1_TX、PA10USART1_RX接USB-TTL模块用于和上位机通信定时器PWM输出接两个舵机的信号线比如用TIM2_CH1接水平舵机、TIM2_CH2接俯仰舵机。舵机电源和STM32电源要分开但需要共地否则串口通信会被干扰。这里我再强调一遍舵机启动瞬间电流很大SG90堵转电流能到1A多两个舵机同时动时冲击更大。所以绝对不要指望用单片机的3.3V或USB的5V直接带两个舵机一定要外接独立供电。4.3 OpenCV端目标检测与坐标输出视觉端的逻辑并不复杂。以颜色追踪为例OpenCV把摄像头画面转换到HSV空间通过阈值提取目标色块计算色块的中心坐标cx, cy和图像中心frame_width/2, frame_height/2的偏差然后把这个偏差通过串口发出去。关键部分大概是import cv2 import serial import numpy as np ser serial.Serial(COM5, 115200) cap cv2.VideoCapture(0) while True: ret, frame cap.read() hsv cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower np.array([35, 100, 100]) # 绿色阈值按需调整 upper np.array([85, 255, 255]) mask cv2.inRange(hsv, lower, upper) contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if contours: c max(contours, keycv2.contourArea) M cv2.moments(c) if M[m00] 0: cx int(M[m10] / M[m00]) cy int(M[m01] / M[m00]) frame_h, frame_w frame.shape[:2] dx cx - frame_w // 2 dy cy - frame_h // 2 msg f{dx},{dy}\n ser.write(msg.encode())串口数据的格式那句dx,dy很重要STM32端解析起来很简单。如果你要扩展“多模式”可以在上位机里加模式切换人脸检测、色块追踪、二维码检测等输出的数据格式保持一致即可这样下位机代码完全不用改。4.4 STM32端串口接收与云台控制STM32端的任务是接收串口数据解析出偏差值再根据偏差调整两个舵机的目标角度并做限幅和死区处理。死区处理是实际效果的关键。如果目标偏差在正负5像素以内就认为已经对准不更新角度避免舵机在目标位置附近反复抖动。限幅则是为了保护舵机比如水平舵机只能在0到180度范围内活动烧过头就撞机械限位了。核心思路代码// 假设串口收到 dx,dy\r\n int dx, dy; sscanf((char*)rx_buf, %d,%d, dx, dy); if (abs(dx) 5) { yaw_target dx * 0.1f; // 比例系数按实际调试 if (yaw_target 10) yaw_target 10; if (yaw_target 170) yaw_target 170; __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, angle_to_ccr(yaw_target)); } if (abs(dy) 5) { pitch_target dy * 0.1f; if (pitch_target 10) pitch_target 10; if (pitch_target 170) pitch_target 170; __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_2, angle_to_ccr(pitch_target)); }比例系数0.1要按实际效果调整。如果目标跑得快0.1可能追不上如果系数太大画面会来回振荡。实际联调的时候我从0.05开始试逐步加大到既跟手又不抖的值。4.5 联调过程与效果联调时建议按下面顺序走一遍先单独测试舵机角度控制确认PWM范围没错再测试串口通信用串口助手手动发“20,10”之类的数据看舵机是否响应最后再启动视觉程序进行整体追踪。我第一次联调时出了个很典型的毛病串口用115200波特率但STM32配置也写的115200OpenCV却默认发了9600结果上位机收到一堆乱码舵机自然纹丝不动。检查之后统一成115200问题就解决了。整个系统跑起来的体验是目标在画面里移动时云台会平滑地“跟”着目标转目标停住时云台也会稳定在那个位置不再来回抖。加上死区判断后整个动作非常干净。5. 高频故障排查与独家心得5.1 舵机抖动、嗡嗡叫、不受控制抖动和嗡嗡声是最常见的问题原因通常有几种。第一种是PWM信号不稳定。如果频率不对或者脉宽波动舵机会反复校正位置表现就是“抽搐”。用示波器看信号最直接没示波器就换一个已知正常的舵机交叉测试。第二种是供电不足。舵机在负载大的时候需要很高的瞬时电流如果电源内阻大或者线太细电压就会跌落舵机内部的比较器判断就会紊乱表现出来就是抖、无力、甚至自己乱转。解决思路很简单换更大电流的电源或者加一个大电容比如1000微法电解电容并接在舵机电源引脚附近。第三种是舵机本身损坏。长期堵转或者超负荷运行会导致减速齿轮磨损、电位器老化这时候再怎么调程序也没用只能换舵机。5.2 供电问题引起的复位、卡顿现象很多人在Arduino上直接插一个SG90发现一运动板子上的LED就闪程序偶尔重启。这个现象十有八九是“共源供电”的锅。舵机启动电流大如果和单片机共用同一个稳压源电压瞬间跌落超过单片机的复位阈值系统就会重启。正确做法是把舵机电源和逻辑电源分开。用一个5V/2A以上的独立电源给舵机供电单片机和传感器用USB或者3.3V稳压供电。两者只共地不共源问题立刻消失。我还有一个经验舵机信号线太长也容易出问题。信号线超过20厘米时建议双绞或者用屏蔽线避免电机转动时产生的电磁干扰串入信号引起误动作。5.3 堵转、过载与保护舵机最怕堵转。堵转时电机电流飙升不仅发热严重还容易烧驱动电路或者齿轮。机械结构上要注意避免舵机超行程。比如在机械臂设计时关节旋转范围比舵机本身还小那就要在结构上添加机械限位防止舵机转到极限位置后别住。代码层面也应该对所有舵机角度做软限位比如你不希望云台转到某个方向撞到支架就把代码里的目标角度限制在0到170之间。如果确实需要在堵转状态下保持力矩那就要用数字舵机或者总线舵机并设置合适的扭矩限制和温度保护。总线舵机在这方面很优秀它能实时上报温度、电压、电流比如温度超过80°C就执行保护策略这在普通PWM舵机上根本做不到。5.4 总线舵机的常见坑点总线舵机和人一样有脾气最常见的问题有三个。ID冲突。如果总线上有两个舵机ID相同你的指令发过去两个舵机都会响应轻则不动作重则整个总线被拉死。所以新舵机到手第一件事就是设置独立ID并做好标签记录。供电波动。总线舵机通信速率高对电源纹波更敏感。如果电源不稳会出现舵机偶发乱动或者通信丢帧。解决办法是在总线电源入口加LC滤波或者大电容而且电源线尽量用粗线减少压降。信号线和电源线分离。如果总线的信号线和电源线绑在一起长距离传输时容易互相干扰。适当给信号线加个对地电阻或者TVS管做保护尤其在电磁环境复杂的场合能省不少麻烦。5.5 平滑控制与延长舵机寿命的小技巧最后分享几个我做舵机项目积累下来的小技巧。第一不要在目标角度上做“瞬移”。哪怕是机械臂需要快速到位也建议加上插值或梯形加减速过程让舵机平滑地转过去。这样不仅动作看起来自然还能减少机械冲击和齿轮磨损。简单做法就是每次控制周期让目标角度递增或递减一个固定步长。Arduino写法里可以维护一个当前角度变量每次write一小步用循环控制速度。第二舵机臂和连接的螺丝要上胶。振动久了螺丝很容易松一旦松了舵机臂打滑位置就全乱了。我一般会在螺纹上点一点点厌氧螺纹胶或者直接用弹簧垫圈。第三关于舵机中位值。很多廉价舵机的中位并不是精确的1.5ms不同舵机之间会有1到10度的差异。组装前最好写个校准程序把每个舵机的实际角度和脉宽关系测出来在软件里补偿。做多关节系统时这个步骤特别重要不然标称90°的位置实际偏了5°整个机械臂就废了。第四舵机关电前一定要把角度复位到负载最小的位置。比如云台在断电前先转到水平位置机械臂在断电前先垂下来这样可以避免下次上电时舵机带着负载硬启动硬启动那一下冲击其实比正常运动伤机器多了。我做舵机项目踩过最多的坑不是控制代码写不出来而是把“舵机”当成一个简单的开关来用。事实上舵机是个完整的机电控制系统从供电、信号到机械结构每一个环节都要认真对待。只要你把脉宽映射、频率计算、电源隔离这些基础打牢上到STM32下到树莓派Pico从SG90玩到总线舵机都是水到渠成的事。希望这篇舵机全攻略能让你少走几步弯路有什么好玩的舵机项目按照这套思路去试就对了。
返回列表