Problemas com comunicação de porta serial

18/08/2008

0

Olá a todos, estou com problemas com um programinha que lê os dados enviados para a porta serial do micro! Estou usando uma API do windows pra isso e o problema é um tanto estranho! Qdo ligo o micro e coloco o programa para rodar ele ñ funciona, recebe apenas um ou dois caracteres de controle! Se eu abrir o Hiper Terminal do Windows e colocar as mesmas configurações q estão dentro do programa, os dados são recebidos corretamente no Hyper Terminal! O grande problema é q depois q uso o Hiper Termial e o fecho, o programa passa a receber os dados corretamente! Estou colocando a parte do cógiso em q acho q pode estar o problema!
Desde já Obrigado


Function OpenComm(NomePorta, ConfigPorta: String):Boolean;
var BarDCB: DCB;
    LastError: Cardinal;
    CTimeOut: COMMTIMEOUTS;
begin
   hComm:=CreateFile(PChar(NomePorta),GENERIC_READ+GENERIC_WRITE,
                                0, //not shared
                                nil, //no security
                                OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL, //+FILE_FLAG_OVERLAPPED
                                0 );
    If hComm = INVALID_HANDLE_VALUE Then begin
        ShowMessage(´Porta Serial ´ + NomePorta + ´ não disponível. configure os paramentros da porta serial´);
        Result:=False;
        Exit;
    End;
//  Configurar os Time Outs para a Porta
    CtimeOut.ReadIntervalTimeout:=20;
    CtimeOut.ReadTotalTimeoutConstant:=1;
    CtimeOut.ReadTotalTimeoutMultiplier:=1;
    CtimeOut.WriteTotalTimeoutConstant:=20;
    CtimeOut.WriteTotalTimeoutMultiplier:=1;
    iRet:=SetCommTimeouts(hComm, CTimeOut);
    If Ord(iRet)= -1 Then begin
        LastError:=GetLastError();
        ShowMessage(´Não é permitido configurar os Timeouts para esta porta ´ + NomePorta + ´ Erro: ´ + Inttostr(LastError));
        CloseHandle(hComm);
        Result:=False;
        Exit;
    End;
    BarDCB.BaudRate := CBR_115200;
    BarDCB.ByteSize := 8;
    BarDCB.Parity   := NOPARITY;
    BarDCB.StopBits := ONESTOPBIT;

    iRet:=BuildCommDCB(PChar(´COM1:115200,N,8,1´), BarDCB);
    If Ord(iRet)=-1 Then begin
        LastError:= GetLastError();
        ShowMessage(´Não é permitido montar os parametros da Porta´ + ConfigPorta + ´ Erro: ´ + Inttostr(LastError));
        CloseHandle(hComm);
        Result:=False;
        Exit;
    End;}
    iRet := SetCommState(hComm, BarDCB);
    If Ord(iRet)= -1 Then begin
        LastError:= GetLastError();
        ShowMessage(´Não é permitido configurar os parametros da Porta´ + ConfigPorta + ´ Erro: ´ + Inttostr(LastError));
        CloseHandle(hComm);
        Result:=False;
        Exit;
    End;
    Result:=True;
End;



Ccbrambilla

Ccbrambilla

Responder

Posts

18/08/2008

Obrunno

O problema é que o windows XP não permite controlar dispositivos de hardware diretamente sem driver iniciado.

Em outras palavras, vc terá de simular o uso de um driver. Tenho um sistema desse funcionando perfeitamente via porta paralela.

Sugiro a vc usar a inpout32.dll. Pesquise na internet a fonte de download e os parametros de uso.


Responder

20/08/2008

Ccbrambilla

Olá obruno, obrigado pela dica!
Consegui resolver o problema usando a API do windows (com apenas 1 linha) e agora está ótimo, só preciso testar com o Vista ou ainda o 98!

Valeu

CEzar


Responder

20/08/2008

Carlosib

Coloca ae a solução encontrada :)


Responder

20/08/2008

Ccbrambilla

Segue o código completo e mais tratado do q o anterior e o problemas estava no fato de não usar o comando ´GetCommState´ antes de setar os parâmetros de configuração da porta.

Abraços a todos!

Function OpenComm(NomePorta, ConfigPorta: String):Boolean;
var BarDCB: DCB;
    LastError: Cardinal;
    CTimeOut: COMMTIMEOUTS;
