⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 PID控制演示
💻 PAS
字号:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, LMDCustomControl, LMDCustomPanel, LMDCustomBevelPanel,
  LMDBaseEdit, LMDCustomEdit, LMDCustomMaskEdit, LMDCustomExtSpinEdit,
  LMDExtSpinEdit, iThreadTimers, iScaleComponent, iSlider, iAnalogDisplay,
  iPipeJoint, iPipe, iPositionComponent, iTank, iComponent, iVCLComponent,
  iCustomComponent, iPanel, iPlotComponent, iPlot;

type
  TForm1 = class(TForm)
    iPanel1: TiPanel;
    iTank1: TiTank;
    iPipeIn1: TiPipe;
    iPipeIn2: TiPipe;
    iPipeJoint1: TiPipeJoint;
    iPipeOut1: TiPipe;
    iPipeJoint2: TiPipeJoint;
    iPipeOut2: TiPipe;
    iAnalogDisplayIn: TiAnalogDisplay;
    iAnalogDisplayOut: TiAnalogDisplay;
    iSliderTank: TiSlider;
    iSliderIn: TiSlider;
    iSliderOut: TiSlider;
    iAnalogDisplayTank: TiAnalogDisplay;
    iThreadTimers1: TiThreadTimers;
    LMDExtSpinEditP: TLMDExtSpinEdit;
    LMDExtSpinEditI: TLMDExtSpinEdit;
    LMDExtSpinEditD: TLMDExtSpinEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    EditError: TEdit;
    Label4: TLabel;
    iPlot1: TiPlot;
    iPlot2: TiPlot;
    procedure iSliderInPositionChange(Sender: TObject);
    procedure iSliderOutPositionChange(Sender: TObject);
    procedure iAnalogDisplayTankChange(Sender: TObject);
    procedure iThreadTimers1Timer1(Sender: TObject);
    procedure iSliderTankPositionChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure iThreadTimers1Timer2(Sender: TObject);
    procedure iThreadTimers1Timer3(Sender: TObject);
    procedure iThreadTimers1Timer4(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  ErrorValueSum, Ek, Ek_1, iSliderInTemp :Double;
  Kp, Ki, Kd :Double;
  i : integer;

implementation

{$R *.dfm}
//{$R windowsxp.res}


///////////////////////
//  入口阀开度调节   //
///////////////////////
procedure TForm1.iSliderInPositionChange(Sender: TObject);
begin
  iAnalogDisplayIn.Value := iSliderIn.Position;

  iPipeIn1.FlowOn := not (iSliderIn.Position=0);
  iPipeIn2.FlowOn := iPipeIn1.FlowOn;

  if iAnalogDisplayIn.Value=100 then
    iPipeIn1.FlowInterval := 1
  else
    iPipeIn1.FlowInterval := 100-Round(iSliderIn.Position);

  iPipeIn2.FlowInterval := iPipeIn1.FlowInterval;
end;

///////////////////////
//  出口阀开度调节   //
///////////////////////
procedure TForm1.iSliderOutPositionChange(Sender: TObject);
begin
  iAnalogDisplayOut.Value := iSliderOut.Position;

  iPipeOut1.FlowOn := not (iSliderOut.Position=0);
  iPipeOut2.FlowOn := iPipeOut1.FlowOn;

  if iSliderOut.Position=100 then
    iPipeOut1.FlowInterval := 1
  else
    iPipeOut1.FlowInterval := 100-Round(iSliderOut.Position);

  iPipeOut2.FlowInterval := iPipeOut1.FlowInterval;
end;

procedure TForm1.iAnalogDisplayTankChange(Sender: TObject);
begin
  iTank1.Position := iAnalogDisplayTank.Value;
end;

// PID 调节
procedure TForm1.iThreadTimers1Timer1(Sender: TObject);
begin

  Kp := StrToFloat(LMDExtSpinEditP.Text); // 比例放大系数
  Ki := Kp*0.001/StrToFloat(LMDExtSpinEditI.Text); //积分放大系数 = 比例放大系数*采样周期 / 积分时间;
                                                  // ”采样周期“见 iThreadTimers1.Interval2/1000
  Kd := Kp*StrToFloat(LMDExtSpinEditD.Text)/0.001; // 微分放大系数 = 比例放大系数*微分时间 / 采样周期

  Ek_1{Error(k-1)} := Ek{Error(k)};
  Ek := iSliderTank.Position - iAnalogDisplayTank.Value;// 误差量
  ErrorValueSum := ErrorValueSum + Ek; // 积分,误差量合计

  EditError.Text := FormatFloat('0.00',iSliderTank.Position - iAnalogDisplayTank.Value);

  {实际调节见iThreadTimers1Timer3(Sender: TObject) 函数,每秒调节一格}
  iSliderInTemp{调节量} := Kp*Ek + Ki*ErrorValueSum{积分} + Kd*(Ek-Ek_1){Ek-Ek_1:微分}; // PID 计算公式
end;

procedure TForm1.iSliderTankPositionChange(Sender: TObject);
begin
  iSliderTank.Hint := '水箱水位设定值:'+FormatFloat('0.00',iSliderTank.Position);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ErrorValueSum := 0;
  Ek := 0;  {Error(k)}
  Ek_1 := 0;  {Error(k-1)}
  iSliderInTemp := 0;
end;

//
procedure TForm1.iThreadTimers1Timer2(Sender: TObject);
begin
  // 水位调节
  iAnalogDisplayTank.Value := iAnalogDisplayTank.Value
                              - (iSliderOut.Position
                              - iSliderIn.Position)/1000;
end;

procedure TForm1.iThreadTimers1Timer3(Sender: TObject);
begin  //阀门调节延时
  if iSliderInTemp>iSliderIn.Position then
    iSliderIn.Position := iSliderIn.Position + 1;
  if iSliderInTemp<iSliderIn.Position then
    iSliderIn.Position := iSliderIn.Position - 1;
end;

procedure TForm1.iThreadTimers1Timer4(Sender: TObject);
begin  // 画曲线图
  iPlot1.Channel[0].AddXY(i,StrToFloat(EditError.Text));
  iPlot1.Channel[1].AddXY(i,0);
  iPlot2.Channel[0].AddXY(i,iAnalogDisplayTank.Value);
  iPlot2.Channel[1].AddXY(i,iSliderTank.Position);
  Inc(i);
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -