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

标签 multithreading delphi function serial-port communication

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

我遇到了很多问题,并且尝试了很多解决方案......不幸的是,没有什么效果很好!

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

我尝试过 Asyncpro、Synaser 和 TComport。

是否可以有这样的功能:

SerialSendandReply(tx string here,timeout) 返回 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/

相关文章:

javascript - 为什么两个 if 语句在一个函数中不起作用?

java - 在生产者/消费者模式中使用多个生产者和消费者对java中的字符串进行排序有什么好处?

c# - 在后台加载一个窗口,直到告诉它显示

delphi - 如何清洗/验证字符串以将其分配给组件名称?

delphi - Windows 7 下打开-保存对话框的问题

delphi - 在delphi中的计算字段上使用locate函数

c - 程序不会终止或返回 scanf 函数错误

java - 多个客户端-Java中的服务器

java - 如何暂停 main()

javascript - 使用递归从数字中添加数字 - javascript