尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

OpenMV4舵机控制全攻略:从PWM原理到视觉追踪实战

OpenMV4舵机控制全攻略:从PWM原理到视觉追踪实战
📅 发布时间:2026/8/4 8:48:34

1. 项目缘起:从“看得见”到“动起来”的跨越

玩OpenMV4的朋友,最开始大多是被它强大的机器视觉能力吸引——识别颜色、追踪色块、人脸检测、二维码解码,这些功能确实很酷。但视觉只是感知世界的第一步,真正的乐趣在于让机器“动”起来,去和物理世界互动。这时候,舵机就成了连接视觉与动作的关键桥梁。你可能已经用OpenMV4的IDE写好了识别红色小球的代码,屏幕上也能看到方框稳稳地框住了目标,但接下来呢?如何让一个机械臂去抓取它,或者让一个云台摄像头始终对准它?这就需要我们深入OpenMV4的舵机控制功能。

我最初接触这个需求,是想做一个简单的颜色分拣装置。OpenMV4识别出不同颜色的积木,然后通过舵机控制的挡板,将它们推到不同的轨道。听起来简单,但实际操作中,从PWM信号的理解,到舵机角度的精确映射,再到与视觉识别结果的实时同步,每一步都有不少细节需要注意。网上关于OpenMV4的教程,大多集中在视觉算法本身,关于如何稳定、可靠地驱动舵机执行动作的完整经验分享并不多见。这篇笔记,就是把我从接线、调试到最终实现稳定控制过程中积累的经验、踩过的坑,系统地梳理出来。无论你是想制作追踪云台、机械臂,还是任何需要“视觉引导动作”的项目,这里的内容都能帮你少走弯路。

2. 硬件连接与PWM基础:给信号找个好“座位”

在写第一行代码之前,正确的硬件连接是成功的基石。OpenMV4 Cam H7 Plus(这也是目前最主流型号)的引脚资源比较丰富,但并非所有引脚都适合驱动舵机。

2.1 引脚选择:避开“雷区”,找到最佳输出口

OpenMV4的引脚分为三组:GPIO、I/O和专用的PWM/TIM引脚。驱动舵机,我们必须使用带有硬件PWM(脉冲宽度调制)功能的引脚。使用软件模拟PWM(比如在任意GPIO上模拟)来驱动舵机是绝对不推荐的,因为软件模拟的时序精度和稳定性极差,会导致舵机抖动、发热甚至无法工作。

OpenMV4 H7 Plus上最常用、最稳定的硬件PWM引脚是P7 和 P8。这两个引脚直接与高级定时器(TIM1)的通道相连,能够产生非常稳定和精确的PWM信号。以我的OpenMV4 H7 Plus板子为例,其引脚排列如下(重点关注P7和P8):

[OpenMV4 H7 Plus 正面] ┌─────────────────┐ │ ○ ○ ○ ○ ○ ○ ○ ○ │ │ ○ ○ ○ ○ ○ ○ ○ ○ │ └─────────────────┘ ... P7 P8 ...

(注:实际板子丝印清晰,请以板载标识为准)

为什么是P7/P8?因为它们对应的定时器TIM1是芯片中功能最强的定时器之一,分辨率高,抗干扰能力强。相比之下,其他一些标有PWM的引脚(如P0、P1)可能关联的定时器资源或优先级不同,在复杂任务中可能产生冲突。所以,对于舵机这种对信号稳定性要求高的设备,P7和P8是首选。

注意:务必查阅你所使用的具体OpenMV4型号的官方引脚图。不同版本(如OpenMV4 H7 Basic)的引脚定义可能有细微差别。连接错误轻则舵机不转,重则可能损坏OpenMV4或舵机。

2.2 舵机供电:独立电源是关键中的关键

这是新手最容易栽跟头的地方。绝对不要试图用OpenMV4板载的3.3V或5V输出直接给舵机供电!

