unit Uexec; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, ExtCtrls, UDessin, UDessinComposant,UFonctions, UInit,UEdit,UPage; procedure SourisBas; procedure SourisHaut; procedure InitExec; procedure CycleExec; procedure Temporisations; implementation uses Unit1,UTest; procedure SourisBas; var i,f,j:integer; begin RAZSelection; SelectionComposants; if CompteurComposant('C')=1 then for i:=0 to Nb_Contact-1 do if (L_Contact[i].Select and L_Contact[i].Manuel) then begin f:=L_Contact[i].Fonction; // Contacts : les poussoirs (11,12,13 et 14) sont à l'état repos, les autres deviennet complémentaires if (L_Contact[i].modele='11') or (L_Contact[i].modele='12') or (L_Contact[i].modele='13') or (L_Contact[i].modele='14') then L_Fonction[f].EtatP:=false else L_Fonction[f].EtatP:=not L_Fonction[f].EtatP; for j:=0 to Nb_Contact-1 do if (L_Contact[j].Fonction=f) then begin L_Contact[j].EtatP:=L_Fonction[f].EtatP; L_Fonction[f].EtatF:=L_Fonction[f].EtatP; end; end; CycleExec; end; procedure SourisHaut; var i,f,j:integer; begin RAZSelection; SelectionComposants; if CompteurComposant('C')=1 then for i:=0 to Nb_Contact-1 do if (L_Contact[i].Select and L_Contact[i].Manuel) then begin f:=L_Contact[i].Fonction; // Contacts : seuls les poussoirs (11,12,13 et 14) reviennent à l'état travail if (L_Contact[i].modele='11') or (L_Contact[i].modele='12') or (L_Contact[i].modele='13') or (L_Contact[i].modele='14') then L_Fonction[f].EtatP:=true; for j:=0 to Nb_Contact-1 do if (L_Contact[j].Fonction=f) then begin L_Contact[j].EtatP:=L_Fonction[f].EtatP; L_Fonction[f].EtatF:=L_Fonction[f].EtatP; end; end; CycleExec; end; procedure InitExec; var i,j:integer; ps:TPoint; b:boolean; s:string; // Cherche le composant et la connexion associée au point ps (extrémité d'un segment) procedure cherchecx; var j,k,g:integer; begin b:=true; for j:=0 to Nb_Alim-1 do if (L_Alim[j].P.X=ps.X) and (L_Alim[j].P.Y=ps.Y) then begin s:='A'+IntToStr(j); b:=false; end; // Alim if b then for j:=0 to Nb_Connect-1 do if (L_Connect[j].P.X=ps.X) and (L_Connect[j].P.Y=ps.Y) then begin s:='X'+IntToStr(j); b:=false; end; // Connect if b then for j:=0 to Nb_Contact-1 do begin g:=StrToInt(L_Contact[j].modele); for k:=0 to length(L_ContactX[g])-1 do begin if (L_Contact[j].P.X+L_ContactX[g,k].X=ps.X) and (L_Contact[j].P.Y+L_ContactX[g,k].Y=ps.Y) then begin s:='C'+IntToStr(j)+'§'+IntToStr(k); b:=false; end; end; end; // Contact if b then for j:=0 to Nb_Relais-1 do begin g:=StrToInt(L_Relais[j].modele); for k:=0 to length(L_RelaisX[g])-1 do begin if (L_Relais[j].P.X+L_RelaisX[g,k].X=ps.X) and (L_Relais[j].P.Y+L_RelaisX[g,k].Y=ps.Y) then begin s:='R'+IntToStr(j)+'§'+IntToStr(k); b:=false; end; end; end; // Relais if b then for j:=0 to Nb_Lampe-1 do begin g:=StrToInt(L_Lampe[j].modele); for k:=0 to length(L_LampeX[g])-1 do begin if (L_Lampe[j].P.X+L_LampeX[g,k].X=ps.X) and (L_Lampe[j].P.Y+L_LampeX[g,k].Y=ps.Y) then begin s:='L'+IntToStr(j)+'§'+IntToStr(k); b:=false; end; end; end; // Lampe if b then for j:=0 to Nb_Compo-1 do begin g:=StrToInt(L_Compo[j].modele); for k:=0 to length(L_CompoX[g])-1 do begin if (L_Compo[j].P.X+L_CompoX[g,k].X=ps.X) and (L_Compo[j].P.Y+L_CompoX[g,k].Y=ps.Y) then begin s:='P'+IntToStr(j)+'§'+IntToStr(k); b:=false; end; end; end; // Compo if b then for j:=0 to Nb_Segment-1 do if (j<>i) then begin if (L_Segment[j].P1.X=ps.X) and (L_Segment[j].P1.Y=ps.Y) or (L_Segment[j].P2.X=ps.X) and (L_Segment[j].P2.Y=ps.Y) then begin s:='S'+IntToStr(j); end; end; // un autre Segment end; // cherchecx // Fonction récursive affectant l'appartenance à un potentiel des branches procedure cherchebr(s:string); var i:integer; begin for i:=0 to Nb_Branche-1 do begin if (L_Branche[i].AppaPotentiel=-1) then begin if L_Branche[i].Cote1=s then begin L_Branche[i].AppaPotentiel:=Nb_Potentiel; Cherchebr(L_Branche[i].Cote2); end; if L_Branche[i].Cote2=s then begin L_Branche[i].AppaPotentiel:=Nb_Potentiel; Cherchebr(L_Branche[i].Cote1); end; end; end; end; // cherchebr // Fonction récursive affectant l'appartenance à une branche d'un segment i procedure cherchesg(i:integer); var j:integer; begin L_Segment[i].AppaBranche:=Nb_Branche; // s'il y a un autre segement du côté 1 if pos('S',L_Segment[i].Cote1)>0 then begin j:=StrToInt(copy(L_Segment[i].Cote1,2,4)); if L_Segment[j].AppaBranche=-1 then cherchesg(j); end; // s'il y a un autre segement du côté 2 if pos('S',L_Segment[i].Cote2)>0 then begin j:=StrToInt(copy(L_Segment[i].Cote2,2,4)); if L_Segment[j].AppaBranche=-1 then cherchesg(j); end; end; // cherchesg begin // InitExec gtc:=gettickcount(); // contact manuel au repos sauf poussoirs for i:=0 to Nb_Contact-1 do if L_Contact[i].Manuel then begin L_Contact[i].EtatP:=false; if (L_Contact[i].modele='11') or (L_Contact[i].modele='12') or (L_Contact[i].modele='13') or (L_Contact[i].modele='14') then L_Contact[i].EtatP:=true; end; // cherche les cotés des segments : remplit cote1 et cote2 for i:=0 to Nb_Segment-1 do begin s:=''; L_Segment[i].Cote1:=''; // Raz des côtés 1 des segments ps:=L_Segment[i].P1; cherchecx; L_Segment[i].Cote1:=s; s:=''; L_Segment[i].Cote2:=''; // Raz des côtés 2 des segments ps:=L_Segment[i].P2; cherchecx; L_Segment[i].Cote2:=s; end; // * Cherche les branches * Nb_branche:=0; Setlength(L_Branche,Nb_Branche); for i:=0 to Nb_Segment-1 do L_Segment[i].AppaBranche:=-1; // Raz de l'appartenance à une branche de tous les segments // Détermine le nombre de branches for i:=0 to Nb_Segment-1 do begin if (L_Segment[i].AppaBranche=-1) then begin cherchesg(i); inc(Nb_branche); end; end; //for i Setlength(L_Branche,Nb_Branche); // RAZ des côtés des branches for i:=0 to Nb_Branche-1 do begin L_Branche[i].Cote1:=''; L_Branche[i].Cote2:=''; end; // affecte la liste des segments de la branche et le composant et la connexion associés aux extrémités de la branche for i:=0 to Nb_Segment-1 do begin // liste des segments SetLength(L_Branche[L_Segment[i].AppaBranche].CompSegments, length(L_Branche[L_Segment[i].AppaBranche].CompSegments)+1); L_Branche[L_Segment[i].AppaBranche].CompSegments[length(L_Branche[L_Segment[i].AppaBranche].CompSegments)-1]:=i; //composant et connexion associés if ((L_Segment[i].Cote1+' ')[1]<>'S') then if (L_Branche[L_Segment[i].AppaBranche].Cote1='') then L_Branche[L_Segment[i].AppaBranche].Cote1:=L_Segment[i].Cote1 else L_Branche[L_Segment[i].AppaBranche].Cote2:=L_Segment[i].Cote1; if ((L_Segment[i].Cote2+' ')[1]<>'S') then if (L_Branche[L_Segment[i].AppaBranche].Cote1='') then L_Branche[L_Segment[i].AppaBranche].Cote1:=L_Segment[i].Cote2 else L_Branche[L_Segment[i].AppaBranche].Cote2:=L_Segment[i].Cote2; end; // * Cherche les potentiels * Nb_potentiel:=0; Setlength(L_Potentiel,Nb_Potentiel); for i:=0 to Nb_Branche-1 do L_Branche[i].AppaPotentiel:=-1; // Raz de l'appartenance à un potentiel de toutes les branches //Détermine le nombre de potentiels for i:=0 to Nb_Branche-1 do begin if (L_Branche[i].AppaPotentiel=-1) then begin L_Branche[i].AppaPotentiel:=Nb_Potentiel; Cherchebr(L_Branche[i].Cote1); Cherchebr(L_Branche[i].Cote2); inc(Nb_potentiel); end; end; // affecte la liste des branches associées aux potentiels Setlength(L_Potentiel,Nb_Potentiel); for i:=0 to Nb_Branche-1 do begin SetLength(L_Potentiel[L_Branche[i].AppaPotentiel].CompBranches, length(L_Potentiel[L_Branche[i].AppaPotentiel].CompBranches)+1); L_Potentiel[L_Branche[i].AppaPotentiel].CompBranches[length(L_Potentiel[L_Branche[i].AppaPotentiel].CompBranches)-1]:=i; end; // * Cherche les fonctions * for i:=0 to Nb_Relais-1 do L_Relais[i].Fonction:=-1; Nb_Fonction:=0; SetLength(L_Fonction,0); for i:=0 to Nb_Relais-1 do begin SetLength(L_Fonction,Nb_Fonction+1); L_Fonction[Nb_Fonction].comp:='R'+IntToStr(i); L_Fonction[Nb_Fonction].nom:=L_Relais[i].nom; L_Fonction[Nb_Fonction].x:=L_Relais[i].P.X; L_Relais[i].Fonction:=Nb_Fonction; inc(Nb_Fonction); end; // à modifier si deux manuels possibles avec si le nom existe déjà for i:=0 to Nb_Contact-1 do begin L_Contact[i].Fonction:=-1; if L_Contact[i].Manuel then begin SetLength(L_Fonction,Nb_Fonction+1); L_Fonction[Nb_Fonction].comp:='C'+IntToStr(i); L_Fonction[Nb_Fonction].nom:=L_Contact[i].nom; L_Fonction[Nb_Fonction].x:=L_Contact[i].P.X; L_Contact[i].Fonction:=Nb_Fonction; inc(Nb_Fonction); end; end; // affecte au reste des contacts leurs fonctions for i:=0 to Nb_Contact-1 do begin // pas de nom if (L_Contact[i].Fonction=-1) and (L_Contact[i].nom='') then for j:=0 to Nb_Fonction-1 do if L_Contact[i].P.X=L_Fonction[j].x then L_Contact[i].Fonction:=j; // pas de fonction mais un nom : vérifie le même nom if (L_Contact[i].Fonction=-1) and (L_Contact[i].nom<>'') then for j:=0 to Nb_Fonction-1 do if L_Contact[i].nom=L_Fonction[j].nom then L_Contact[i].Fonction:=j; end; // affecte les potentiels aux bornes des relais for i:=0 to Nb_Relais-1 do for j:=0 to 3 do L_Relais[i].AppPot[j]:=-1; for i:=0 to Nb_Branche-1 do begin s:=L_Branche[i].Cote1; if s[1]='R' then L_Relais[StrToInt(copy(s,2,pos('§',s)-2))].AppPot[StrToInt(copy(s,pos('§',s)+1,3))]:=L_Branche[i].AppaPotentiel; s:=L_Branche[i].Cote2; if s[1]='R' then L_Relais[StrToInt(copy(s,2,pos('§',s)-2))].AppPot[StrToInt(copy(s,pos('§',s)+1,3))]:=L_Branche[i].AppaPotentiel; end; // affecte les potentiels aux bornes des lampes for i:=0 to Nb_Lampe-1 do for j:=0 to 3 do L_Lampe[i].AppPot[j]:=-1; for i:=0 to Nb_Branche-1 do begin s:=L_Branche[i].Cote1; if s[1]='L' then L_Lampe[StrToInt(copy(s,2,pos('§',s)-2))].AppPot[StrToInt(copy(s,pos('§',s)+1,3))]:=L_Branche[i].AppaPotentiel; s:=L_Branche[i].Cote2; if s[1]='L' then L_Lampe[StrToInt(copy(s,2,pos('§',s)-2))].AppPot[StrToInt(copy(s,pos('§',s)+1,3))]:=L_Branche[i].AppaPotentiel; end; // affecte les potentiels aux bornes des compo for i:=0 to Nb_Compo-1 do for j:=0 to 3 do L_Compo[i].AppPot[j]:=-1; for i:=0 to Nb_Branche-1 do begin s:=L_Branche[i].Cote1; if s[1]='P' then L_Compo[StrToInt(copy(s,2,pos('§',s)-2))].AppPot[StrToInt(copy(s,pos('§',s)+1,3))]:=L_Branche[i].AppaPotentiel; s:=L_Branche[i].Cote2; if s[1]='P' then L_Compo[StrToInt(copy(s,2,pos('§',s)-2))].AppPot[StrToInt(copy(s,pos('§',s)+1,3))]:=L_Branche[i].AppaPotentiel; end; // affecte le potentiel aux connections; for i:=0 to Nb_Connect-1 do begin for j:=0 to Nb_Branche-1 do begin if (L_Branche[j].Cote1='X'+IntToStr(i)) or (L_Branche[j].Cote2='X'+IntToStr(i)) then L_Connect[i].AppaPotentiel:=L_Branche[j].AppaPotentiel; end; end; // positionnement des contacts initiaux for j:=0 to Nb_Contact-1 do for i:=0 to Nb_Fonction-1 do if (L_Contact[j].Fonction=i) then begin L_Fonction[i].EtatP:=L_Contact[j].EtatI; L_Fonction[i].EtatF:=L_Fonction[i].EtatP; end; for j:=0 to Nb_Contact-1 do if L_Contact[j].Fonction>-1 then L_Contact[j].EtatP:= L_Fonction[L_Contact[j].Fonction].EtatP; // lance les cycles // test('fin init'); // form1.memo1.lines.add('fin init '+IntToStr(gettickcount-gtc)); //gtc:=gettickcount(); CycleExec; end; // InitExec procedure CycleExec; var i,j,k:integer; EtatF1,EtatF2:string; btempo:boolean; bc1:boolean; sa,so:string; l,m:integer; cb1,cb2:integer; // * * * procedure PBoucle (s1:string;b:boolean); forward; procedure PBoucle2 (s1:string;b:boolean); var g:integer; sa,so:string; bc:boolean; sg2:integer; begin sa:=copy(s1,pos('§',s1)+1,1); so:=copy(s1,1,pos('§',s1)); sg2:=StrToInt('0'+copy(s1,2,pos('§',s1)-2)); if s1[1]='C' then for g:=0 to Nb_Contact-1 do begin if g=sg2 then begin // pour le contact concerné bc:= L_Fonction[L_Contact[g].Fonction].EtatP; // travail if (L_Contact[g].modele='1') or (L_Contact[g].modele='2') or (L_Contact[g].modele='13') or (L_Contact[g].modele='14') or (L_Contact[g].modele='10') or (L_Contact[g].modele='16') or (L_Contact[g].modele='17') then begin if bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; PBoucle(so,b); end; end; // c 1 2 13 14 10 // repos if (L_Contact[g].modele='3') or (L_Contact[g].modele='4') or (L_Contact[g].modele='11') or (L_Contact[g].modele='12') or (L_Contact[g].modele='15') then begin if not bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; PBoucle(so,b); end; end; // 3 4 11 12 // travail / repos if (L_Contact[g].modele='5') or (L_Contact[g].modele='6') then begin if bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; if (sa='0') or (sa='1') then PBoucle(so,b); end; if not bc then begin if sa='0' then so:=so+'2'; if sa='2' then so:=so+'0'; if (sa='0') or (sa='2') then PBoucle(so,b); end; end; // end; // if g=StrToInt(copy(s1,2,pos('§',s1)-2)) end; // for g Contact end; procedure PBoucle (s1:string;b:boolean); var l,app:integer; b1:boolean; begin app:=-1; for l:=0 to Nb_Branche-1 do if (L_Branche[l].Cote1=S1) or (L_Branche[l].Cote2=S1) then app:=L_Branche[l].AppaPotentiel; if app>-1 then begin b1:=true; if b and (L_Potentiel[app].PRp=0) then b1:=false; if not b and (L_Potentiel[app].PRm=0) then b1:=false; if b1 then begin if b then L_Potentiel[app].PRp:=0 else L_Potentiel[app].PRm:=0; for l:=0 to Nb_Branche-1 do if L_Branche[l].AppaPotentiel=app then begin if (L_Branche[l].Cote1<>S1) and (L_Branche[l].Cote1[1]<>'A') and (L_Branche[l].Cote1[1]<>'X') then PBoucle2(L_Branche[l].Cote1,b); if (L_Branche[l].Cote2<>S1) and (L_Branche[l].Cote2[1]<>'A') and (L_Branche[l].Cote2[1]<>'X') then PBoucle2(L_Branche[l].Cote2,b); end; // for l end; // if b1 end; // if app>-1 end; // procedure PBoucle // * * * procedure Boucle (s1:string;i2:integer;b:boolean); forward; procedure Boucle2 (s1:string;i2:integer;b:boolean); var app,l,g:integer; sa,so:string; bc,b1:boolean; sg2:integer; begin sa:=copy(s1,pos('§',s1)+1,1); so:=copy(s1,1,pos('§',s1)); sg2:=StrToInt('0'+copy(s1,2,pos('§',s1)-2)); if s1[1]='C' then for g:=0 to Nb_Contact-1 do begin if g=sg2 then begin // pour le contact concerné bc:= L_Fonction[L_Contact[g].Fonction].EtatP; // travail if (L_Contact[g].modele='1') or (L_Contact[g].modele='2') or (L_Contact[g].modele='13') or (L_Contact[g].modele='14') or (L_Contact[g].modele='10') or (L_Contact[g].modele='7') or (L_Contact[g].modele='16') or (L_Contact[g].modele='17') then begin if bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; app:=-1; // antiboucle for l:=0 to Nb_Branche-1 do if (L_Branche[l].Cote1=so) or (L_Branche[l].Cote2=so) then app:=L_Branche[l].AppaPotentiel; b1:=true; if b and (L_Potentiel[app].Rp=i2) then b1:=false; if not b and (L_Potentiel[app].Rm=i2) then b1:=false; if b1 then boucle(so,i2,b); end; end; // c 1 2 13 14 10 // repos if (L_Contact[g].modele='3') or (L_Contact[g].modele='4') or (L_Contact[g].modele='11') or (L_Contact[g].modele='12') or (L_Contact[g].modele='15') or (L_Contact[g].modele='8') then begin if not bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; app:=-1; // antiboucle for l:=0 to Nb_Branche-1 do if (L_Branche[l].Cote1=so) or (L_Branche[l].Cote2=so) then app:=L_Branche[l].AppaPotentiel; b1:=true; if b and (L_Potentiel[app].Rp=i2) then b1:=false; if not b and (L_Potentiel[app].Rm=i2) then b1:=false; if b1 then boucle(so,i2,b); end; end; // 3 4 11 12 // travail / repos if (L_Contact[g].modele='5') or (L_Contact[g].modele='6') or (L_Contact[g].modele='9') then begin if bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; if (sa='0') or (sa='1') then begin app:=-1; // antiboucle for l:=0 to Nb_Branche-1 do if (L_Branche[l].Cote1=so) or (L_Branche[l].Cote2=so) then app:=L_Branche[l].AppaPotentiel; b1:=true; if b and (L_Potentiel[app].Rp=i2) then b1:=false; if not b and (L_Potentiel[app].Rm=i2) then b1:=false; if b1 then boucle(so,i2,b); end; end; if not bc then begin if sa='0' then so:=so+'2'; if sa='2' then so:=so+'0'; if (sa='0') or (sa='2') then begin app:=-1;// antiboucle for l:=0 to Nb_Branche-1 do if (L_Branche[l].Cote1=so) or (L_Branche[l].Cote2=so) then app:=L_Branche[l].AppaPotentiel; b1:=true; if b and (L_Potentiel[app].Rp=i2) then b1:=false; if not b and (L_Potentiel[app].Rm=i2) then b1:=false; if b1 then boucle(so,i2,b); end; end; end; // c 5 6 9 end; // if g=StrToInt(copy(s1,2,pos('§',s1)-2)) end; // for g Contact if s1[1]='R' then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; if sa='2' then so:=so+'3'; if sa='3' then so:=so+'2'; boucle(so,i2+1,b); end; // for g Relais if s1[1]='L' then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; boucle(so,i2+1,b); end; // for g Lampe if s1[1]='P' then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; boucle(so,i2+1,b); end; // for g Compo end; procedure Boucle (s1:string;i2:integer;b:boolean); var l,app:integer; b1:boolean; begin app:=-1; for l:=0 to Nb_Branche-1 do if (L_Branche[l].Cote1=S1) or (L_Branche[l].Cote2=S1) then app:=L_Branche[l].AppaPotentiel; if app>-1 then begin b1:=true; if b and ((L_Potentiel[app].RpS1) and (L_Branche[l].Cote1[1]<>'A') and (L_Branche[l].Cote1[1]<>'X') then Boucle2(L_Branche[l].Cote1,i2,b); if (L_Branche[l].Cote2<>S1) and (L_Branche[l].Cote2[1]<>'A') and (L_Branche[l].Cote2[1]<>'X') then Boucle2(L_Branche[l].Cote2,i2,b); end; // for l end; // if b1 end; // if app>-1 end; // procedure Boucle // relais bobine simple function CalculPotentiel2(p1,p2:integer):boolean; var i1p,i1m,i2p,i2m:integer; begin i1p:=L_Potentiel[p1].Rp; i1m:=abs(L_Potentiel[p1].Rm); i2p:=L_Potentiel[p2].Rp; i2m:=abs(L_Potentiel[p2].Rm); // test(i1p+i1m); result:=(ABS(i1p/(i1p+i1m)-i2p/(i2p+i2m))>(1/rmax)) and (((i1p+i1m+i2p+i2m)>=rmax) or (ABS((i1p+i1m)-(i2p+i2m))<=1)); end; // relais basculeur function CalculPotentielBASC(bq:boolean;p1,p2,p3,p4:integer):boolean; var i1p,i1m,i2p,i2m,i3p,i3m,i4p,i4m:integer; br,bs:boolean; begin i1p:=L_Potentiel[p1].Rp; i1m:=abs(L_Potentiel[p1].Rm); i2p:=L_Potentiel[p2].Rp; i2m:=abs(L_Potentiel[p2].Rm); i3p:=L_Potentiel[p3].Rp; i3m:=abs(L_Potentiel[p3].Rm); i4p:=L_Potentiel[p4].Rp; i4m:=abs(L_Potentiel[p4].Rm); br:=(ABS(i1p/(i1p+i1m)-i2p/(i2p+i2m))>(1/rmax)) and (((i1p+i1m+i2p+i2m)>=rmax) or (ABS((i1p+i1m)-(i2p+i2m))<=1)); bs:=(ABS(i3p/(i3p+i3m)-i4p/(i4p+i4m))>(1/rmax)) and (((i3p+i3m+i4p+i4m)>=rmax) or (ABS((i3p+i3m)-(i4p+i4m))<=1)); result:=(not(br) and bs) or (bq and not(br)) or (bq and bs); end; // relais temporisé function CalculPotentielTA(p1,p2:integer):boolean; var i1p,i1m,i2p,i2m:integer; begin i1p:=L_Potentiel[p1].Rp; i1m:=abs(L_Potentiel[p1].Rm); i2p:=L_Potentiel[p2].Rp; i2m:=abs(L_Potentiel[p2].Rm); result:=(ABS(i1p/(i1p+i1m)-i2p/(i2p+i2m))>(1/rmax)) and (((i1p+i1m+i2p+i2m)>=rmax) or (ABS((i1p+i1m)-(i2p+i2m))<=1)); end; // relais attraction maintien function CalculPotentielAM(bq:boolean;p1,p2,p3,p4:integer):boolean; var i1p,i1m,i2p,i2m,i3p,i3m,i4p,i4m:integer; br,bs:boolean; begin i1p:=L_Potentiel[p1].Rp; i1m:=abs(L_Potentiel[p1].Rm); i2p:=L_Potentiel[p2].Rp; i2m:=abs(L_Potentiel[p2].Rm); i3p:=L_Potentiel[p3].Rp; i3m:=abs(L_Potentiel[p3].Rm); i4p:=L_Potentiel[p4].Rp; i4m:=abs(L_Potentiel[p4].Rm); br:=(ABS(i1p/(i1p+i1m)-i2p/(i2p+i2m))>(1/rmax)) and (((i1p+i1m+i2p+i2m)>=rmax) or (ABS((i1p+i1m)-(i2p+i2m))<=1)); bs:=(ABS(i3p/(i3p+i3m)-i4p/(i4p+i4m))>(1/rmax)) and (((i3p+i3m+i4p+i4m)>=rmax) or (ABS((i3p+i3m)-(i4p+i4m))<=1)); result:=br or bs and bq; end; // relais flux additif function CalculPotentielFA(p1,p2,p3,p4:integer):boolean; var i1p,i1m,i2p,i2m,i3p,i3m,i4p,i4m:integer; br,bs,bq:boolean; begin i1p:=L_Potentiel[p1].Rp; i1m:=abs(L_Potentiel[p1].Rm); i2p:=L_Potentiel[p2].Rp; i2m:=abs(L_Potentiel[p2].Rm); i3p:=L_Potentiel[p3].Rp; i3m:=abs(L_Potentiel[p3].Rm); i4p:=L_Potentiel[p4].Rp; i4m:=abs(L_Potentiel[p4].Rm); bq:=(i1p/(i1p+i1m)>i2p/(i2p+i2m))and(i3p/(i3p+i3m)>i4p/(i4p+i4m)) or (i1p/(i1p+i1m)(1/rmax)) and (((i1p+i1m+i2p+i2m)>=rmax) or (ABS((i1p+i1m)-(i2p+i2m))<=1)); bs:=(ABS(i3p/(i3p+i3m)-i4p/(i4p+i4m))>(1/rmax)) and (((i3p+i3m+i4p+i4m)>=rmax) or (ABS((i3p+i3m)-(i4p+i4m))<=1)); result:=br and bs and bq; end; function ResteBrancheNul:boolean; var i,j,cc :integer; b:boolean; begin b:=false; for i:=0 to Nb_Connect-1 do begin cc:=0; for j:=0 to Nb_Branche-1 do begin // branche if (L_Branche[j].Cote1='X'+IntToStr(i)) or (L_Branche[j].Cote2='X'+IntToStr(i)) then if L_Branche[j].Courant=-1 then inc(cc); end; // for j:=0 to Nb_Branche-1 b:=b or (cc=1); end; // for i:=0 to Nb_Connect-1 result:=b; end; procedure CNulBoucle (s1:string); var l,g:integer; b0,b1,bc:boolean; s,s2,sa,so:string; sg2:integer; begin for l:=0 to Nb_Branche-1 do begin s2:=''; if (L_Branche[l].Cote1=S1) then begin S2:=L_Branche[l].Cote2; L_Branche[l].Courant:=0; end; if (L_Branche[l].Cote2=S1) then begin S2:=L_Branche[l].Cote1; L_Branche[l].Courant:=0; end; if S2<>'' then begin sa:=copy(s2,pos('§',s2)+1,1); so:=copy(s2,1,pos('§',s2)); sg2:=StrToInt('0'+copy(s2,2,pos('§',s2)-2)); if s2[1]='C' then for g:=0 to Nb_Contact-1 do begin // contact if g=sg2 then begin // contact concerné bc:= L_Fonction[L_Contact[g].Fonction].EtatP; // travail c 1 2 13 14 10 7 if (L_Contact[g].modele='1') or (L_Contact[g].modele='2') or (L_Contact[g].modele='13') or (L_Contact[g].modele='14') or (L_Contact[g].modele='10') or (L_Contact[g].modele='7') or (L_Contact[g].modele='16') or (L_Contact[g].modele='17') then begin if bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; CNulBoucle(so); end; end;// travail c 1 2 13 14 10 7 // repos c 3 4 11 12 15 8 if (L_Contact[g].modele='3') or (L_Contact[g].modele='4') or (L_Contact[g].modele='11') or (L_Contact[g].modele='12') or (L_Contact[g].modele='15') or (L_Contact[g].modele='8') then begin if not bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; CNulBoucle(so); end; end; // repos c 3 4 11 12 15 8 // travail / repos c 5 6 9 if (L_Contact[g].modele='5') or (L_Contact[g].modele='6') or (L_Contact[g].modele='9') then begin if bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; if (sa='0') or (sa='1') then CNulBoucle(so); end; if not bc then begin if sa='0' then so:=so+'2'; if sa='2' then so:=so+'0'; if (sa='0') or (sa='2') then CNulBoucle(so); end; end; // travail / repos c 5 6 9 end; // contact concerné end; //for g Contanct if s2[1]='R' then begin //for g:=0 to Nb_Relais-1 do begin // Relais if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; if sa='2' then so:=so+'3'; if sa='3' then so:=so+'2'; CNulBoucle(so); end; // for g Relais if S2[1]='L' then begin //for g:=0 to Nb_Lampe-1 do begin // Lampe if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; CNulBoucle(so); end; // for g Lampe if S2[1]='P' then begin //for g:=0 to Nb_Compo-1 do begin // Composant if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; CNulBoucle(so); end; // for g Compo end; // if S2<>'' end; // l:=0 to Nb_Branche-1 end; // procedure CNulBoucle (s1:string); // * procedure CBoucle (s1:string;b:boolean;st:string); var app,l,g,h:integer; sa,so,s2,sk:string; bc,b1,dp:boolean; cote:integer; sg2:integer; begin for l:=0 to Nb_Branche-1 do begin s2:=''; if (L_Branche[l].Cote1=S1) then begin S2:=L_Branche[l].Cote2; cote:=1; end; if (L_Branche[l].Cote2=S1) then begin S2:=L_Branche[l].Cote1; cote:=2; end; // déjà parcouru dp:=true; sk:=st; while length(sk)>=1 do begin dp:=dp and not (StrToInt(copy(sk,1,pos('µ',sk)-1))=l); sk:=copy(sk,pos('µ',sk)+1,length(sk)); end; if (S2<>'') and dp and (L_Branche[l].Courant<>0) then begin L_Branche[l].Parcouru:=1; if (S2+' ')[1]='X' then CBoucle(S2,b,st+inttostr(l)+'µ'); if S2[1]='A' then begin sg2:=StrToInt('0'+copy(S2,2,length(S2))); for g:=0 to Nb_Alim-1 do if g=sg2 then begin if (b and (L_Alim[g].modele='2')) or (not b and (L_Alim[g].modele='1')) or (not b and (L_Alim[g].modele='3') and pulse) then begin sk:=st+inttostr(l)+'µ'; while length(sk)>=1 do begin L_Branche[StrToInt(copy(sk,1,pos('µ',sk)-1))].Courant:=1; // met le courant à 1 sk:=copy(sk,pos('µ',sk)+1,length(sk)); end; end; end; end; sa:=copy(S2,pos('§',S2)+1,1); so:=copy(S2,1,pos('§',S2)); sg2:=StrToInt('0'+copy(S2,2,pos('§',S2)-2)); if s2[1]='C' then for g:=0 to Nb_Contact-1 do begin if g=sg2 then begin // pour le contact concerné bc:= L_Fonction[L_Contact[g].Fonction].EtatP; // travail if (L_Contact[g].modele='1') or (L_Contact[g].modele='2') or (L_Contact[g].modele='13') or (L_Contact[g].modele='14') or (L_Contact[g].modele='10') or (L_Contact[g].modele='7') or (L_Contact[g].modele='16') or (L_Contact[g].modele='17') then begin if bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; CBoucle(so,b,st+inttostr(l)+'µ'); end; end; // c 1 2 13 14 10 // repos if (L_Contact[g].modele='3') or (L_Contact[g].modele='4') or (L_Contact[g].modele='11') or (L_Contact[g].modele='12') or (L_Contact[g].modele='15') or (L_Contact[g].modele='8') then begin if not bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; CBoucle(so,b,st+inttostr(l)+'µ'); end; end; // 3 4 11 12 // travail / repos if (L_Contact[g].modele='5') or (L_Contact[g].modele='6') or (L_Contact[g].modele='9') then begin if bc then begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; if (sa='0') or (sa='1') then CBoucle(so,b,st+inttostr(l)+'µ'); end; if not bc then begin if sa='0' then so:=so+'2'; if sa='2' then so:=so+'0'; if (sa='0') or (sa='2') then CBoucle(so,b,st+inttostr(l)+'µ'); end; end; // c 5 6 9 end; // if g end; // contact} if s2[1]='R' then begin //for g:=0 to Nb_Relais-1 do begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; if sa='2' then so:=so+'3'; if sa='3' then so:=so+'2'; CBoucle(so,b,st+inttostr(l)+'µ'); end; // for g Relais if S2[1]='L' then begin //for g:=0 to Nb_Lampe-1 do begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; CBoucle(so,b,st+inttostr(l)+'µ'); end; // for g Lampe if S2[1]='P' then begin //for g:=0 to Nb_Compo-1 do begin if sa='0' then so:=so+'1'; if sa='1' then so:=so+'0'; CBoucle(so,b,st+inttostr(l)+'µ'); end; // for g Compo end; // if S2 end; // for l end; // * // * * * * * * * * * * * * * * * * * * // begin Cycle Exec begin // test('D'); gtc:=getTickcount(); if gtc1=0 then gtc1:=getTickcount(); // mémorise l'état des fonctions avant cycle (chaine) EtatF1:=''; for i:=0 to Nb_Fonction-1 do if L_Fonction[i].EtatP then EtatF1:=EtatF1+'1' else EtatF1:=EtatF1+'0'; // RAZ des potentiels for i:=0 to Nb_Potentiel-1 do begin L_Potentiel[i].Np:=rmax; L_Potentiel[i].Nm:=rmax; L_Potentiel[i].Rp:=rmax; L_Potentiel[i].Rm:=rmax; L_Potentiel[i].PRp:=rmax; L_Potentiel[i].PRm:=rmax; end; // RAZ des courants for i:=0 to Nb_Branche-1 do begin L_Branche[i].Courant:=-1; L_Branche[i].Parcouru:=-1; end; // PreBoucle les potentiels for i:=0 to Nb_Alim-1 do begin if L_Alim[i].modele='1' then PBoucle ('A'+IntToStr(i),true); if L_Alim[i].modele='2' then PBoucle ('A'+IntToStr(i),false); if (L_Alim[i].modele='3') and pulse then PBoucle ('A'+IntToStr(i),true); //if (L_Alim[i].modele='3') and not pulse then PBoucle ('A'+IntToStr(i),0,false,0); end; //} // Boucle les potentiels for i:=0 to Nb_Alim-1 do begin if L_Alim[i].modele='1' then Boucle ('A'+IntToStr(i),0,true); if L_Alim[i].modele='2' then Boucle ('A'+IntToStr(i),0,false); if (L_Alim[i].modele='3') and pulse then Boucle ('A'+IntToStr(i),0,true); //if (L_Alim[i].modele='3') and not pulse then Boucle ('A'+IntToStr(i),0,false,0); end; // Boucle des courants nuls (contacts ouverts) for i:=0 to Nb_Contact-1 do begin bc1:= L_Fonction[L_Contact[i].Fonction].EtatP; if (L_Contact[i].modele='1') or (L_Contact[i].modele='2') or (L_Contact[i].modele='13') or (L_Contact[i].modele='14') or (L_Contact[i].modele='10') or (L_Contact[i].modele='7') or (L_Contact[i].modele='16') or (L_Contact[i].modele='17') then begin if not bc1 then begin CNulBoucle ('C'+IntToStr(i)+'§0'); CNulBoucle ('C'+IntToStr(i)+'§1'); end; end; // c 1 2 13 14 10 7 // repos if (L_Contact[i].modele='3') or (L_Contact[i].modele='4') or (L_Contact[i].modele='11') or (L_Contact[i].modele='12') or (L_Contact[i].modele='15') or (L_Contact[i].modele='8') then begin if bc1 then begin CNulBoucle ('C'+IntToStr(i)+'§0'); CNulBoucle ('C'+IntToStr(i)+'§1'); end; end; // 3 4 11 12 // travail / repos if (L_Contact[i].modele='5') or (L_Contact[i].modele='6') or (L_Contact[i].modele='9') then begin if bc1 then begin CNulBoucle ('C'+IntToStr(i)+'§2'); end; if not bc1 then begin CNulBoucle ('C'+IntToStr(i)+'§1'); end; end; // c 5 6 9 } end;//for i:=0 to Nb_Contact-1 // Boucle des courants nuls (pulse éteint) for i:=0 to Nb_Alim-1 do begin if (L_Alim[i].modele='3') and not pulse then begin CNulBoucle ('A'+IntToStr(i)); end; end; // for i:=0 to Nb_Alim-1 // Boucle des courants nuls (relais non alimenté) for i:=0 to Nb_Relais-1 do begin if not (CalculPotentiel2(L_Relais[i].AppPot[0],L_Relais[i].AppPot[1])) then begin CNulBoucle ('R'+IntToStr(i)+'§0'); CNulBoucle ('R'+IntToStr(i)+'§1'); end; if (L_Relais[i].modele='10') or (L_Relais[i].modele='11') or (L_Relais[i].modele='12') then begin if not (CalculPotentiel2(L_Relais[i].AppPot[2],L_Relais[i].AppPot[3])) then begin CNulBoucle ('R'+IntToStr(i)+'§2'); CNulBoucle ('R'+IntToStr(i)+'§3'); end; end; end; // Boucle des courants nuls (Lampe non alimentée) for i:=0 to Nb_Lampe-1 do if not (CalculPotentiel2(L_Lampe[i].AppPot[0],L_Lampe[i].AppPot[1])) then begin CNulBoucle ('L'+IntToStr(i)+'§0'); CNulBoucle ('L'+IntToStr(i)+'§1'); end; // Boucle des courants nuls (Compo non alimentée) for i:=0 to Nb_Compo-1 do if not (CalculPotentiel2(L_Compo[i].AppPot[0],L_Compo[i].AppPot[1])) then begin CNulBoucle ('P'+IntToStr(i)+'§0'); CNulBoucle ('P'+IntToStr(i)+'§1'); end; // Boucle des courants nuls (noeuds dernière branche) repeat; for i:=0 to Nb_Connect-1 do begin cb2:=0; for j:=0 to Nb_Branche-1 do begin // branche if (L_Branche[j].Cote1='X'+IntToStr(i)) or (L_Branche[j].Cote2='X'+IntToStr(i)) then begin if L_Branche[j].Courant=-1 then inc(cb2); end; end; // for j:=0 to Nb_Branche-1 if cb2=1 then CNulBoucle('X'+IntToStr(i)); end; // for i:=0 to Nb_Connect-1 until not ResteBrancheNul; // Boucle les courants for i:=0 to Nb_Alim-1 do begin for j:=0 to Nb_Branche-1 do L_Branche[j].Parcouru:=-1;; if L_Alim[i].modele='1' then CBoucle ('A'+IntToStr(i),true,''); if L_Alim[i].modele='2' then CBoucle ('A'+IntToStr(i),false,''); end; // ... // Boucle des courants dans les connections for i:=0 to Nb_Connect-1 do begin L_Connect[i].Parcouru:=-1; for j:=0 to Nb_Branche-1 do begin // branche if (L_Branche[j].Cote1='X'+IntToStr(i)) or (L_Branche[j].Cote2='X'+IntToStr(i)) then begin if L_Branche[j].Courant=1 then L_Connect[i].Parcouru:=1; end; end; // for j:=0 to Nb_Branche-1 end; // for i:=0 to Nb_Connect-1 // Boucle des courants dans les alimentations (affichage courants) for i:=0 to Nb_Alim-1 do begin L_Alim[i].Parcouru:=-1; for j:=0 to Nb_Branche-1 do begin // branche if (L_Branche[j].Cote1='A'+IntToStr(i)) or (L_Branche[j].Cote2='A'+IntToStr(i)) then begin if L_Branche[j].Courant=1 then L_Alim[i].Parcouru:=1; end; end; // for j:=0 to Nb_Branche-1 end; // for i:=0 to Nb_Alim-1 // Boucle des courants dans les contacts (affichage courants) for i:=0 to Nb_Contact-1 do begin L_Contact[i].Parcouru:=-1; for j:=0 to Nb_Branche-1 do begin // branche if (pos('C'+IntToStr(i)+'§',L_Branche[j].Cote1)>0) or (pos('C'+IntToStr(i)+'§',L_Branche[j].Cote2)>0) then begin if L_Branche[j].Courant=1 then L_Contact[i].Parcouru:=1; end; end; // for j:=0 to Nb_Branche-1 end; // for i:=0 to Nb_Alim-1 // Boucle les lampes for i:=0 to Nb_Lampe-1 do begin if (L_Lampe[i].modele='1') or (L_Lampe[i].modele='2') then begin L_Lampe[i].EtatB:=CalculPotentiel2(L_Lampe[i].AppPot[0],L_Lampe[i].AppPot[1]); end; end; // Boucle les relais btempo:=false; for i:=0 to Nb_Relais-1 do begin //for j:=0 to Nb_Branche-1 do begin if (L_Relais[i].modele='1') or (L_Relais[i].modele='2') or (L_Relais[i].modele='3') then begin L_Fonction[L_Relais[i].Fonction].EtatF:=CalculPotentiel2(L_Relais[i].AppPot[0],L_Relais[i].AppPot[1]); end; if (L_Relais[i].modele='10') then begin L_Fonction[L_Relais[i].Fonction].EtatF:=CalculPotentielBASC(L_Fonction[L_Relais[i].Fonction].EtatP,L_Relais[i].AppPot[0],L_Relais[i].AppPot[1],L_Relais[i].AppPot[2],L_Relais[i].AppPot[3]); end; if (L_Relais[i].modele='4') or (L_Relais[i].modele='5') or (L_Relais[i].modele='6') or (L_Relais[i].modele='7') or (L_Relais[i].modele='8') or (L_Relais[i].modele='9') then begin L_Relais[i].EtatB:=CalculPotentiel2(L_Relais[i].AppPot[0],L_Relais[i].AppPot[1]); btempo:=true; end; if (L_Relais[i].modele='11') then begin L_Fonction[L_Relais[i].Fonction].EtatF:=CalculPotentielAM(L_Fonction[L_Relais[i].Fonction].EtatP,L_Relais[i].AppPot[0],L_Relais[i].AppPot[1],L_Relais[i].AppPot[2],L_Relais[i].AppPot[3]); end; if (L_Relais[i].modele='12') then begin L_Fonction[L_Relais[i].Fonction].EtatF:=CalculPotentielFA(L_Relais[i].AppPot[0],L_Relais[i].AppPot[1],L_Relais[i].AppPot[2],L_Relais[i].AppPot[3]); end; end; // boucle les potentiels dans les contacts (affichage potentiel) // ClrPotentiel(L_Potentiel[L_Branche[Sg.AppaBranche].AppaPotentiel].Rp,L_Potentiel[L_Branche[Sg.AppaBranche].AppaPotentiel].Rm); for i:=0 to Nb_Contact-1 do begin L_Contact[i].cl0:=clBlack; L_Contact[i].cl1:=clBlack; L_Contact[i].cl2:=clBlack; for j:=0 to Nb_Branche-1 do begin // branche if (pos('C'+IntToStr(i)+'§',L_Branche[j].Cote1)>0) then begin k:=1+pos('§',L_Branche[j].Cote1); k:=strtoint(L_Branche[j].Cote1[k]); if k=0 then L_Contact[i].cl0:=ClrPotentiel(L_Potentiel[L_Branche[j].AppaPotentiel].Rp,L_Potentiel[L_Branche[j].AppaPotentiel].Rm); if k=1 then L_Contact[i].cl1:=ClrPotentiel(L_Potentiel[L_Branche[j].AppaPotentiel].Rp,L_Potentiel[L_Branche[j].AppaPotentiel].Rm); if k=2 then L_Contact[i].cl2:=ClrPotentiel(L_Potentiel[L_Branche[j].AppaPotentiel].Rp,L_Potentiel[L_Branche[j].AppaPotentiel].Rm); end; if (pos('C'+IntToStr(i)+'§',L_Branche[j].Cote2)>0) then begin k:=1+pos('§',L_Branche[j].Cote2); k:=strtoint(L_Branche[j].Cote2[k]); if k=0 then L_Contact[i].cl0:=ClrPotentiel(L_Potentiel[L_Branche[j].AppaPotentiel].Rp,L_Potentiel[L_Branche[j].AppaPotentiel].Rm); if k=1 then L_Contact[i].cl1:=ClrPotentiel(L_Potentiel[L_Branche[j].AppaPotentiel].Rp,L_Potentiel[L_Branche[j].AppaPotentiel].Rm); if k=2 then L_Contact[i].cl2:=ClrPotentiel(L_Potentiel[L_Branche[j].AppaPotentiel].Rp,L_Potentiel[L_Branche[j].AppaPotentiel].Rm); end; end; // for j:=0 to Nb_Branche-1 end; // for i:=0 to Nb_Contact-1 if btempo then Temporisations; // Mise à jour des fonctions for i:=0 to Nb_Fonction-1 do L_Fonction[i].EtatP:=L_Fonction[i].EtatF; // Mise à jour des Contacts for j:=0 to Nb_Contact-1 do if L_Contact[j].Fonction>-1 then L_Contact[j].EtatP:= L_Fonction[L_Contact[j].Fonction].EtatP; // Affichage; // Form1.Image.Refresh; // gtc1:=gtc1+ (gettickcount-gtc); // form1.memo1.lines.add('Cycle inter '+IntToStr(gettickcount-gtc)); // mémorise l'état des fonctions après cycle (chaine) EtatF2:=''; for i:=0 to Nb_Fonction-1 do if L_Fonction[i].EtatP then EtatF2:=EtatF2+'1' else EtatF2:=EtatF2+'0'; // Form1.Button4Click(nil); Application.Processmessages; // si modification d'un état pendant le cycle : relance un cycle If EtatF1<>EtatF2 then begin if bExec then CycleExec; end else begin // form1.memo1.lines.add('Cycle fin '+IntToStr(gettickcount-gtc1)); gtc1:=0; Affichage; end; bExec2:=true; end; // CycleExec procedure Temporisations; var i:integer; tps:longword; EtatF1,EtatF2:string; begin if bexec2 then begin tps:=GetTickCount; // mémorise l'état des fonctions avant cycle (chaine) EtatF1:=''; for i:=0 to Nb_Fonction-1 do if L_Fonction[i].EtatF then EtatF1:=EtatF1+'1' else EtatF1:=EtatF1+'0'; for i:=0 to Nb_Relais-1 do begin if (L_Relais[i].modele='4') or (L_Relais[i].modele='5') or (L_Relais[i].modele='6') then begin if not L_Relais[i].EtatB then L_Relais[i].tpo:=tps; L_Fonction[L_Relais[i].Fonction].EtatF:=L_Relais[i].EtatB and (tps>(L_Relais[i].tpo+L_Relais[i].tpr)); end; // si relais temporisé TA if (L_Relais[i].modele='7') or (L_Relais[i].modele='8') or (L_Relais[i].modele='9') then begin if L_Relais[i].EtatB then L_Relais[i].tpo:=tps+L_Relais[i].tpr; L_Fonction[L_Relais[i].Fonction].EtatF:=L_Relais[i].EtatB or (tpsEtatF2 then begin CycleExec; end; // if changement d'état end; //if execution end; end.