begin
   hComm:=CreateFile(PChar(NomePorta),GENERIC_READ+GENERIC_WRITE,
                                0, //not shared
                                nil, //no security
                                OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL, //+FILE_FLAG_OVERLAPPED
                                0 );
    If hComm = INVALID_HANDLE_VALUE Then
    begin
        ShowMessage(´Porta Serial ´ + NomePorta + ´ não disponível. configure os paramentros da porta serial´);
        Result:=False;
        Exit;
    End;
//  Configurar os Time Outs para a Porta
    CtimeOut.ReadIntervalTimeout         :=20;
    CtimeOut.ReadTotalTimeoutConstant    :=1;
    CtimeOut.ReadTotalTimeoutMultiplier  :=1;
    CtimeOut.WriteTotalTimeoutConstant   :=20;
    CtimeOut.WriteTotalTimeoutMultiplier :=1;

    iRet:=SetCommTimeouts(hComm, CTimeOut);
    If Ord(iRet)= -1 Then
    begin
        LastError:=GetLastError();
        ShowMessage(´Não é permitido configurar os Timeouts para esta porta ´ + NomePorta + ´ Erro: ´ + Inttostr(LastError));
        CloseHandle(hComm);
        Result:=False;
        Exit;
    End;

    iRet := GetCommState(hComm, BarDCB);
    If Ord(iRet)=-1 Then
    begin
        LastError:= GetLastError();
        ShowMessage(´Não é permitido montar os parametros da Porta ´ + ConfigPorta + ´ Erro: ´ + Inttostr(LastError));
        CloseHandle(hComm);
        Result:=False;
        Exit;
    End;

    BarDCB.BaudRate := CBR_115200;
    BarDCB.ByteSize := 8;
    BarDCB.Parity   := NOPARITY;
    BarDCB.StopBits := ONESTOPBIT;

    iRet:=BuildCommDCB(PChar(NomePorta + ´:´ + ConfigPorta), BarDCB);
    If Ord(iRet)=-1 Then
    begin
        LastError:= GetLastError();
        ShowMessage(´Não é permitido montar os parametros da Porta ´ + ConfigPorta + ´ Erro: ´ + Inttostr(LastError));
        CloseHandle(hComm);
        Result:=False;
        Exit;
    End;

    iRet := SetCommState(hComm, BarDCB);
    If Ord(iRet)= -1 Then
    begin
        LastError:= GetLastError();
        ShowMessage(´Não é permitido configurar os parametros da Porta´ + ConfigPorta + ´ Erro: ´ + Inttostr(LastError));
        CloseHandle(hComm);
        Result:=False;
        Exit;
    End;
    Result:=True;
End;



Responder

20/08/2008

Carlosib

Não querendo ser chato... mas já o sendo... dá um exemplo de quais parâmetros vc passaria para chamar a função.

Function OpenComm(NomePorta, ConfigPorta: String):Boolean


Nome da porta seria COM1, COM2, etc?

ConfigPorta seria o que?


Responder

20/08/2008

Ccbrambilla

Sem problema nenhum, é o seguinte, o NomePorta é isso COM1, COM2...

o ConfigPorta seria ´115200,N,8,1´ onde esses parâmetros seriam:

´BaudeRate, Parity, ByteSize, StopBits´, e passando esses parâmetros eu acho q nem precisaria passar as linas de código :

    BarDCB.BaudRate := CBR_115200; 
    BarDCB.ByteSize := 8; 
    BarDCB.Parity   := NOPARITY; 
    BarDCB.StopBits := ONESTOPBIT; 


mas ainda não deu tempo de fazer os testes!

Abraços


Responder

15/04/2015

Wilson Azevedo

Estou utilizando a mesma API e o mesmo código para comunicação com um transceptor de radioamador que utiliza caracteres em Hexadecimal em sua conexão com a serial. A recepção dos caracteres está ok, más não tô conseguindo transmitir nenhum caracter, através da função "function TPorta_Serial.SendComm(sComando: String): Integer;". Já alterei a forma de abertura da COM em "function TPorta_Serial.F_CharToHex(MyChar: Char): String;" e nada. Outra questão, é que quando abrimos a COM, a linhas DTR e RTS vem habilitadas, precisando chamar a funções correspondentes (final do código) para desativá-las, ocasionando um pico momentâneo de ativação das mesmas. Teria como abrir a serial ser ter essas linhas ativadas? Estou usando o Delphi X7 e Windows 8.1. Se alguém puder me ajudar serei grato. Veja o código abaixo.