OpenMV4的USB口或稳压芯片提供的电流非常有限(通常只有500mA左右)。而一个普通9g微型舵机在空载时工作电流约100-200mA,但在堵转(卡住)或带负载启动的瞬间,电流可以轻松飙升到500mA以上。多个舵机同时工作,电流需求更大。直接用OpenMV4供电,会导致:

  1. 电压骤降:OpenMV4自身重启或摄像头模块工作异常,图像识别卡顿。
  2. 电流过载:可能烧毁OpenMV4的稳压芯片,永久性损坏主板。

正确的供电方案是使用独立的外接电源。具体接线方法如下:

  1. 准备一个合适的电源:对于1-2个微型舵机,一块常见的5V/2A的手机充电宝或USB适配器就足够了。对于更多或更大扭矩的舵机,需要准备专门的舵机测试电源或稳压模块(如LM2596降压模块)。
  2. 共地操作:将外接电源的负极(GND)与OpenMV4的任何一个GND引脚(如P6旁边的GND)用杜邦线连接起来。这是必须的步骤,它为PWM信号提供了统一的电压参考基准。没有共地,舵机无法正确解读信号。
  3. 连接信号与电源:舵机一般有三根线:棕色或黑色(GND)、红色(VCC,正极)、橙色或黄色(Signal,信号线)。
    • 舵机GND线 -> 外接电源GND。
    • 舵机VCC线 -> 外接电源正极(通常是5V)。
    • 舵机Signal线 -> OpenMV4的P7或P8引脚。

这样,OpenMV4只负责提供微弱的控制信号(几乎不耗电),而动力则由独立电源提供,互不干扰,系统非常稳定。

2.3 PWM信号原理:舵机如何听懂你的话

理解了硬件连接,我们再来看看OpenMV4究竟发出了什么样的指令。舵机接收的是PWM信号,但它并不关心频率(当然要在合理范围内),它只关心每个周期内高电平持续的时间,也就是脉冲宽度。

对于最常见的模拟舵机(如SG90, MG996R),控制标准通常是:

  • 脉冲宽度范围:500us(微秒)到 2500us。
  • 对应角度范围:通常对应舵机0度到180度的机械旋转。
  • 信号周期:通常为20ms(即频率50Hz)。这意味着每秒发送50个脉冲。

映射关系:角度 = (脉冲宽度 - 500) / (2500 - 500) * 180。例如:

  • 脉冲宽度 = 1500us -> 对应中间位置,90度。
  • 脉冲宽度 = 500us -> 对应极限位置,0度。
  • 脉冲宽度 = 2500us -> 对应另一极限位置,180度。

在OpenMV4的PyMicroPython环境中,我们通过设置PWM对象的占空比(Duty Cycle)来间接控制脉冲宽度。占空比 = 高电平时间 / 周期时间。因此,要输出1500us的脉冲,占空比 = 1500us / 20000us = 0.075,即7.5%。

3. 代码实战:从基础驱动到与视觉联动

理论清晰后,我们进入代码环节。OpenMV4的IDE基于MicroPython,控制舵机主要用到pyb模块中的Pin和Timer。

3.1 基础单舵机控制:让舵机动起来

我们先写一个最简单的程序,让连接在P7引脚上的舵机进行往复运动。

