1061 lines
40 KiB
ObjectPascal

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].Rp<i2) or (L_Potentiel[app].PRm=0) ) then b1:=false;
if not b and ((L_Potentiel[app].Rm<i2) or (L_Potentiel[app].PRp=0)) then b1:=false;
if b1 then begin
if b then L_Potentiel[app].Rp:=i2 else L_Potentiel[app].Rm:=i2;
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 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)<i2p/(i2p+i2m))and(i3p/(i3p+i3m)<i4p/(i4p+i4m));
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 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 (tps<L_Relais[i].tpo);
end; // si relais temporisé TA
end; // for i
// mémorise l'état des fonctions avant cycle (chaine)
EtatF2:='';
for i:=0 to Nb_Fonction-1 do if L_Fonction[i].EtatF then EtatF2:=EtatF2+'1' else EtatF2:=EtatF2+'0';
If EtatF1<>EtatF2 then begin
CycleExec;
end; // if changement d'état
end; //if execution
end;
end.