[code][/unit Porta_Serial_Codigo;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;

type
TPorta_Serial = class(TForm)
function F_CharToHex(MyChar: Char): String;
function OpenComm(NomePorta, ConfigPorta: String): Boolean;
function CloseComm(): Boolean;
procedure FlushComm();
procedure ClearReadComm();
procedure ClearSendComm();
function ReadComm(): String;
function SendComm(sComando: String): Integer;
function GetSensors(): String;
procedure DTR_On_Off(ATIVADO: Boolean);
procedure RTS_On_Off(ATIVADO: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Porta_Serial: TPorta_Serial;
hComm: THandle;
bRead: array[0..255] of byte;
iRet: LongBool;
bAberta: Boolean;

implementation

{$R *.dfm}

uses Captura_Dados_Serial;

function TPorta_Serial.F_CharToHex(MyChar: Char): String;
var escala: string;
res, num: integer;
begin
num:=Ord(Mychar);
escala := '0123456789ABCDEF';
res := (num div 16);
result := escala[res+1];
res := (num-(res*16));
result := result+escala[res+1];
end;

function TPorta_Serial.OpenComm(NomePorta, ConfigPorta: String): Boolean;
var
BarDCB: DCB;
LastError: Cardinal;
CTimeOut: COMMTIMEOUTS;
begin
//==============================================================================
// Abrir porta.
hComm := CreateFile(PChar(NomePorta),GENERIC_READ + GENERIC_WRITE,
0, //not shared
nil, //no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, //+ FILE_FLAG_OVERLAPPED
0 );

if hComm = INVALID_HANDLE_VALUE then
begin
ShowMessage('Porta Serial ' + NomePorta + ' não disponível. Configure os parâmentros da porta serial');
Result := False;
Exit;
end;
//==============================================================================
// Configurar os Time Outs para a Porta
CtimeOut.ReadIntervalTimeout:=20;
CtimeOut.ReadTotalTimeoutConstant:=1;
CtimeOut.ReadTotalTimeoutMultiplier:=1;
CtimeOut.WriteTotalTimeoutConstant:=20;
CtimeOut.WriteTotalTimeoutMultiplier:=1;

iRet := SetCommTimeouts(hComm, CTimeOut);

if Ord(iRet) = -1 then
begin
LastError := GetLastError();
ShowMessage('Não é permitido configurar os timeouts para esta porta ' + NomePorta + ' Erro: ' + Inttostr(LastError));
CloseHandle(hComm);
Result := False;
Exit;
end;
//==============================================================================
iRet := GetCommState(hComm, BarDCB);

if Ord(iRet) = -1 then
begin
LastError := GetLastError();
ShowMessage('Não é permitido montar os parâmetros da porta ' + ConfigPorta + ' Erro: ' + Inttostr(LastError));
CloseHandle(hComm);
Result := False;
Exit;
end;
//==============================================================================
iRet := BuildCommDCB(PChar(NomePorta + ':' + ConfigPorta), BarDCB);

if Ord(iRet) = -1 then
begin
LastError := GetLastError();
ShowMessage('Não é permitido montar os parâmetros da porta ' + ConfigPorta + ' Erro: ' + Inttostr(LastError));
CloseHandle(hComm);
Result := False;
Exit;
end;
//==============================================================================
iRet := SetCommState(hComm, BarDCB);

if Ord(iRet)= -1 then
begin
LastError := GetLastError();
ShowMessage('Não é permitido configurar os parâmetros da porta ' + ConfigPorta + ' Erro: ' + Inttostr(LastError));
CloseHandle(hComm);
Result := False;
Exit;
end;
//==============================================================================

//Desligando os comandos.
DTR_On_Off(False);
RTS_On_Off(False);

Result := True;
end;
//==============================================================================
{
Objetivo: Fechar comunicação com a porta serial
Retorno: True ou false
}
function TPorta_Serial.CloseComm(): Boolean;
begin
Result := CloseHandle(hComm);
end;
//==============================================================================
{
Objetivo: Limpar Buffer de Leitura e Escrita
}
procedure TPorta_Serial.FlushComm();
begin
FlushFileBuffers(hComm);
end;
//==============================================================================
{
Objetivo: Limpar dados recebidos na porta serial
}
procedure TPorta_Serial.ClearReadComm();
begin
PurgeComm(hComm,PURGE_RXCLEAR);
end;
//==============================================================================
{
Objetivo: Limpar dados enviados para porta serial
}
procedure TPorta_Serial.ClearSendComm();
begin
PurgeComm(hComm,PURGE_TXCLEAR);
end;
//==============================================================================
{
Objetivo: Ler dados na Porta serial
Retorno: String
}
function TPorta_Serial.ReadComm(): String;
var
BytesLidos: DWord;
I: Integer;
ReadStr: String;
begin
iRet := ReadFile(hComm, bRead[0], 255, BytesLidos, nil);
if ord(iRet) = -1 then exit;
ReadStr := '';

//if BytesLidos > 0 then ShowMessage(IntToStr(BytesLidos));

if BytesLidos > 0 then
begin
for I := 0 to BytesLidos - 1 do ReadStr := ReadStr + chr(bRead[I]);
end
else
begin
FlushComm;
end;

Result := ReadStr;
end;
//==============================================================================
{
Objetivo: Enviar dados para a porta serial
Paramentros:
sComando = ’54FEC400'
comando para configurar o leitor em 9600,o,8,1
Modelo TL800 da empresa Tecsimi
Retorno: Integer
}
function TPorta_Serial.SendComm(sComando: String): Integer;
var
BytesEnviados: DWORD;
begin
iRet := WriteFile(hComm,PCHAR(sComando)[0],Length(sComando), BytesEnviados, nil);
FlushComm;

if iRet then Result := BytesEnviados else Result := -1;
end;
//==============================================================================
//Saber estado de sensores.
function TPorta_Serial.GetSensors(): String;
var
COMStatus: DWORD; //Status do Modem (API).
RETORNO: String[4];
begin
//Obtém estado da COM.
GetCommModemStatus(hComm, COMStatus);

if(COMStatus and MS_RLSD_ON) = MS_RLSD_ON then //Se DCD está ligado.
RETORNO := '1' //DCD Ligado.
else
RETORNO := '0'; //DCD desligado.

if(COMStatus and MS_DSR_ON) = MS_DSR_ON then //Se DSR está ligado.
RETORNO := RETORNO + '1' //DSR ligado.
else
RETORNO := RETORNO + '0'; //DSR desligado.

if(COMStatus and MS_CTS_ON) = MS_CTS_ON then //Se CTS está ligado.
RETORNO := RETORNO + '1' //CTS ligado.
else
RETORNO := RETORNO + '0'; //CTS desligado.

if(COMStatus and MS_RING_ON) = MS_RING_ON then //Se RI está ligado.
RETORNO := RETORNO + '1' //RI ligado.
else
RETORNO := RETORNO + '0'; //RI desligado.

Result := RETORNO;
end;
//==============================================================================
//Ativar/Deativar comando DTR.
procedure TPorta_Serial.DTR_On_Off(ATIVADO: Boolean);
begin
if ATIVADO = True then
EscapeCommFunction(hComm, SETDTR) //Liga a linha DTR.
else
EscapeCommFunction(hComm, CLRDTR); //Desliga a linha DTR.
end;
//==============================================================================
//Ativar/Deativar comando RTS.
procedure TPorta_Serial.RTS_On_Off(ATIVADO: Boolean);
begin
if ATIVADO = True then
EscapeCommFunction(hComm, SETRTS) //Liga a linha RTS.
else
EscapeCommFunction(hComm, CLRRTS); //Desliga a linha RTS.
end;
//==============================================================================

end.code]


Abraço a todos.
Responder

07/01/2021

Mauricio Gabriel

Function OpenComm(NomePorta, ConfigPorta: String):Boolean

Poderia por favor ajudar-me neste sentido , pois estou com dificuldades em passar os parametros acima citados , devido ser iniciantes , fiz varias tentativas e sem sucesso de como chamar essa function .... poderia por favor ajudar-me neste sentido , ou posta o arquivo .pas para estudo a aprendizado. Desde já antecipo cordial agradecimentos.

Abaços.
Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar