gpt4 book ai didi

multithreading - 如何发送字符串(串行端口),等待(超时)并捕获回复字符串?

转载 作者:行者123 更新时间:2023-12-03 18:37:37 27 4
gpt4 key购买 nike

在阅读了关于stackoverflow的这个非常有趣的主题之后-> How to wait for COM port receive event before sending more data in a loop

我遇到了很多问题,并且尝试了许多解决方案……不幸的是,一切都做不好!

许多串行端口库都是事件驱动的,我很难理解它们。

我已经尝试过Asyncpro,Sinaser和TComport。

是否可以有这样的功能:

SerialSendandReply(此处为tx字符串,超时)返回rx字符串,如果超时则发送错误字符串

来自设备的响应以毫秒为单位进行屏蔽会更好吗?

像这样:

Dosomething here
showmessage(SerialSendandReply('test',100 )); //100 ms timeout
dosomething else

有了这个代码
TForm1 = class(TForm)
...
private
IOEvent : THandle; // used for IO events
IORx : string;
Comport : TapdComport;
...


procedure TForm1.ComportTriggerAvail(CP: TObject; Count: Word);

var i : integer;

begin
for i:=1 to Count do
IORx:=IORx+Comport.GetChar;
SetEvent(IOEvent);
end;

function TForm1.SerialSAWR(tx : string; TimeOut : integer) : boolean;
begin
Result := False;
try
IORx := ''; // your global var
ResetEvent(IOEvent);
Comport.PutString(tx);
Result := WaitForSingleObject(IOEvent, TimeOut) = WAIT_OBJECT_0;
except
on E : Exception do
// dosomething with exception
end;
end;

// constructor part
IOEvent := CreateEvent(nil, True, False, nil);
// destructor part
if IOEvent <> 0 then
CloseHandle(IOEvent);

然后我试图调用此函数:
if SerialSAWR('test'; 5000) then showmessage(IORx);

发送效果很好,但不返回字符串中的任何内容。

有什么建议吗?

非常感谢你!

问候,
劳伦特

最佳答案

我使用TComPort,并创建了以下例程来执行您要求的操作。 TComPort在其监视线程中监视收到的字符,而我的例程在不调用Application.ProcessMessages的情况下等待字符。它可能不是最优雅的代码,但是可以正常工作。

function TArtTComPort.SerialPort_AwaitChars(AMinLength: integer;
ATerminator: char; AQtyAfterTerm: integer; ARaise: boolean): string;
var
fDueBy : TDateTime;

function IsEndOfReplyOrTimeout( var AStr : string ) : boolean;
var
I : integer;
begin
Result := False;
If ATerminator <> #0 then
begin
I := Length( AStr ) - AQtyAfterTerm;
If I > 0 then
Result := AStr[I] = ATerminator;
end;
If not Result then
Result := Length(AStr) >= AMinLength;


// Un-comment this next line to disable the timeout.
//Exit;

If not Result then
begin
Result := Now > fDueBy;
If Result then
If ARaise then
raise EArtTComPort.Create( 'Serial port reply timeout' )
else
AStr := '';
end;
end;

var
Events : TComEvents;
iCount : integer;
S : string;
begin
Assert( AMinLength > 0, 'Invalid minimum length' );

If not FComPort.Connected then
begin
Result := '';
Exit;
end;

fDueBy := Now + (FTimeoutMS * TDMSec );

Result := '';


Repeat

// Setup events to wait for:
Events := [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak,
evCTS, evDSR, evError, evRLSD, evRx80Full];

// Wait until at least one event happens.
FComPort.WaitForEvent(
Events,
FStopEvent.Handle,
FTimeOutMS);

If Events = [] then // timeout
begin
If ARaise then
raise EArtTComPort.Create( 'Serial port reply timeout' )
end
else
begin
If evRxChar in Events then
begin
iCount := FComport.InputCount;
FComPort.ReadStr( S, iCount );
Result := Result + S;
end;
end;

until IsEndOfReplyOrTimeout( Result );


end;

关于multithreading - 如何发送字符串(串行端口),等待(超时)并捕获回复字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13868851/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com