import pyb import time # 1. 初始化引脚和定时器 # 使用TIM2,通道1(CH1)对应引脚P7。频率设为50Hz(周期20ms) tim = pyb.Timer(2, freq=50) # 生成PWM对象 ch = tim.channel(1, pyb.Timer.PWM, pin=pyb.Pin.board.P7) # 2. 定义角度到脉冲宽度的转换函数 def angle_to_duty(angle): # 将角度(0-180)映射到脉冲宽度(500-2500us) pulse_width_us = 500 + (angle / 180) * 2000 # 2000 = 2500-500 # 计算占空比:脉冲宽度(us) / 周期(us)。周期20ms=20000us duty = pulse_width_us / 20000.0 # PWM占空比范围是0-1,返回结果 return duty # 3. 控制舵机运动 try: while True: # 转动到0度 duty_cycle = angle_to_duty(0) ch.pulse_width_percent(duty_cycle * 100) # 方法接收百分比参数 print("Angle: 0, Duty: {:.2%}".format(duty_cycle)) time.sleep_ms(1000) # 等待1秒,让舵机到位 # 转动到90度(中间位置) duty_cycle = angle_to_duty(90) ch.pulse_width_percent(duty_cycle * 100) print("Angle: 90, Duty: {:.2%}".format(duty_cycle)) time.sleep_ms(1000) # 转动到180度 duty_cycle = angle_to_duty(180) ch.pulse_width_percent(duty_cycle * 100) print("Angle: 180, Duty: {:.2%}".format(duty_cycle)) time.sleep_ms(1000) # 再回到90度 duty_cycle = angle_to_duty(90) ch.pulse_width_percent(duty_cycle * 100) print("Angle: 90, Duty: {:.2%}".format(duty_cycle)) time.sleep_ms(1000) except KeyboardInterrupt: # 按下Ctrl+C后,让舵机回到安全位置(如90度) ch.pulse_width_percent(angle_to_duty(90) * 100) print("\nProgram interrupted. Servo set to 90 degrees.")

代码解析与避坑点:

  • pyb.Timer(2, freq=50):这里选择了定时器2(TIM2)。OpenMV4的定时器资源是有限的,P7引脚可以映射到多个定时器通道。使用TIM2是常见且稳定的选择。freq=50设置了PWM频率为50Hz。
  • angle_to_duty函数:这是核心转换。务必注意计算精度,使用20000.0确保是浮点数除法,避免整数除法截断导致精度丢失。
  • pulse_width_percent():这个方法接收的是一个百分比数值(0-100),而不是0-1的小数。所以我们需要将计算出的占空比duty乘以100。这是一个非常容易写错的地方,写错了舵机要么不动,要么乱转。
  • 异常处理:在try...except块中捕获KeyboardInterrupt(Ctrl+C)是个好习惯。确保在程序意外停止时,舵机能回到一个预设的安全角度,避免机械结构处于极限位置长时间受力。

3.2 多舵机协同控制:构建简单云台

单个舵机只能实现一维转动。要实现摄像头追踪,至少需要两个舵机构成的二自由度云台(Pan-Tilt):一个控制水平左右转动(Pan),一个控制垂直上下转动(Tilt)。

