ESP32(MicroPython)编码器电机PID距离控制

本程序通过PID控制编码器电机的转动距离,程序运行时输入目标距离(距离为编码器计数,目标距离为距当前位置的距离,如果距离计数改为不归零则可以控制距开始位置的距离),程序累加编码器计数作为距离计数并计算与目标值的偏差,并据此进行PID控制。增大P值有助于确保电机正常启动。实测增大D值对减少抖动、加快距离稳定有明显帮助。最终P值调到8,I调到5,D调到6。由于难以准确评估不同调校的效果,上述参数不一定是最佳参数。认定是否到达目标位置时可以按实际需要留一定余量以加快相应,还要结合结束时的速度进行判断。

代码如下

python 复制代码
from machine import *
import time
from moto import *
import random
'''
本程序使用增量式PID,公式为
Pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
e(k):本次偏差
e(k-1):上一次的偏差
e(k-2):上上次的偏差
Kp:比例项参数
Ki:积分项参数
Kd:微分项参数
Pwm:代表增量输出
'''
# 编码器初始化
pin18 = Pin(18, Pin.IN)
pin19 = Pin(19, Pin.IN)   
encoder = encoder(pin18, pin19, 0)   # 参数(编码器A相引脚,编码器B相引脚,定时器序号)

# 电机初始化
motor=Pin(15,Pin.OUT)
motor.value(0)
motor1=PWM(Pin(4),freq=1000,duty=0)
motor2=PWM(Pin(16),freq=1000,duty=0)
while True:
    speed = encoder.read() #测试时发现有时候占空比不能回0,就增加一项检测,确保占空比回零
    if speed>2 or speed<-2: 
        motor1.duty(0)    
        motor2.duty(0)
    else:
        break
duty=0
target=0
distance=0
offset=0 #e(k)
offset1=0 #e(k-1)
offset2=0 #e(k-2)
p=8 #PID参数
i=5
d=6
  
while True:
    motor1.duty(0)    
    motor2.duty(0)
    motor1.duty(0)    
    motor2.duty(0)
    target=int(input('target_distance'))
    while True:
        speed = encoder.read()
        distance+=speed
        offset2=offset1 #记录上一次偏差
        offset1=offset
        offset=target-distance
        adjustmentP=offset-offset1
        adjustmentP*=p
        adjustmentI=offset
        adjustmentI=round(adjustmentI*i)
        adjustmentD=offset-offset1-offset1+offset2
        adjustmentD*=d
        duty=adjustmentP+adjustmentI+adjustmentD
        if duty<-1023:
            duty=-1023
        elif duty>1023:
            duty=1023
        if duty>0:
            if duty<200:
                duty=200
            motor1.duty(duty)
            motor2.duty(0)
        if duty<0:
            if duty>-200:
                duty=-200
            motor1.duty(0)    
            motor2.duty(-duty)
        print(offset,duty)
        if offset<11 and offset>-11 and speed<11 and speed>-11: #误差的速度较小时停止
            motor1.duty(0)    
            motor2.duty(0)
            while True:
                speed = encoder.read() #测试时发现有时候占空比不能回0,就增加一项检测,确保占空比回零
                if speed>2 or speed<-2: 
                    motor1.duty(0)    
                    motor2.duty(0)
                else:
                    break
            distance=0 #不归零则可以控制距开始位置的角度
            break
        time.sleep(0.05)
    
相关推荐
卷无止境7 分钟前
智能体开发环境ADE浅析,编程工具的下一次范式跃迁
后端·python
彧azz2 小时前
图的存储结构详解:邻接矩阵的原理、实现与应用
开发语言·数据结构·学习·php
单片机仿真设计3 小时前
【proteus仿真】基于 STM32 单片机衣柜温湿度监测系统(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus
嵌入式学习菌3 小时前
Modbus‑RTU 数据类型分析
开发语言·单片机·bug
千秋岁rr3 小时前
11.USART
单片机·嵌入式硬件
ouynagda3 小时前
51 单片机外部中断 + 定时器中断实验(P3.2 按键清零,无消抖)
单片机·嵌入式硬件
辰域电子3 小时前
STM32项目开源:环境质量监测系统(代码+原理图+仿真)
stm32·单片机·嵌入式硬件·开源·毕业设计·proteus
单片机仿真设计4 小时前
【proteus仿真】基于 STM32+DHT11 温湿度监测系统 Proteus 仿真设计
stm32·单片机·嵌入式硬件·proteus
matlab代码4 小时前
基于matlab数字图像处理的指纹识别系统【源码68期】
开发语言·matlab
国科安芯4 小时前
星链供电架构中的高集成度电源管理方案研究——基于ASP4644四通道降压稳压器在低轨卫星星座中的应用分析
大数据·单片机·嵌入式硬件·架构·低轨卫星·星间链路