NOBのArduino日記!

NOBのArduino日記!

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

PID_AutoTune_v0.hライブラリ(Get/Set ControlType関数の使い方)

■Get/Set ControlType関数
  PID_AutoTune_v0.hライブラリのGet/Set ControlType関数は、GetKpなどが呼び出されたときに、PIまたはPIDチューニングパラメータを 取得/設定 します。

■使用例
 Arduino IDEで使用するGet/Set ControlType関数の使用例は以下の通りです。
 試しにこのプログラムをArduino UNOで実行すると、DoModel関数で生成したInput値に対してPID関数でPID制御を開始します。
 Get ControlType関数によって取得したチューニングパラメータの値が図1の様にPCのシリアルモニタ上に出力されます。

#include <PID_v1.h>
#include <PID_AutoTune_v0.h>
byte ATuneModeRemember = 2;
double input = 80, output = 50, setpoint = 180;
double kp = 2, ki = 0.5, kd = 2;
double kpmodel = 1.5, taup = 100, theta[50];
double outputStart = 5;
double aTuneStep = 50, aTuneNoise = 1, aTuneStartValue = 100;
unsigned int aTuneLookBack = 20;
boolean tuning = false;
unsigned long  modelTime, serialTime;
PID myPID(&input, &output, &setpoint, kp, ki, kd, DIRECT);
PID_ATune aTune(&input, &output);
boolean useSimulation = true;

void AutoTuneHelper(boolean start) {
  if (start)
    ATuneModeRemember = myPID.GetMode();
  else
    myPID.SetMode(ATuneModeRemember);
}

void changeAutoTune() {
  if (!tuning) {
    output = aTuneStartValue;
    aTune.SetNoiseBand(aTuneNoise);
    aTune.SetOutputStep(aTuneStep);
    aTune.SetLookbackSec((int)aTuneLookBack);
    AutoTuneHelper(true);
    tuning = true;
  }
  else
  {
    aTune.Cancel();
    tuning = false;
    AutoTuneHelper(false);
  }
}

void SerialSend() {
  Serial.print("Type: "); Serial.print(aTune.GetControlType()); Serial.print(" ");
  Serial.print("setpoint: "); Serial.print(setpoint); Serial.print(" ");
  Serial.print("input: "); Serial.print(input); Serial.print(" ");
  Serial.print("output: "); Serial.print(output); Serial.print(" ");
  if (tuning) {
    Serial.println("tuning mode");
  } else {
    Serial.print("kp: "); Serial.print(myPID.GetKp()); Serial.print(" ");
    Serial.print("ki: "); Serial.print(myPID.GetKi()); Serial.print(" ");
    Serial.print("kd: "); Serial.print(myPID.GetKd()); Serial.println();
  }
}

void SerialReceive() {
  if (Serial.available()) {
    char b = Serial.read();
    Serial.flush();
    if ((b == '1' && !tuning) || (b != '1' && tuning))changeAutoTune();
  }
}

void DoModel() {
  //cycle the dead time
  for (byte i = 0; i < 49; i++)
  {
    theta[i] = theta[i + 1];
  }
  //compute the input
  input = (kpmodel / taup) * (theta[0] - outputStart) + input * (1 - 1 / taup) + ((float)random(-10, 10)) / 100;
}

void setup() {
  if (useSimulation) {
    for (byte i = 0; i < 50; i++) {
      theta[i] = outputStart;
    }
    modelTime = 0;
  }
  //Setup the pid
  myPID.SetMode(AUTOMATIC);
  if (tuning) {
    tuning = false;
    changeAutoTune();
    tuning = true;
  }
  serialTime = 0;
  Serial.begin(9600);
}

void loop() {
  unsigned long now = millis();
  if (!useSimulation)
  {
    input = analogRead(0);
  }
  if (tuning) {
    byte val = (aTune.Runtime());
    if (val != 0) {
      tuning = false;
    }
    if (!tuning)
    {
      kp = aTune.GetKp();
      ki = aTune.GetKi();
      kd = aTune.GetKd();
      myPID.SetTunings(kp, ki, kd);
      AutoTuneHelper(false);
    }
  }
  else myPID.Compute();
  if (useSimulation) {
    theta[30] = output;
    if (now >= modelTime) {
      modelTime += 100;
      DoModel();
    }
  } else {
    analogWrite(0, output);
  }
  if (millis() > serialTime) {
    SerialReceive();
    SerialSend();
    serialTime += 500;
  }
}
イメージ 1
図1:プログラム例
 

 イメージ 1
図2:プログラム実行結果

 

■構文
 SetControlType(type)
■パラメータ
 type:0 = PI、1 = PID

■戻り値
 ありません。

 

■構文
 GetControlType()

■パラメータ
 ありません。

■戻り値
 コントロールの種類を返します。

 
イメージ 1 イメージ 3
励みになりますのでよければクリック下さい(^o^)/

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