【K210+micropython】PWM信号控制舵机

【K210+micropython】PWM信号控制舵机



相关知识准备


一、舵机

舵机又叫伺服电机,是一个可以旋转特定角度的电机,可转动角度通常是
90°、180°和 360°(360°可以连续旋转)。
在这里插入图片描述

我是在一个二轴舵机云台上进行代码验证的。
舵机一般按照转动方式可以分为两种。一种是可调角度但不能调转速的180度舵机,另一种是可调转速但不能调角度的360度舵机。前者虽然叫“180度舵机”,但是你如果用手转动转轴,你会发现它的转角其实可以大于180度,这是为什么呢?我也不是很懂唉~不过有一点可以确定,那便是通电后,它的转角范围确实只有180度。

二、PWM控制

180°舵机的控制一般需要一个 20ms 左右的时基脉冲,该脉冲的高电平部分一般为 0.5ms-2.5ms 范围内的角度控制脉冲部分,总间隔为 2ms。以 180 度角度伺服为例,在 MicroPython 编程对应的控制关系是从-90°至 90°,示例图如下
在这里插入图片描述
而对于 360°连续旋转舵机,上面的脉冲表则对应从正向最大速度旋转到反向最大速度旋转的过程。

看了上面的解释,如果你还是不太懂的话。那么就听听我不太专业的发言吧。
大概就是,你得用单片机输出一种波(叫PWM波)来控制舵机旋转,这种波通常是一束频率为50HZ(周期为20ms)的方波,然后喃,然后就是你得改变输出波形的占空比来使180度舵机转到不同的角度。不同占空比的PWM波对应舵机不同的角度,2.5%占空比对应的是0度,12.5%占空比对应的是180度。举个例子,如果你想让舵机转到135度,那么我们做一个简单的运算
d u t y ( 占 空 比 ) = 12.5 % − 2.5 % 180 ∗ 135 + 2.5 % duty(占空比) = \frac{12.5\%-2.5\%}{180}*135 +2.5\% duty()=18012.5%2.5%135+2.5%
这样,我们只需要输出一个占空比为duty的PWM波形就好了。

三、关键代码

  • 导入 PWM 模块,创建 PWM 对象,PWM 输出引脚接到舵机信号输入
from machine import Timer,PWM
tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
S1 = PWM(tim, freq=50, duty=0, pin=17)
  • 输出不同占空比波形来控制舵机
S1.duty(135/180*10+2.5)

PWM 控制 API 参考: PWM API

三、代码整合

1.Servo库

羡慕像openmv那样固件自带pyb模块的板子,\哭,同为microPython开发,咋差别就那么大呢。于是就上网找相关大佬写的开源库,然后自己效仿写了写。下面是自己乱写的servo库,大佬轻喷~~~~~
代码如下:

from machine import Timer,PWM
import time,sys


class Servo:

    def __init__(self, timer_id):
        self.pin = None
        self.freq = 50
        self.duty = 0
        self.servo = None
        self.interval = 500  # ms

        '''all timer default use channel0'''
        if timer_id == 0:
            self.tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
        elif timer_id == 1:
            self.tim = Timer(Timer.TIMER1, Timer.CHANNEL0, mode=Timer.MODE_PWM)
        elif timer_id == 2:
            self.tim = Timer(Timer.TIMER2, Timer.CHANNEL0, mode=Timer.MODE_PWM)
        else:
            print("erorr timer_id is [0,2]!")
            sys.exit(retval=0)

    def set_pin(self,pin_num):
        self.pin = pin_num
        self.servo = PWM(self.tim, freq=self.freq, duty=self.duty, pin=self.pin)

    def position(self,angle):
        time.sleep_us(self.interval)
        self.servo.duty(angle*1.0/180*10+2.5)

    def set_speed(self,_interval):
        self.interval = _interval

servo1 = Servo(1)
servo2 = Servo(2)
servo1.set_pin(17)
servo2.set_pin(18)


'''button event control'''
from Maix import GPIO
from fpioa_manager import fm
from board import board_info


fm.register(27,fm.fpioa.GPIO0)
fm.register(29,fm.fpioa.GPIO1)
fm.register(30,fm.fpioa.GPIO2)
fm.register(31,fm.fpioa.GPIO3)
key1 = GPIO(GPIO.GPIO0,GPIO.IN)
key2 = GPIO(GPIO.GPIO1,GPIO.IN)
key3 = GPIO(GPIO.GPIO2,GPIO.IN)
key4 = GPIO(GPIO.GPIO3,GPIO.IN)
angle1 = 0
angle2 = 0
dir_flag_1 = 2
dir_flag_2 = 2

while True:
    if key1.value()==0:
        time.sleep_ms(10)  
        if key1.value()==0:
            if dir_flag_1 != 1:
                angle1 = angle1 + 1

    if key2.value()==0:
        time.sleep_ms(10)  
        if key2.value()==0:
            if dir_flag_1 != 0:
                angle1 = angle1 - 1

    if angle1 == 180:
        dir_flag_1 = 1
    elif angle1 == 0:
        dir_flag_1 = 0
    else:
        dir_flag_1 = 2

    if key3.value()==0:
        time.sleep_ms(10)  
        if key3.value()==0:
            if dir_flag_2 != 1:
                angle2 = angle2 + 1

    if key4.value()==0:
        time.sleep_ms(10)   
        if key4.value()==0:
            if dir_flag_2 != 0:
                angle2 = angle2 - 1

    if angle2 == 135:
        dir_flag_2 = 1
    elif angle2 == 0:
        dir_flag_2 = 0
    else:
        dir_flag_2 = 2

    servo1.position(angle1)
    servo2.position(angle2)


遇到的问题和总结

  • 舵机供电问题

舵机一般需要外接电源的,根据舵机工作电压选择不同的外接电源。听说直接电脑给舵机供电可能会烧,不可轻易尝试啊(试试就逝世)~还有一点,千万不要像我一样蠢,直接把外接电源和舵机正负相接就完事了,还有必须要和单片机共地! 共地! 共地!(就是把外接电源、舵机、maix-bit的GND引脚相连)因为这个,我调了一下午舵机,换了不同的电源,尝试了很多种方法舵机,上电后一直没转。幸亏第二天同组的大佬学弟提醒了我(被自己菜哭)。

  • 舵机转动卡顿(抖动)

这个问题一般是由于在程序中给两种不同的PWM波之间设置了较长的延迟所导致的,可以适当修改延迟时长。

总结

对于二轴云台来说,简单控制舵机转动显得运动相当不稳,后期可以考虑加入PID来使得运动变得更加“丝滑”。

  • 12
    点赞
  • 135
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值