舵机的控制原理各位可以看这篇文章——舵机控制原理
python3有相应的PWM控制库,如 python3-libgpiod、python-periphery 。但由于不同舵机实际的0°~180°对应的脉宽为不一定是0.5ms~2.5ms,也可能为0.4ms~2.4ms这样的微小误差,这会导致你标准库控制舵机的角度就不精确。
所以本次采用的是python3的文件IO来配置Linux板子的PWM设备,其控制进准度代码如下:
import time
# 导出 PWM 控制器
def pwm_export(pwmid):
with open('/sys/class/pwm/pwmchip%d/export' % pwmid, 'wb') as f:
f.write("0".encode())
# 取消导出 PWM 控制器
def pwm_unexport(pwmid):
with open('/sys/class/pwm/pwmchip%d/unexport' % pwmid, 'wb') as f:
f.write("0".encode())
# 配置 PWM 周期和占空比
def pwm_config(pwmid, pwmPeriod, pwmDutyCycle):
with open('/sys/class/pwm/pwmchip%d/pwm0/period' % pwmid, 'wb') as f:
f.write(str(pwmPeriod).encode())
with open('/sys/class/pwm/pwmchip%d/pwm0/duty_cycle' % pwmid, 'wb') as f:
f.write(str(pwmDutyCycle).encode())
# 使能 PWM 控制器
def pwm_enable(pwmid):
with open('/sys/class/pwm/pwmchip%d/pwm0/enable' % pwmid, 'wb') as f:
f.write("1".encode())
# 禁用 PWM 控制器
def pwm_disable(pwmid):
with open('/sys/class/pwm/pwmchip%d/pwm0/enable' % pwmid, 'wb') as f:
f.write("0".encode())
# 设置 PWM 极性
def pwm_polarity(pwmid, pwmPolarity):
with open('/sys/class/pwm/pwmchip%d/pwm0/polarity' % pwmid, 'wb') as f:
f.write(pwmPolarity.encode())
# 初始化 PWM 控制器
def pwm_structure(pwmid, pwmPeriod, pwmDutyCycle, pwmPolarity):
pwm_export(pwmid)
pwm_config(pwmid, pwmPeriod, pwmDutyCycle)
pwm_polarity(pwmid, pwmPolarity)
pwm_enable(pwmid)
# 销毁 PWM 控制器
def pwm_destruction(pwmid):
pwm_disable(pwmid)
pwm_unexport(pwmid)
# 角度转换为 PWM 占空比
def set_servo_angle(angle):
min_pulse = 500 # 最小脉冲宽度
max_pulse = 2500 # 最大脉冲宽度
# 限制角度在0到180度之间
angle = max(0, min(180, angle))
# 计算占空比
pwmDutyCycle = 1000 * int((angle / 180.0) * (max_pulse - min_pulse) + min_pulse)
# 配置 PWM
pwm_config(1, 20000000, pwmDutyCycle)
# 比例控制函数
def P_control(initial_value, target_value, change_rate):
while abs(initial_value - target_value) > 0.5: # 当最后一个返回的值接近设定值时退出循环
error = target_value - initial_value
change = error * change_rate
initial_value += change
set_servo_angle(initial_value)
# 主函数
if __name__ == '__main__':
pwm_index = 1
pwm_structure(pwm_index, 20000000, 0, "normal") # 初始化 PWM 控制器,设置周期和占空比
try:
while True:
# 使用比例控制器进行控制
P_control(5, 180, 0.001) # 从角度5逐渐增加到180
P_control(180, 5, 0.001) # 从角度180逐渐减少到5
finally:
pwm_destruction(1) # 销毁 PWM 控制器
以上的注释应该也很详细了。比例控制就根据给的比例系数change、目标角度target_value与实际角度initial_value的差值,去计算每次控制舵机变化的角度值,让舵机先快后慢去稳定达到目标角度,实现舵机的丝滑控制!其中pwmid要根据自己要用的pwm编号去设置。
于是这个py文件可以作为控制舵机的一个库来使用,可根据不同舵机先调试一下脉宽范围,修改一下里面的脉宽参数,就能达到精准控制的效果了。