如何在循环发送更多数据之前等待 COM 端口接收事件 [英] How to wait for COM port receive event before sending more data in a loop
问题描述
我正在使用旧的索尼爱立信手机编写和读取 AT 命令的小组件.向/从手机发送和写入完全没有问题,但是我希望能够暂停我的 SendATCmd 功能并等待 COM 端口组件通过通知事件通知我,然后再次恢复 SendATCmd 功能.
I'm working on a small component for writing and reading AT Commands using an old Sony Ericsson phone. Sending and writing to/from the phone is no problem at all, however I would like to be able to pause my SendATCmd function and wait for the COM Port component to notify me with a Notification Event, and then resume the SendATCmd function again.
场景:我想获取手机中 SMS 消息的计数.通常我只会告诉电话:嘿,你有多少条短信?手机会在通知事件中回复.都很好.
Scenario: I want to get the count of SMS messages in the phone. Normally I'd just tell the phone: Hey, how many SMS messages do you have? and the phone would reply in the notification event. Thats all good.
但我真正想做的是
if SendATCmd('CountSMS')>0 then
for 0 to SMSCount do
AddSMSToList;
SendATCmd 的代码如下所示:
The code for SendATCmd looks like this:
function TSE_Z1010.SendATCmd(Cmd: string): TATResult;
begin
fCOMPort.PutString(Cmd); //Sending AT command
//Here is where I would like to pause this function
//wait for the fCOMPort to notify me when data is available
//and then resume this function again.
result:=fTMPATResult;
end;
我尝试过使用 while 循环、暂停等,但除了一件事外,没有任何效果,那就是我将 ShowMessage 放在应该暂停的地方.我不知道 ShowMessage 在内部是如何工作的,但它似乎不会像 while-loop 和 pause 那样停止程序.
I've tried using a while-loop, pause, etc etc, but nothing's worked except for one thing, and that's when I put a ShowMessage where the pause should be. I don't know how ShowMessage works internally but it seems that it doesn't halt the program like while-loop and pause do.
=====================
====================
修复它.
我所要做的就是在uses子句中添加Forms,然后添加while fTMPATResult.Full=false do Application.ProcessMessages;在我想暂停程序的部分.
All I had to do was to add Forms in the uses clause, and then I added while fTMPATResult.Full=false do Application.ProcessMessages; in the part where I wanted to pause the procedure.
fTMPATResult"是组件内全局存储传入 COM 端口数据的变量.
"fTMPATResult" is the variable where the incoming COM Port data is stored, globally within the component.
推荐答案
虽然 AsyncPro 确实有一些解决方案(ontriggerdata),但它们是基于事件的,使代码难以阅读/理解.
While AsyncPro does have some solutions for this (ontriggerdata), they are event based and make code difficult to read/understand.
这里是带有 AsyncPro 的 SendAndWaitForResponse(就像 Remy 建议的那样):
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);
最好的解决方案是使用 comport 创建一个线程,这样您的 GUI 就不会被阻塞.我有几个使用 Asyncpro 生产的应用程序,它就像一个魅力......
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...
这篇关于如何在循环发送更多数据之前等待 COM 端口接收事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!