import pyb import time class ServoGimbal: def __init__(self, pan_pin='P7', tilt_pin='P8'): """ 初始化云台。 :param pan_pin: 水平舵机引脚,默认P7 :param tilt_pin: 垂直舵机引脚,默认P8 """ # 初始化水平舵机 (Pan) - 使用TIM2, CH1 self.tim_pan = pyb.Timer(2, freq=50) self.ch_pan = self.tim_pan.channel(1, pyb.Timer.PWM, pin=pyb.Pin.board.P7) # 初始化垂直舵机 (Tilt) - 使用TIM4, CH2 (P8对应此通道,需查手册确认) # 注意:P8可能对应不同定时器,OpenMV4 H7 Plus上P8常用TIM4_CH2 self.tim_tilt = pyb.Timer(4, freq=50) self.ch_tilt = self.tim_tilt.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.P8) # 设置舵机初始角度(中间位置) self.pan_angle = 90 self.tilt_angle = 90 self.move_to(self.pan_angle, self.tilt_angle) time.sleep_ms(500) # 给舵机时间初始化到位 def _angle_to_duty(self, angle): """内部使用的角度转占空比函数""" pulse_width_us = 500 + (angle / 180) * 2000 return (pulse_width_us / 20000.0) * 100 # 直接返回百分比 def move_to(self, pan_angle=None, tilt_angle=None): """ 移动云台到指定角度。 :param pan_angle: 水平角度 (0-180),None表示不改变 :param tilt_angle: 垂直角度 (0-180),None表示不改变 """ if pan_angle is not None: # 添加软件限位,防止超出机械范围损坏舵机 pan_angle = max(0, min(180, pan_angle)) self.pan_angle = pan_angle self.ch_pan.pulse_width_percent(self._angle_to_duty(pan_angle)) if tilt_angle is not None: # 垂直方向限位可能更严格,例如防止摄像头碰到底座 tilt_angle = max(30, min(150, tilt_angle)) # 假设限制在30-150度 self.tilt_angle = tilt_angle self.ch_tilt.pulse_width_percent(self._angle_to_duty(tilt_angle)) def smooth_move(self, target_pan, target_tilt, steps=20, delay_ms=20): """ 平滑移动到目标位置,避免舵机跳跃式运动。 :param steps: 平滑步数 :param delay_ms: 每步之间的延迟(毫秒) """ start_pan, start_tilt = self.pan_angle, self.tilt_angle for i in range(steps + 1): ratio = i / steps current_pan = start_pan + (target_pan - start_pan) * ratio current_tilt = start_tilt + (target_tilt - start_tilt) * ratio self.move_to(current_pan, current_tilt) time.sleep_ms(delay_ms) # 使用示例 if __name__ == '__main__': gimbal = ServoGimbal() print("云台初始化完成,位于中心位置(90, 90)") # 示例:让云台平滑地扫描一个区域 try: while True: # 看向左上 gimbal.smooth_move(pan_angle=45, tilt_angle=120, steps=30, delay_ms=15) time.sleep_ms(1000) # 看向右下 gimbal.smooth_move(pan_angle=135, tilt_angle=60, steps=30, delay_ms=15) time.sleep_ms(1000) # 回到中心 gimbal.smooth_move(pan_angle=90, tilt_angle=90, steps=30, delay_ms=15) time.sleep_ms(1000) except KeyboardInterrupt: gimbal.move_to(90, 90) # 中断时回归中心 print("云台已回归中心位置。")

多舵机控制的核心要点:

  1. 定时器资源分配:两个舵机必须使用不同的定时器(Timer)或者同一定时器的不同通道(Channel)。上述代码中,Pan用了TIM2_CH1,Tilt用了TIM4_CH2,它们是完全独立的硬件资源,不会互相干扰。
  2. 封装与抽象:将舵机控制逻辑封装成ServoGimbal类,大大提高了代码的可读性和复用性。初始化、角度转换、移动控制都集中在类内部。
  3. 软件限位:在move_to方法中加入了max和min函数进行角度限幅。这是极其重要的保护措施,尤其是对于垂直舵机,物理结构可能不允许0-180度的全范围运动,强行驱动会导致齿轮打齿或电机烧毁。
  4. 平滑运动:smooth_move函数实现了简单的线性插值。直接让舵机从角度A跳到角度B,会产生剧烈的抖动和噪音,对机械结构冲击也大。通过分成多小步逐步移动,运动变得非常柔和、安静,也更像“人”的操作。

3.3 与视觉识别结合:实现自动追踪

现在,我们将舵机云台和OpenMV4的核心功能——视觉识别结合起来,实现一个简单的颜色追踪云台。我们让摄像头寻找画面中最大的色块,然后控制云台转动,使这个色块始终位于画面中心。

