Newsgroup: it.comp.lang.delphi
Titolo: TPApro Porta seriale

Salve a tutti,
qualcuno di voi ha idea di come si usi il componente TAdpComPort senza 
l'evento OnTriggerAvail?
Creo il componente in una function, quindi non ho modo di usare il 
suddetto evento.
In particolare l'evento mi mette a disposizione una variabile Count, 
percui non ho la piu' pallida idea di come svuotare il buffer senza 
creare errori di run time.
Avete qualche idea?
Avevo pensato di fare cosi':
if ComPort.GetChar <> nil then
   pacchetto := pacchetto + ComPort.GetChar;
solo che ogni volta che chiamo il metodo GetChar, mi elimina il 
carattere dal buffer, per rendere disponibile il successivo.
Questo mi creerebbe altri errori...
Qualcuno ha altre idee???

   pacchetto := pacchetto + ComPort.GetChar;
Ecco il risultao se servisse:
var
   C : Char;
begin
.....
if ApdComPort.CharReady then
   C := ApdComPort.GetChar;
....
end;
Ciao,
--
Davide

 suddetto evento.
[]
Si' che ne hai modo, che problema c'e'? ad esempio, se vuoi usare la com
port in un thread a parte:
TComThread = class(TThread)
private
  fComPort: TApdComPort;
  fBuffer: string;
  fBufCount: integer;
  fToutHandle: word;
protected
  procedure Execute; override;
  procedure GetIncomingData(CP: TObject; Count: word);
  procedure HandleTimeout(CP: TObject; TriggerHandle: word);
  ...
public
  constructor Create(ComNum, BaudRate: integer);
  destructor Destroy; override;
end;
...
constructor TComThread.Create(ComNum, BaudRate: integer);
begin
  inherited Create(True);
  fComPort := TApdComPort.Create(nil);
  fBufCount := 0;
  fComPort.ComNumber := ComNum;
  fComPort.BaudRate := BaudRate;
  fComPort.OnTriggerAvail := GetIncomingData;
  fComPort.OnTriggerTimer := HandleTimeout;
  fComPort.Open := True;
  fToutHandle := AddTimerTrigger;
end;
procedure TComThread.Execute;
begin
  fComPort.SetTimerTrigger(fToutHandle, 182, true);
  while GetMessage(TmpMsg, 0, 0, 0) do begin
    DispatchMessage(TmpMsg);
    if Terminated then
      break;
  end;
end;
procedure TComThread.GetIncomingData(CP: TObject; Count: word);
var i: integer;
    ch: char
begin
  fComPort.SetTimerTrigger(fToutHandle, 0, false);
  for i := 0 to Count-1 do begin
    ch := fComPort.GetChar;
    fBuffer := fBuffer + ch;
  end;
  fComPort.SetTimerTrigger(fToutHandle, 18, True);
end;
Ovviamente questo caso in cui il proprietario (ed handler degli eventi)
della comPort e' un thread puo' essere banalmente ricondotto ad un caso
in cui il gestore e' un form, un datamodule o un qualunque oggetto.
Saluti
Paolo Arosio
-- 
"La dimostrazione dell'esistenza di specie intelligenti nell'universo
 e' che non ci vengono a trovare" [Calvin & Hobbes]

   fComPort := TApdComPort.Create(nil);
...



Ma per fare così la create del TApdComPort non doveva essere fatta
all'interno dell'Execute del TThread oppure è sufficiente la chiamata al
SetTimeTrigger per spostare la gestione degli eventi da un thread all'altro?
Dalle prove che ho fatto nei giorni scorsi per gestire i componenti comport
all'interno dei TThread, mi risultava che se creavo il componente comport
nella create, che a sua volta viene eseguita dal thread principale, gli
eventi di notifica di arrivo di dati, venivano processati dal thread
principale e non dal mio TThread. Questo perché la creazione della finestra,
alla quale verranno passati i messaggi di windows relativi all'attività
della seriale, avviene nella Create, che è eseguita nel thread principale.
Altre esperienze?

 Altre esperienze?
Una buona fonte di informazione ed esempi e' il sito di Paul Breneman
http://www.brenemanlabs.com/AsyncPro.htm


 in cui il gestore e' un form, un datamodule o un qualunque oggetto.
Ti ringrazio per la chiarificazione celerissima!
Effettivamente avevo pensato a creare un thred separato per gestire la 
cosa. Mi sono bloccato perche' in effetti pensavo fosse una cosa difficile.
Pero' se e' facile cosi' come scrivi, ci faccio un pensierino! Anzi, mi 
metto subito di impegno.
Ora una domanda, ho visto che sei abbastanza ferrato sull'uso di Asynk 
Pro e mi chiedevo se sapevi rispondere a questa cosa:
i := GetTickCount;
c := 1;
repeat
     while cpMain.CharReady do
       begin
         Pacchetto := Pacchetto+IntToStr(Byte(cpMain.GetChar))+ ' | ';
         if ((c mod 8) = 0) then
           begin
             if (Copy(Pacchetto, 1, 8) = '2 | 0 | ') then
               Result.Received := Pacchetto
             else
               Pacchetto := '';
           end;
         inc(c);
       end;
until (GetTickCount - i) < 8600;
Questo pezzo di codice mi serve per recuperare i dati e dividerli in 
pacchetti da 8 byte, che cominciano SEMPRE con #2 e finiscono SEMPRE con 
#3.
Ora il mio problema, il componente mi recupera solo i primi 6 caratteri, 
poi non ne riceve piu', ma sono certo che e' solo un problema di 
configurazione, perche' prima funzionava.
Usavo infatti gli eventi OnTriggerAvail e facevo la stessa cosa, solo 
che non avevo il timer e le variabili erano globali, per ricostruire il 
pacchetto diviso in piu' eventi.
Ora invce non mi funziona una ceppa... Hai idea di come posso fare, per 
aggiustare velocemente la funzione?
Il Thred penso che lo creero' questo fine settimana, quando avro' anche 
il tempo di studiarmi il manuale...
Ti ringrazio moltissimo per l'aiuto!
Ciao,
--
Davide Gurgone

 con #3.
Perche' non usare allora un DataPacket? Direi che e' la via piu' rapida.
Aternativamente userei un TriggerAvail + 1 o piu' dataTrigger impostati
in modo da scattare alla ricezione di STX (#2) e/o ETX (#3).


 in modo da scattare alla ricezione di STX (#2) e/o ETX (#3).
Sei una fonte di informazioni inesauribile....
:)
Grazie mille!
--
Davide