How to wait for COM port receive event before sending more data in a loop

江枫思渺然 提交于 2019-12-01 12:41:41

While AsyncPro does have some solutions for this (ontriggerdata), they are event based and make code difficult to read/understand.

here is SendAndWaitForResponse with AsyncPro (like Remy suggested):

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);

Best solution is to create a thread with the comport so your GUI won't be blocked. I have several applications in production with Asyncpro this way and it works like a charm...

Any time you need to call Application.ProcessMessages() manually, you need to rethink your code design. Doubly so when calling it in a loop.

I do not know how Asynch Pro works, but the Win32 API has a WaitCommEvent() function that does what you are asking for. You call that function to ask the serial port for notification of the desired event(s) and then you can use either WaitForOverlappedResult() or WaitForSingleObject() to wait for those events to actually occur, depending on whether the serial port is operating in overlapped mode or not. No message processing is needed. I would be surprised if Asynch Pro does not somehow expose that functionality.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!