import sensor, image, time import pyb from servo_gimbal import ServoGimbal # 假设我们将上面的类保存为 servo_gimbal.py # 初始化摄像头 sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) # 320x240 sensor.skip_frames(time = 2000) sensor.set_auto_gain(False) # 追踪颜色时最好关闭自动增益 sensor.set_auto_whitebal(False) # 关闭白平衡 # 定义要追踪的颜色阈值 (LAB色彩空间) # 这里以追踪亮绿色为例,实际需要通过工具菜单->机器视觉->阈值编辑器来获取 green_threshold = (30, 80, -40, -10, 20, 60) # 初始化云台 gimbal = ServoGimbal() # 设置云台初始位置,让摄像头朝前 gimbal.move_to(90, 90) time.sleep_ms(1000) # 获取画面中心坐标 center_x = sensor.width() // 2 # 160 center_y = sensor.height() // 2 # 120 # PID控制器参数(比例-积分-微分) # 这些参数需要根据云台机械惯性、舵机速度进行实际调试 Kp_pan = 0.5 # 水平比例系数 Kp_tilt = 0.5 # 垂直比例系数 # 初始可以只用P(比例)控制,I和D设为0,系统稳定后再考虑加入 Ki_pan = 0.0 Ki_tilt = 0.0 Kd_pan = 0.0 Kd_tilt = 0.0 # PID误差累积变量 integral_pan = 0 integral_tilt = 0 last_error_pan = 0 last_error_tilt = 0 clock = time.clock() while(True): clock.tick() img = sensor.snapshot() # 1. 寻找色块 blobs = img.find_blobs([green_threshold], pixels_threshold=100, area_threshold=100, merge=True) if blobs: # 找到最大的色块 largest_blob = max(blobs, key=lambda b: b.pixels()) # 在图像上画出矩形和十字 img.draw_rectangle(largest_blob.rect(), color=(255,0,0)) img.draw_cross(largest_blob.cx(), largest_blob.cy(), color=(0,255,0)) # 2. 计算目标与画面中心的误差 error_pan = largest_blob.cx() - center_x # 水平误差:目标中心X - 画面中心X error_tilt = largest_blob.cy() - center_y # 垂直误差:目标中心Y - 画面中心Y # 3. 应用简单的P控制(比例控制) # 误差越大,需要补偿的角度变化量越大 pan_adjustment = error_pan * Kp_pan tilt_adjustment = error_tilt * Kp_tilt # 4. 计算新的目标角度(当前角度 + 调整量) # 注意:误差是像素,调整量也是像素单位,需要转换为角度。 # 这里做一个简化映射:假设画面边缘到中心对应云台转动30度。 # 即 error_pan从 -160 到 +160,对应 pan_adjustment_angle 从 -30度 到 +30度 pan_adjustment_angle = (pan_adjustment / center_x) * 30 tilt_adjustment_angle = (tilt_adjustment / center_y) * 30 new_pan_angle = gimbal.pan_angle - pan_adjustment_angle # 注意符号:如果目标在右边(error>0),云台应向右转(pan_angle增加) new_tilt_angle = gimbal.tilt_angle + tilt_adjustment_angle # 如果目标在下边(error>0),云台应向下转(tilt_angle增加) # 5. 限制角度范围并发送指令 # 直接调用move_to,它会进行限幅。为了更平滑,可以调用smooth_move。 gimbal.move_to(new_pan_angle, new_tilt_angle) # 或者使用平滑移动(推荐,但计算量稍大) # gimbal.smooth_move(new_pan_angle, new_tilt_angle, steps=5, delay_ms=10) # 打印调试信息 print("Target:({:3d},{:3d}) Error:({:4d},{:4d}) AdjAngle:({:5.1f},{:5.1f}) NewAngle:({:5.1f},{:5.1f}) FPS:{:.1f}".format( largest_blob.cx(), largest_blob.cy(), error_pan, error_tilt, pan_adjustment_angle, tilt_adjustment_angle, new_pan_angle, new_tilt_angle, clock.fps())) else: # 没有找到色块,可以执行搜索模式或停止不动 print("No blob found. FPS:{:.1f}".format(clock.fps())) # 例如:缓慢地水平扫描 # current_pan = gimbal.pan_angle # if current_pan <= 60: # gimbal.smooth_move(current_pan+5, 90, steps=10, delay_ms=30) # elif current_pan >= 120: # gimbal.smooth_move(current_pan-5, 90, steps=10, delay_ms=30) # else: # gimbal.smooth_move(current_pan+5, 90, steps=10, delay_ms=30)

