NOBのArduino日記!

NOBのArduino日記!

趣味は車・バイク・自転車・ラジコン・電子工作です。

PID制御!(プログラム編)

イメージ 2
 前回の「PID制御とは?編」に引き続きArduinoIDEでPID制御をプログラムにしてみました!

※PID制御とは、制御工学におけるフィードバック制御の一種であり、産業用制御システムでは今でも広く使用されている制御ループフィードバックメカニズムです。

1. プログラム

1.1 計算式
 プログラムの元になるPID制御の計算式は式1の通りです。
 MV= MVn-1 + Kp(en-en-1) + Ki en + Kd*1・・・式1
※MVn    : 今回操作量
※MVn-1   : 前回操作量
※Kp,Ki,Kd: 比例,積分,微分項のパラメータ
※en    : 今回の偏差
※en-1  : 前回の偏差
※en-2  : 前々回の偏差

 

1.2 接続
 図1,黄色線部の様に、ArduinoUNOの2番ピンと3番ピンをジャンプワイヤーで接続するだけでOKです!
イメージ 2
図1:ArduinoUNO回路図
 
1.3 プログラム
 PID制御をArduinoIDEでプログラムにしたものを下記に示します。
 内容としては、3番ピンから出したPWM信号のDuty比を2番ピンで測定し、測定結果と目標値のズレから次に3番ピンから出力するPWM信号のDuty比を式1から求め出力する事を繰り返します!
/*NOBのArduino日記!_PID制御!プログラム編_20170330*/
double setpoint = 180, Kp = 0.1, Ki = 0.1, Kd = 0.1;
double input = 0, MVn = 0, MVn1 = 0, en = 0, en1 = 0, en2 = 0;

// PWMのD比測定(詳細はコチラ)
volatile float Duty;
volatile unsigned long UpNew, UpOld, DownNew, DownOld;
void SUB() {
  if (digitalRead(2) == LOW) {
    DownOld = DownNew; DownNew = micros();
    Duty = ((DownNew - UpNew) * 1000) / ((UpNew - UpOld)) * 0.1;
  }
  else {
    UpOld = UpNew; UpNew = micros();
    Duty = ((DownNew - UpOld) * 1000) / (UpNew - UpOld) * 0.1;
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(3, OUTPUT); pinMode(2, INPUT_PULLUP); //3ピン出力2ピン入力設定
  attachInterrupt(0, SUB, CHANGE);
}//2ピンの電圧変化時にSUB実行

void loop() {
  input = map(Duty, 0, 100, 0, 255); //2ピン入力値取得
  en2 = en1; //前々回の偏差
  en1 = en; //前回の偏差
  en = (setpoint - input); //今回の偏差
  MVn1 = MVn;  //前回操作量
  MVn = MVn1 + Kp * (en - en1) + Ki * en + Kd * ((en - en1) - (en1 - en2)); //PID制御量計算
  MVn = constrain(MVn, 0, 255); analogWrite(3, MVn); //3ピンから出力
  Serial.print("input="); Serial.print(input);
  Serial.print(",output="); Serial.println(MVn); delay(1000);
}
イメージ 1
図1:プログラム例
 

2. 実験!

2.1 測定
 上記プログラムを実行すると図2の様にPCのシリアルモニター上に2番ピンへの入力値「input」と、3番ピンからの出力値「output」が1秒毎に表示されます。
イメージ 1
図2:Arduino IDE シリアルモニター

2.2 結果
 図2で測定されたデータをグラフ化したものを図3に示します。
 安定して目標値の180付近に向かって制御されました!
イメージ 3
図3:図2グラフ化

3. まとめ

 前回の記事 に書きましたが、PID制御のパラメータ(Kp,Ki,Kd)設定が肝です。
 設定を誤ると永遠に目標値に届かなかったり、制御幅が大き過ぎて振幅が止まらなかったりします
 
イメージ 1 イメージ 3
励みになりますのでよければクリック下さい(^o^)/

↩【PID制御!】目次に戻る