Bonjour à tous,

Je vais vous expliquer mon problème, je dois réaliser la régulation d'un chauffage à l'aide d'un PID. J'utilise actuellement Lazarus pour mon projet sur demande de mon tuteur.
J'étais parti sur l'idee d'un timer mais cela ne plaisait pas trop à mon tuteur qui m'a conseillé d'utiliser la fonction ProcessMessages. J'utilise des modules d'entrées sorties analogiques et un module de sortie relais en RS485.

Le probleme c'est que je ne comprends pas bien la fonction processMessage, je suis allé me renseigner a pleins d'endroit sur le net et de partout je vois des gens qui critique l'utilisation de cette application. Je vous met à la suite mon code

Code:
unit main;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LazSerial, Forms, Controls, Graphics, Dialogs,
  StdCtrls, ExtCtrls, LazSynaSer, dateutils, Lclintf;

type

  { TForm1 }

  TForm1 = class(TForm)
    ButtonStop: TButton;
    ButtonStart: TButton;
    CheckBox1: TCheckBox;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    EditAdresse: TEdit;
    Editcmd: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    LEtat2: TLabel;
    LEtat: TLabel;
    LazSerial1: TLazSerial;
    Memo1: TMemo;
    Memo2: TMemo;
    Memo3: TMemo;
    Memo4: TMemo;
    Timer1: TTimer;
    procedure ButtonStopClick(Sender: TObject);
    procedure ButtonStartClick(Sender: TObject);
    procedure CheckBox1Change(Sender: TObject);
    procedure Edit4Change(Sender: TObject);
    procedure EditAdresseChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    Procedure CommandeADAM(adr:string; cmd:string; var reponse:string);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  TimeOut : boolean;
  str_retour :string;
  str_answer :string;
  integrale : real;
  ancienne_valeur: real;
  delta_Temp_pre:real;
  delta_Temp_pre2: real;
  com_pre : real;
  stopautomate : boolean;
  //ButtonQuitter : boolean;
  RAZ_Automate : boolean;
  x: real;
  z: real;
implementation

{$R *.lfm}

{ TForm1 }

Procedure TForm1.CommandeADAM( adr:string; cmd:string; var reponse:string);
var

  Atime, Btime: TDateTime;
  Etime: int64;    // temps écoulé
  chaine : string;

begin
  LazSerial1.WriteData( adr + cmd + CRLF);
  chaine :='';

  TimeOut:= False;
  Atime:= now;
  While not TimeOut do // On attend la reponse
     Begin
          ETime := MilliSecondsBetween (Now, Atime);
          TimeOut := LazSerial1.DataAvailable;
          if Etime >= 50 then TimeOut := True; // TimeOut
     end;

  if LazSerial1.DataAvailable then
  begin  // Reponse OK
      Btime:= now;
      TimeOut:= False;
      While not TimeOut do
       Begin
            chaine := chaine + LazSerial1.ReadData;
            ETime := MilliSecondsBetween (Now, Btime);
            if AnsiLastChar (chaine) = #13 then Timeout := True; // chaine complete
            if Etime >= 50 then TimeOut := True; // TimeOut
       end;
  end else chaine := 'error';
  reponse := chaine;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Temp : real ;   // température converti en reel
  e: integer; // vérification (code erreur) 0 = ok ; x = erreur au caractere x

  commande1: real;
  commande2: real;
  delta_Temp: real;
  kp : real;
  ki: real;
  kd : real;
  dT: real;
  derivee : real;// tout les var precedentes servent a calculer commande

  periode : longword;

  y: real;
  temps_haut:longword;
  temps_bas: longword;
  th:string;
  tb:string;

  timedown : boolean;

  debut: integer;
  fin: integer;



begin
debut:=GetTickCount ;

  CommandeADAM( EditAdresse.text, Editcmd.text, str_retour);
  Memo1.Lines.add ('Reçu:'  + str_retour +' - ' + IntToStr(Memo1.Lines.Count));
  delete(str_retour,1,1);   //supprimé le > qui est le premier caractère
  delete(str_retour,8,3);   // supprimé le 8 eme caractère
  Val (str_retour,Temp,e);   // convertir la chaine en reel

  delta_temp:= strtofloat(Edit4.text) - Temp ;  //calcul de l'erreur

  //  Méthode1:

kp:= 1;
ki:=0;
kd:=0;
dt:=1000;

  derivee:= (delta_Temp - ancienne_valeur) / dt;      //calcul de la derivee
  ancienne_valeur := delta_Temp;               // mise en memoire de ancienne valeur

  integrale += integrale + delta_Temp * dt ;          //calcul integrale

  commande1 := kp * delta_Temp + ki * integrale + kd * derivee; //calcul de la commande
  Memo4.Lines.add ( floattostr (commande1));

  periode :=2000; // durée d'une période

  x:= commande1 /10 * periode;
  z:= periode - x;



  fin:= GettickCount - debut;
  Memo3.Lines.add ('Tps du prog: ' + floattostr(fin)+ 'ms');
end;

procedure TForm1.ButtonStartClick(Sender: TObject);
var
  BeginTime : cardinal;
  TimeOut : boolean;
 
begin
    ButtonStop.Enabled := true;
    ButtonStart.Enabled := false;
    StopAutomate := True;
    RAZ_Automate := true;
    while (StopAutomate) do
        begin

          TimeOut := False;
          BeginTime := GetTickCount;
          Timer1Timer(owner);*

          while not TimeOut  do
              begin
                application.ProcessMessages;
                CommandeADAM (Edit1.text, Edit3.text,str_answer);
                TimeOut := (GetTickCount - BeginTime) > x;

              end;
               Memo2.lines.add ( 'fermee: '+ floattostr(x) + ' ms'); // 1s

          Timeout :=false;
          while not TimeOut  do
              begin
                application.ProcessMessages;
                CommandeADAM (Edit1.text, Edit2.text,str_answer);
                TimeOut := (GetTickCount - BeginTime) > z;
                
              end;
		Memo2.lines.add ( 'ouvert '+ floattostr(z) + ' ms');

    end;
    LEtat.Caption := 'Arrêt';
    LEtat2.Caption := 'Arrêt';
end;

procedure TForm1.ButtonStopClick(Sender: TObject);
begin
    StopAutomate := false;  // arret automate PC
    ButtonStart.Enabled := true;
    ButtonStop.Enabled := false;
    //ButtonQuitter.Enabled := True;
end;

procedure TForm1.CheckBox1Change(Sender: TObject);
begin
  Timer1.enabled := CheckBox1.Checked;
end;


procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
LazSerial1.close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  LazSerial1.Device:= 'COM4';
  LazSerial1.Open;
end;

end.
j'ai mis en gras italique la partie du code ou est situé mon problème. L'objectif c'est que au final mon PID me donne un valeur que je module afin qu'elle soit comprise entre 0 et 1 et que je demande a mon module de sortie relais de rester fermer x temps ( x etant la commande modulé* la duree d'une periode) et de s'ouvrir le reste du temps de la periode.

Si des zones d'ombres subsistent dites le moi j'essayerai d'éclairer tout cela

Cordialement,
Quentin