视觉追踪的关键逻辑与调试经验:

  1. 误差计算:核心是计算目标物体中心点与画面中心点的像素差(error_x, error_y)。这个误差就是我们需要用舵机去“补偿”的量。
  2. 从像素误差到角度指令:这是整个控制环中最需要实际调试的一步。代码中的(error / center) * 30是一种线性映射假设。实际上,这个映射关系取决于摄像头的焦距、舵机安装位置、物体距离等多种因素。最佳实践是“实测标定”:
    • 将目标物体固定在画面最左侧,记录下此时云台的水平角度A。
    • 将目标物体移动到画面最右侧,记录角度B。
    • 那么,水平方向的角度变化范围就是B - A,对应像素范围是sensor.width()。比例系数就是(B - A) / sensor.width()。垂直方向同理。用这个实测的比例系数替换掉代码中固定的30,控制会精准得多。
  3. 控制算法:示例中使用了最简单的比例(P)控制。Kp系数的大小直接影响系统的响应速度。Kp太大,云台会剧烈振荡,在目标左右来回晃;Kp太小,云台移动缓慢,总是追不上快速移动的目标。需要耐心反复测试,找到一个响应迅速又稳定的值。
  4. 平滑与响应速度的权衡:使用smooth_move会让运动更柔和,但也会引入延迟,可能跟不上快速移动的目标。在追踪场景下,通常直接使用move_to,但可以适当减小控制周期(提高主循环的FPS),并精心调校PID参数来抑制抖动。

4. 进阶技巧与深度避坑指南

掌握了基础控制后,下面这些从实际项目中总结的经验,能帮你把项目做得更可靠、更专业。

4.1 电源噪声与信号干扰的解决之道

即使使用了独立电源,在多舵机、特别是大扭矩舵机(如MG996R)同时动作时,电源线上仍会产生较大的电压波动和电流噪声。这些噪声可能通过共地线串扰到OpenMV4,导致:

  • 摄像头图像出现横条纹或抖动。
  • OpenMV4程序偶尔跑飞或重启。
  • 舵机偶尔抽动一下,不受控制。

解决方案:

  1. 电源滤波:在舵机供电入口处并联一个大容量电解电容(如470uF 16V)和一个小容量陶瓷电容(如0.1uF)。电解电容应对低频大电流波动,陶瓷电容滤除高频噪声。这是成本最低、效果最显著的改进。
  2. 磁珠隔离:在舵机信号线上串接一个铁氧体磁珠,可以有效抑制高频干扰信号从舵机端传回OpenMV4。
  3. 使用稳压模块:确保外接电源是干净的。如果使用电池,建议中间加一个高质量的DC-DC稳压模块(如LM2596),并将其输出电容加大。
  4. 物理隔离:尽量将电源线(特别是大电流路径)与OpenMV4的信号线、摄像头排线分开走线,避免平行缠绕。

4.2 舵机抖动与中位校准:硬件本身的“脾气”

新买的舵机,或者使用一段时间后,可能会发现它停在某个角度时有轻微的高频抖动,或者“零点”(500us脉冲对应的位置)并不精确对应0度。

抖动处理:

  • 检查机械负载:确保舵机摇臂安装牢固,没有外力卡住或负载过重。
  • 检查电源:用万用表测量舵机VCC和GND之间的电压,在大角度转动时是否跌落严重(如从5V跌到4.5V以下)。如果是,说明电源功率不足,需要升级。
  • 软件死区:在控制代码中,可以为目标角度设置一个“死区”。例如,如果目标角度与当前角度差值小于0.5度,就不发送新的PWM指令。这可以避免因传感器噪声或计算舍入导致的微小角度变化不断驱动舵机,从而消除抖动。
    def move_to_with_deadzone(self, target_angle, current_angle, deadzone=0.5): if abs(target_angle - current_angle) > deadzone: # 执行移动 self._raw_move_to(target_angle) return target_angle else: # 不移动,返回当前角度 return current_angle

中位校准: 每个舵机的中位脉冲宽度可能有微小差异。更专业的做法是进行校准:

  1. 编写一个测试程序,让舵机以0.1%的步进改变占空比(对应约0.036度)。
  2. 机械上安装一个指针,对准一个参考零点。
  3. 运行程序,找到舵机臂完全对准参考零点时对应的占空比值,记录下来。
  4. 以后在代码中,就以这个校准值作为“0度”的基准进行计算。

4.3 定时器冲突与资源管理

