前回の「PID制御とは?編」に引き続きArduinoIDEでPID制御をプログラムにしてみました!
1. プログラム
1.1 計算式
プログラムの元になるPID制御の計算式は式1の通りです。
1.2 接続
図1,黄色線部の様に、ArduinoUNOの2番ピンと3番ピンをジャンプワイヤーで接続するだけでOKです!
図1:ArduinoUNO回路図
1.3 プログラム
/*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:プログラム例
2. 実験!
2.1 測定
上記プログラムを実行すると図2の様にPCのシリアルモニター上に2番ピンへの入力値「input」と、3番ピンからの出力値「output」が1秒毎に表示されます。
3. まとめ
前回の記事 に書きましたが、PID制御のパラメータ(Kp,Ki,Kd)設定が肝です。
設定を誤ると永遠に目標値に届かなかったり、制御幅が大き過ぎて振幅が止まらなかったりします
励みになりますのでよければクリック下さい(^o^)/