📄 unit1.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 + -