OpenMV4的硬件定时器(Timer)是有限资源,除了用于PWM,还可能被内部系统或其他功能(如串口超时、引脚中断等)占用。当你发现舵机控制突然失效,或者和其他功能(如特定的图像算法、多线程)同时使用时出问题,很可能遇到了定时器冲突。

排查与解决:

  1. 查阅官方文档:仔细阅读OpenMV4的官方数据手册,查看你使用的引脚(如P7、P8)对应的定时器通道有哪些,以及这些定时器是否还被其他系统功能默认启用。
  2. 避免使用系统关键定时器:有些定时器(如TIM5)可能被摄像头底层驱动或文件系统占用。尽量使用TIM2, TIM3, TIM4等用户可自由支配的定时器。
  3. 统一管理:在项目开始时,规划好所有需要PWM的功能(舵机、蜂鸣器、LED调光等),为它们分配不同的定时器通道,并在一个中心模块中初始化,避免在代码不同地方重复初始化冲突。
  4. 使用pyb.Timer的deinit()方法:在程序结束或需要重新配置定时器前,调用tim.deinit()来释放定时器资源,这是一个好习惯。

4.4 超越180度:连续旋转舵机与角度舵机的模式切换

市面上还有一种“连续旋转舵机”。它去掉了内部的位置反馈电位器,其PWM信号不再对应角度,而是对应旋转速度和方向。

  • 1500us:停止。
  • 1300us - 1500us:顺时针慢速到停止。
  • 1500us - 1700us:停止到逆时针慢速。
  • 极端值(如500us和2500us)对应两个方向的全速。

如果你的项目需要轮式小车驱动,这种舵机就派上用场了。控制代码只需微调:

def set_speed(speed): """ :param speed: -100 到 +100。负值为逆时针,正值为顺时针。 """ speed = max(-100, min(100, speed)) # 限幅 # 将速度映射到脉冲宽度:-100->1300us, 0->1500us, +100->1700us pulse_width_us = 1500 + speed * 2 # 每1%速度对应2us变化 duty = pulse_width_us / 20000.0 ch.pulse_width_percent(duty * 100)

重要提示:务必确认你手中的舵机型号。将角度舵机当作连续旋转舵机来驱动(发送非中位信号并期望它连续转),会迫使电机堵转,几秒钟内就可能烧毁。

相关新闻

  • 2025年Flash浏览器终极指南:如何让经典Flash游戏和网页重获新生
  • Kafka性能调优实战:从原理到最佳实践
  • 2026年便携式臭氧检测仪源头厂家推荐:四家优选厂商的实用指南 - geo交流

最新新闻

  • TCP三次握手原理与高并发优化实践
  • 开源AI语音合成工具animated-voiceover本地部署与实战指南
  • Python基础之日志封装
  • 告别Office安装噩梦!LKY_OfficeTools让你一键拥有完整办公套件
  • 金蝶ERP一套多少钱?2026年完整费用拆解,别只看报价单
  • 食品加工厂地面清洁机器人实力盘点: 2026主流品牌多维度解读

日新闻

  • 5分钟快速搭建智能数字人:Live2D虚拟形象终极部署指南
  • 告别繁简字幕转换烦恼:这款开源工具让你一键搞定影视字幕处理 [特殊字符]
  • GPT-5.4传闻背后:大模型永久记忆与极限推理的技术演进与挑战

周新闻

  • 怀化母婴除甲醛公司测甲醛中心怎么选:康之居母婴除甲醛标准、流程、避坑指南 - 信誉隆金银铂奢回收
  • 三步打造你的终极音乐中心:foobox-cn网络电台功能完整指南
  • Lance湖仓格式:为多模态AI工作流设计的终极数据存储方案

月新闻

  • ClickHouse版本管理深度实战:4步构建零风险升级与回滚体系
  • Java 23 种设计模式:从踩坑到精通 | 番外:责任链模式 —— 物流审批流程实战
  • 华硕笔记本性能解放指南:G-Helper轻量级控制工具全面解析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号