Friday, July 25, 2008

Delphi: Lettura dati da seriale

Lettura dati dalla porta seriale.

function Leggi(PortaCOM:String; Comando:String):String;
var str:string;
cmd, Buffer: Pchar;
hCom:Thandle;
ComStat: TComStat;
lpdcb:Tdcb;
bw,br:Dword;
Errors: DWORD;
begin
//Apro la porta
str := '';
hCom := CreateFile (pchar(PortaCOM),
GENERIC_READ + GENERIC_WRITE,
0, // comm devices must be opened w/exclusive-access*/
nil, // no security attrs */
OPEN_EXISTING, //* comm devices must use OPEN_EXISTING */ 0, //* not overlapped I/O */
0); //* hTemplate must be NULL for comm devices */ );
if (hCom = INVALID_HANDLE_VALUE) then

MessageBox(0, pChar('Impossibile aprire la porta seriale'), 'ATTENZIONE', MB_ICONSTOP or MB_OK)
else
if GetFileType( hCom ) <> FILE_TYPE_CHAR then
MessageBox(0, 'Attenzione errore apertura file', 'ATTENZIONE', MB_ICONSTOP or MB_OK)
else
Begin //Se tutto ok imposto i settaggi della porta: 9600:7:E:1
GetCommState(hCom, lpdcb);
lpdcb.BaudRate := Settaggi.BaudRate;
lpdcb.ByteSize := Settaggi.ByteSize;
lpdcb.Parity := Settaggi.Parity;
lpdcb.StopBits := Settaggi.StopBits;
SetCommState(hCom, lpdcb); //costruisco il comando da inviare alla porta
cmd := pchar(Comando);
bW := 0;
bR := 0;
str := ''; //Scrivo il comando sulla porta
WriteFile(hCom,cmd^,Length(Comando),bW,nil);
//Attendo 2 sec.
sleep(2000);
//Leggo i bytes nel buffer di input
ClearCommError(hCom, Errors, @ComStat);
if ComStat.cbInQue > 0 then
begin
//Alloco la memoria necessaria per memorizzare i bytes letti
GetMem(Buffer, ComStat.cbInQue);
//Leggo i bytes
ReadFile(hCom,Buffer^,ComStat.cbInQue,br,nil);
//trasferisco il buffer in Str
setLength(str, br);
Move(Buffer^, PChar(str)^, br);
//libero la memoria occupata dal buffer
FreeMem(Buffer);
end;
end;
closeHandle(hcom);
result:=str;
end;

Inseressante la funzione ClearCommError che consente di sapere i byte in attesa di essere scaricati. Questa funzione aspetta che sulla COM siano presenti i Byte riportati dalla funzione prima di uscire dal ReadFile.