【Arduino 101】五分钟搞懂PID控制算法



演示视频

【Arduino 101】五分钟搞懂PID控制算法


物料清单

Arduino Uno x 1
超声波模块(HC-SR04)x 1
舵机(Tower Pro MG996R)x 1
舵机供电: 5V 稳压管(LM7805) x 1 , 滤波电容 (0.33uF, 0.1uF) x 2, 9V 电池 x 1
滑轨:泡沫板
支架:乐高
滚动物体:胶带(Up试过网球,但是测距模块的表现不理想)


尺寸 & 设计缺陷

在这里插入图片描述
设计缺陷:
1: 测距模块读数不稳定,存在+/-5mm 的浮动。
2: 整体制作比较粗糙,轨道摩擦不均匀。对稳态误差的出现原因仅仅是个猜测,所以视频中用了“可能”两个字。


接线

在这里插入图片描述


Arduino IDE 代码

/* PID control Demo, PID 控制算法演示
 * Last Edited: March.12th.2021 by Mun Kim
 * Contact: Robotix.Kim@gmail.com
 */

#include <Servo.h>

Servo servo;   
int angle = 0;                           //舵机角度

#define echo 2                           //HC-SR04的Echo接 Arduino D2
#define trig 3                           //HC-SR04的Trig接 Arduino D3
float time, duration, distance;

//PID constants****************************************************************
float setPoint=19;                       //滑轨中心与测距模块的距离
float error;                             //当前误差
float previous_error;                    //上一时刻误差,用来计算D
float kp=0;                              //10
float ki=0;                              //0.05
float kd=0;                              //200 
int   dt=50;                             //每50毫秒进行一次计算                       
float P,I,D, PID;
//*****************************************************************************

void setup() {
  Serial.begin(9600);
  pinMode(trig, OUTPUT); 
  pinMode(echo, INPUT); 
  servo.attach(9);                 
  time = millis();
}

void loop() {
    if (millis() > time + dt)
  {
    time = millis();    

    // HC-SR04 Distance Measuremnt, 通过超声波模块测量胶带的位置*******************
    digitalWrite(trig, LOW); 
    delayMicroseconds(2); 
    digitalWrite(trig, HIGH); 
    delayMicroseconds(10); 
    digitalWrite(trig, LOW); 

    duration = pulseIn(echo, HIGH);        //读取反射信号 
    distance = (duration*0.0343)/2;        //测距公式,单位为cm
    
    // PID Calculation, PID计算*************************************************
    error = distance-setPoint;             //计算误差
    P = kp*error;                          //P项
    if(-4 < error && error < 4){
       I += ki*error;    }                 //I项
    else{
       I = 0;            }   
    D = kd*((error - previous_error)/dt);  //D项,
    PID=P + I + D ;                        //PID
    if (PID>200){PID=200;}                 //限幅
    if (PID<-200){PID=-200;}               //限幅

    previous_error=error;                  //更新上一时刻误差
    
    // Serial Display,在串口监视器显示每个项,有助于调试*****************************
     Serial.print("Distance: "); Serial.print(distance); Serial.print(" cm  "); 
     Serial.print("Error: ");    Serial.print(error);    Serial.print(" cm  ");
     Serial.print("   P: ");     Serial.print(P); 
     Serial.print("   D: ");     Serial.print(D);
     Serial.print("   I: ");     Serial.print(I);
     Serial.print("   PID: ");   Serial.println(PID);
    
    // Servo Control,用计算结果控制舵机*******************************************
    angle = map(PID, -200,200,150,20);
    servo.write(angle); 
  }
}

关于霍尔电机的转速控制

Up只是把上面有关PID计算的代码块搬到上期的项目中,替代了起停式控制的那一部分。dt=1s。详细的接线以及代码请大家参考这个博文:
【Arduino 101】霍尔编码器(增量,正交)与起停式闭环控制

  • 55
    点赞
  • 258
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值