Due programmi che condividono uModbusRTU e uGauge: - Console/PlanciaConsole: plancia nautica descritta da file XML, con modalita' plancia e modalita' configurazione. Comandi, spie, selettori, strumenti e allarmi sonori; il bus gira in un thread suo perche' la finestra non si fermi mai. - ProjectPlancia: il programma di prova piu' vecchio, usato per collaudare i canali. Le plance sono in Console/*.xml, la documentazione in Console/LEGGIMI.md. Esclusi dal versionamento i compilati (.exe, .dcu), i file dell'IDE e un audio da 17 MB. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
130 lines
3.2 KiB
ObjectPascal
130 lines
3.2 KiB
ObjectPascal
program monitorio;
|
|
|
|
{
|
|
Mostra in tempo reale gli ingressi digitali di un modulo IO.
|
|
|
|
Serve al banco, quando si collega un morsetto e si vuole vedere subito quale
|
|
canale si muove. Stampa una riga solo quando qualcosa cambia, cosi' la
|
|
finestra non scorre da sola e la cronologia resta leggibile.
|
|
|
|
Uso: monitorio [porta] [baud] [slave] [canali] [cicli]
|
|
cicli = quante letture fare prima di uscire; 0 o assente = per sempre
|
|
Es.: monitorio COM7 9600 2 8
|
|
|
|
Si chiude con Ctrl+C.
|
|
}
|
|
|
|
{$APPTYPE CONSOLE}
|
|
|
|
uses
|
|
System.SysUtils,
|
|
uModbusRTU in '..\..\uModbusRTU.pas';
|
|
|
|
/// "1 0 0 1 . . . ." con i canali spenti resi come punto: gli accesi saltano all'occhio.
|
|
function Render(const ABits: TArray<Boolean>): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
for I := 0 to High(ABits) do
|
|
if ABits[I] then
|
|
Result := Result + '[1]'
|
|
else
|
|
Result := Result + ' . ';
|
|
end;
|
|
|
|
function Header(ACount: Integer): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
for I := 0 to ACount - 1 do
|
|
Result := Result + Format(' %d ', [I]);
|
|
end;
|
|
|
|
var
|
|
Port: string;
|
|
Baud, Slave, Count, Cycles, Done: Integer;
|
|
Bus: TModbusRTU;
|
|
Bits, Prev: TArray<Boolean>;
|
|
First: Boolean;
|
|
Changed: Boolean;
|
|
I, Errors: Integer;
|
|
LastErr: string;
|
|
|
|
begin
|
|
Port := 'COM7'; Baud := 9600; Slave := 2; Count := 8; Cycles := 0; Done := 0;
|
|
if ParamCount >= 1 then Port := ParamStr(1);
|
|
if ParamCount >= 2 then Baud := StrToIntDef(ParamStr(2), 9600);
|
|
if ParamCount >= 3 then Slave := StrToIntDef(ParamStr(3), 2);
|
|
if ParamCount >= 4 then Count := StrToIntDef(ParamStr(4), 8);
|
|
if ParamCount >= 5 then Cycles := StrToIntDef(ParamStr(5), 0);
|
|
|
|
Writeln(Format('Ingressi dello slave %d su %s a %d baud. Ctrl+C per uscire.',
|
|
[Slave, Port, Baud]));
|
|
Writeln;
|
|
Writeln(' canale: ' + Header(Count));
|
|
Writeln;
|
|
|
|
Bus := TModbusRTU.Create(Port, Baud, 500);
|
|
try
|
|
Bus.Connect;
|
|
First := True;
|
|
Errors := 0;
|
|
LastErr := '';
|
|
SetLength(Prev, 0);
|
|
|
|
while True do
|
|
begin
|
|
try
|
|
Bits := Bus.ReadDiscreteInputs(Slave, 0, Count);
|
|
|
|
if Errors > 0 then
|
|
begin
|
|
Writeln(Format('%s ... ripristinato dopo %d letture fallite',
|
|
[FormatDateTime('hh:nn:ss', Now), Errors]));
|
|
Errors := 0;
|
|
end;
|
|
|
|
Changed := First or (Length(Prev) <> Length(Bits));
|
|
if not Changed then
|
|
for I := 0 to High(Bits) do
|
|
if Bits[I] <> Prev[I] then
|
|
begin
|
|
Changed := True;
|
|
Break;
|
|
end;
|
|
|
|
if Changed then
|
|
begin
|
|
Writeln(FormatDateTime('hh:nn:ss', Now) + ' ' + Render(Bits));
|
|
Prev := Copy(Bits);
|
|
First := False;
|
|
end;
|
|
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
// Un errore ripetuto non deve riempire lo schermo: lo si stampa
|
|
// la prima volta e poi si tace finche' non cambia.
|
|
Inc(Errors);
|
|
if E.Message <> LastErr then
|
|
begin
|
|
Writeln(FormatDateTime('hh:nn:ss', Now) + ' ERRORE: ' + E.Message);
|
|
LastErr := E.Message;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
Sleep(200);
|
|
|
|
Inc(Done);
|
|
if (Cycles > 0) and (Done >= Cycles) then
|
|
Break;
|
|
end;
|
|
|
|
finally
|
|
Bus.Free;
|
|
end;
|
|
end.
|