当前位置:   article > 正文

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

arduino 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); 
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

关于霍尔电机的转速控制

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/608282
推荐阅读
相关标签
  

闽ICP备14008679号