📜 ⬆️ ⬇️

Visual component monitor COM-port

Today we will try to create a visual component for working with all sorts of readers connected via a COM port (the correct interface name is RS232). Our goal is to get the byte sequence that the device sends when it is read.

Let's start by creating a new project of the Delphi Component type:
image
In the next window, select TEdit as the parent component.
image
Finally, we give a sonorous name to our future component - TRS232Edit and place it in the MyComponents set of the component palette (RS 232 - the name of the standard).
image
After clicking Finish, we name the component module uRS232Edit.pas and save it. The development environment will automatically generate such a pattern:

unit uRS232EANEdit;
interface
uses
SysUtils, Classes, Controls, StdCtrls;

type
TRS232Edit = class(TEdit)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('MyComponents', [TRS232Edit]);
end;

end.


Let's declare the structure for storing 20 bytes from the port (more is not necessary :))
')
type
TBuffer = array[0..20] of byte;


We start laying the functional. To begin with, in the private section of the TRS232Edit class, we will declare variables in which we will store the connection parameters with the port.

cComPort : integer; //
cBaud : integer; // ()
cParity : integer; //
cCountBit : integer; //
cStopBit : integer; //


We also need

CommHandle : integer; // COM-
DCB : TDCB; //
Ovr : TOverlapped; //
Stat : TComStat; //
CommThread : THandle; // ,
function DigitHex(aValue: Integer): Char;
function GetAsHexagonal(aValue: Integer): String; // 16-
function DecodeBarCode(buf : TBuffer; bufsize : integer) : string;
procedure PortInit;
procedure SetZero;


and in the public section

BarCode : string; // Text
constructor Create(AOwner:Tcomponent);override;
destructor Free;
procedure Init(comport, baud, parity, countbit, stopbit : integer);


We will initialize the connection with the port by calling the Init method. In it, parameters are assigned to internal variables, initial values ​​are set and the connection method is called directly.

procedure TRS232EANEdit.Init(comport, baud, parity, countbit, stopbit : integer);
begin
cComPort := comport;
cBaud := baud;
cParity := parity;
cCountBit := countbit;
cStopBit := stopbit;
SetZero;
PortInit;
end;


The most interesting here is the PortInit method - let's analyze it in detail.

procedure TRS232EANEdit.PortInit;
var
ThreadID: dword ;
begin
//
CommHandle:= CreateFile(cComPort,GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,0);
// - " "
SetCommMask(CommHandle,EV_RXFLAG);
// DCB
GetCommState(CommHandle, DCB);
//
DCB.BaudRate:=cBaud;
DCB.Parity:=cParity;
DCB.ByteSize:=cCountBit;
DCB.StopBits:=cStopBit;
DCB.EvtChar:=chr(13); // 0x0D

//
SetCommState(CommHandle,DCB);
/* , . - . BeginThread - CreateThread. @ReadComm - */

CommThread := BeginThread(nil,0,@ReadComm,Self,0,ThreadID);
end;


Data reception occurs in the ReadComm procedure

procedure ReadComm(s : Pointer);
var
Resive : TBuffer;
a : TRS232EANEdit;
begin
a := s; // s -
while true do
begin
a.TransMask:=0;
WaitCommEvent(a.CommHandle,a.TransMask,@a.Ovr);
if (a.TransMask and EV_RXFLAG)=EV_RXFLAG then //
begin
ClearCommError(a.CommHandle,a.Errs,@a.Stat);
ReadFile(a.CommHandle, Resive, a.Stat.cbInQue, a.Stat.cbInQue, @a.Ovr);//
a.Text := a.DecodeBarCode(Resive, 20); // -
Application.ProcessMessages;
end;
end;
end;


Everything. Compile, install. To start reading, in the test application, it is enough to attribute something like

RS232Edit1.Init(1, 9600, 0, 8, 1)

Source: https://habr.com/ru/post/120183/


All Articles