PID_v1.h 库的奇怪问题-Arduino中文社区 - Powered by Discuz! Archiver

pig881 发表于 2016-4-14 21:42

PID_v1.h 库的奇怪问题

官方的代码:

#include <PID_v1.h>
double Setpoint,Input ,Output;

PID myPID(&Input,&Output,&Setpoint,2,5,1,DIRECT);
void setup() {

   Serial.begin(9600);
   Input=80;
   Setpoint=100;

myPID.SetMode(AUTOMATIC);
}

void loop() {
Input = 80;

myPID.Compute();
//analogWrite(3,Output);

Serial.print("Output= ");
Serial.println(Output);
delay(500);
}

原代码的 Input 是读取 A0 口的模拟值 ( 有的代码里还会 map(val, 0 ,1023 , 0, 255)   类似这样的);

我这里把 Input 设置为一个固定值, setpoint 定为 100


为什么 OUTPUT 一开始是接近 setpoint,后面就一直向上,直到 255,就不变了,我觉得很纳闷,

到底这个 Input 有什么用?还是代码本身有什么问题?


http://image.geek-workshop.com/forum/201604/14/203607nllmkutuqkgv26ah.png

开心咔咔 发表于 2016-4-15 08:52

INPUT固定,程序认为调整无效,继续调整。主要是PID里的积分导致。

pig881 发表于 2016-4-15 13:40

开心咔咔 发表于 2016-4-15 08:52
INPUT固定,程序认为调整无效,继续调整。主要是PID里的积分导致。

听起来是有那么点道理,但是我昨晚做了试验,如果输入Input 比 Setpoint大(超过1),那么OUTPUT会趋于0,最终变成0,如果Setpoint 比 Input 大1,或是小1(在这个区间内变化),那么OUTPUT 会是一个常数,在一个小范围内变化(大概也是正负1左右的变化幅度) ,但是我的目的是要OUTPUT 跟 SETPOINT 变化,一样,或是不差太远,这不也是PID算法的最主要的作用吗?

qchi1983 发表于 2016-4-15 15:00

PID為閉迴路控制系統, 當PID output輸出後, 會再觀察input 和setpoint間的差值變化, 在計算下一步的輸出, 進而讓被控物達到目標(input-setpoint=0); 你的範例給定input為定值, 也就是說無論PID output如何輸出, 始終無法讓 input 與setpoint的差值為零 , 所以而積分控制項將驅動PID 輸出趨近於最大或最小;至於你讓setpoint比Input在 +/-1區間做變化, PID輸出為常數, 有以下兩種可能 1) Ki 的值太小使PID output反應不出來; 2)在setpoint +/-1 之間有加filter提高PID控制器的穩定度

pig881 发表于 2016-4-15 17:43

qchi1983 发表于 2016-4-15 15:00
PID為閉迴路控制系統, 當PID output輸出後, 會再觀察input 和setpoint間的差值變化, 在計算下一步的輸出,...

其实我输入Input不是固定的,我是采用 测速输入的 ,码盘测速,20线 ,测出来是从 68 到 79之间变化的

pig881 发表于 2016-4-15 17:49

我的码盘是 20格的,Input 也是根据码盘测速来变化,speeds 测速是这样
volatile int scode = 0; //speed test

void setup() {
    attachInterrupt(digitalPinToInterrupt(OUT1),code,CHANGE );


}

void code() //interrputer
{
    scode = scode + 1;
}


void speedtest() {
    detachInterrupt(digitalPinToInterrupt(OUT1));
    oldtime = newtime;
    speeds = scode / 2;
    scode = 0;
    delay(1);
    attachInterrupt(digitalPinToInterrupt(OUT1), code, CHANGE);
}


void loop() {

newtime =newtime1= millis();
    if (newtime - oldtime > 1000) {
      Serial.println("begin test...");
      speedtest();
      speedtest1();
       // Setpoint=speeds1;         // 曾经把 Setpoint 放在这里,试图用另外一边轮子的速度作为标准 ,但是OUTPUT值不是趋向于0就是趋向于255
    }



   Input =speeds;
    myPID.Compute();


}

开心咔咔 发表于 2016-4-15 22:57

你的Ki=5,对于+-1来说太大,用小于1的值试试。pid得参数要自己搭配找到最合适的值。

pig881 发表于 2016-4-16 08:46

开心咔咔 发表于 2016-4-15 22:57
你的Ki=5,对于+-1来说太大,用小于1的值试试。pid得参数要自己搭配找到最合适的值。 ...

输出并不是确定的,有时候是+-1,有时候也有更大的值,我试过更换其他Ki ,但是好像总是变成0,或是255(当speed为0的时候)
页: [1]
查看完整版本: PID_v1.h 库的奇怪问题