Files
2023-11-19 22:39:32 +08:00

159 lines
3.8 KiB
ObjectPascal

unit SerialManager;
{$mode ObjFPC}{$H+}
{$m+}
interface
uses
Classes, SysUtils, Synaser;
type
TRecvDataEvent = procedure(Data: string) of object;
TConnectedEvent = procedure of object;
TConnectedFailedEvent = procedure of object;
TClosedEvent = procedure of object;
{ SerialThread }
SerialThread = class(TThread)
protected
procedure Execute; override;
procedure ProcessRecvEvent;
procedure ProcessConnectedEvent;
procedure ProcessConnectedFailedEvent;
procedure ProcessOnCloseEvent;
private
MserialPort: TBlockSerial;
MSerialName: string;
FOnRecvData: TRecvDataEvent;
FOnConnected: TConnectedEvent;
FOnClosed: TClosedEvent;
FOnConnectedFailed: TConnectedFailedEvent;
currentRecvData: string;
public
constructor Create(CreateSuspended: boolean; serialName: string);
destructor Destroy; override;
procedure Close();
procedure SendString(Data: ansistring);
function SendBuffer(buffer: pointer; length: integer): integer;
procedure ConfigureSerial(baud, bits: integer; parity: char;
stop: integer; softflow, hardflow: boolean);
property OnRecvData: TRecvDataEvent read FOnRecvData write FOnRecvData;
property OnConnected: TConnectedEvent read FOnConnected write FOnConnected;
property OnConnectedFailed: TConnectedFailedEvent
read FOnConnectedFailed write FOnConnectedFailed;
property OnClosed: TClosedEvent read FOnClosed write FOnClosed;
function isConnected(): boolean;
end;
implementation
constructor SerialThread.Create(CreateSuspended: boolean; serialName: string);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
self.MSerialName := serialName;
Self.MserialPort := TBlockSerial.Create;
end;
destructor SerialThread.Destroy;
begin
inherited Destroy;
FreeAndNil(MserialPort);
end;
procedure SerialThread.Close;
begin
if MserialPort <> nil then
begin
MserialPort.Purge();
MserialPort.CloseSocket();
Terminate();
FreeAndNil(MserialPort);
ProcessOnCloseEvent();
end;
end;
procedure SerialThread.SendString(Data: ansistring);
begin
if (MserialPort <> nil) and isConnected() then
MserialPort.SendString(Data);
end;
function SerialThread.SendBuffer(buffer: pointer; length: integer): integer;
begin
if (MserialPort <> nil) and isConnected() then
Result := MserialPort.SendBuffer(buffer, length);
end;
procedure SerialThread.ConfigureSerial(baud, bits: integer; parity: char;
stop: integer; softflow, hardflow: boolean);
begin
MserialPort.Config(baud, bits, parity, stop,
softflow, hardflow);
end;
function SerialThread.isConnected(): boolean;
begin
Result := ((MserialPort <> nil) and MserialPort.InstanceActive);
end;
procedure SerialThread.Execute;
begin
MserialPort.Connect(MSerialName);
if isConnected() then
begin
Synchronize(@ProcessConnectedEvent);
end
else
begin
Synchronize(@ProcessConnectedFailedEvent);
Exit;
end;
while not (Terminated) do
begin
currentRecvData := MserialPort.RecvPacket(-1);
Synchronize(@ProcessRecvEvent);
end;
end;
procedure SerialThread.ProcessRecvEvent;
begin
if Assigned(FOnRecvData) then
begin
FOnRecvData(currentRecvData);
end;
end;
procedure SerialThread.ProcessConnectedEvent;
begin
if Assigned(FOnConnected) then
begin
FOnConnected();
end;
end;
procedure SerialThread.ProcessConnectedFailedEvent;
begin
if Assigned(FOnConnectedFailed) then
begin
FOnConnectedFailed();
end;
end;
procedure SerialThread.ProcessOnCloseEvent;
begin
if Assigned(FOnClosed) then
begin
FOnClosed();
end;
end;
end.