il discorso del ciclo infinito alla fine non è che sia questo gran problema, basta mettere uno sleep per ottenere un'attesa.
per quanto riguarda il "bottone sulla form", come dicevo sul post precedente, non devi mandare il comando direttamente ma lo devi mettere in coda.
poi il famoso loop infinito lo puoi fare tipo
var esci_dal_ciclo: boolean;
s: string;
begin
esci_dal_ciclo := false;
repeat
while coda.count > 0 then
// preleva comando da prima posizione coda
s := coda[0];
// elimina il primo elemento nella coda
coda.delete(0);
// invia comando
send_command_rs485(s);
// legge risultato
s := get_rs485_result;
// fa qualcosa col risultato
process_rs485_result(s);
end;
// legge status
send_command_rs485('get_status');
s := get_rs485_result;
process_rs485_result(s);
// se è il caso aspetta
if coda.count = 0 then
sleep(300);
until esci_dal_ciclo;
end;
In questo modo se l'utente non invia comandi, il loop esegue sempre una interrogazione dello stato.
Se ci sono comandi, questi vengono eseguiti e poi si riparte con l'interrogazione.
Nel pezzo di codice sopra i comandi utente vengono eseguiti tutti quanti prima di riprendere ad interrogare lo stato, se non dovesse andar bene puoi fare 1 comando e poi interroghi.
Poi nella form ci puoi mettere 2 pulsanti:
1) un bottone che imposta esci_dal_ciclo = true (per uscire dal repeat/until e chiudere il programma)
2) un bottone che mette il comando che vuole l'utente nella coda
Con questo modo non ti serve neanche il semaforo; non so se il pezzo di codice è adatto a quello che vuoi fare tu ma intanto può essere un inizio.
Ciao
nomorelogic
ciao Nomore
grazie delle dritte ma vorrei sottoporti ilseguente codice (che poi è quasi il tuo)...
Una form e due pulsanti: il primo fa partire e il secondo dovrebbe fermare ma è in possibile in quanto il ciclo continua...è li che non capisco
ho inserito 1000 righe allo show in una stringlist
lancio il via (button1)
ma ne durante l'eliminazione delle 1000 righe ne durante il ciclo di sleep riesco a preme l'altro bottone.
in buona sostanza fino a che il ciclo di repeat non finisce non posso intervenire e nemmeno durante il ciclo di sleep
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormShow(Sender: TObject);
procedure ciclo;
private
{ private declarations }
ferma: Boolean;
coda: TStringList;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i:= 0 to 100 do
coda.Add('comando'+IntToStr(i));
ciclo;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ferma:= True;
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
coda.Free;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
coda:= TStringList.Create;
end;
procedure TForm1.ciclo;
var
s: String;
begin
ferma:= False;
repeat
while coda.count > 0 do
begin
// preleva comando da prima posizione coda
s := coda[0];
// elimina il primo elemento nella coda
coda.delete(0);
// fa qualcosa col risultato
Label1.Caption:= s;
end;
if coda.count = 0 then
sleep(300);
until ferma;
end;
end.