没有用户输入,从串口读取iis不稳定

Maw*_*awg 2 delphi serial-port

使用Delphi 7我正在从串口读取.

读取总是在写入之前触发h/w从传感器测量并写入一些内容供我阅读(并且总有一些东西需要阅读).

我有两种可能性:手动输入命令并单击按钮将其写入串行端口(读取型号或f/w版本等)或单击按钮循环读取测量值,直到按下停止按钮.这两个都使用相同的内部函数,因此代码看起来像这样:

WriteSerial('?model');
SerialData := ReadSerial();  // returns string
WriteSerial('?fw');
SerialData := ReadSerial();
Run Code Online (Sandbox Code Playgroud)

while stopButtonNotPressed do
begin
  WriteSerial('?data');
  SerialData := ReadSerial();
  Memo1.Lines.Add(SerialData );
end;
Run Code Online (Sandbox Code Playgroud)

第一个变体(手动输入命令和按下按钮)总是成功的,无论我输入命令的速度有多快或多慢(按住按钮重复),第二个变量在哪里

pass
fail
pass
pass
fail
pass
pass
fail
... add infinitum
Run Code Online (Sandbox Code Playgroud)

添加对sleep的调用什么都不产生,但是试图调试,我发现如果我MsgDialog, 'Please close this dialog...', mtInfo, [mrOK]);在循环中添加一个模态对话框,那么它就不再失败了.

现在,它看起来不像时间(否则肯定添加Sleep(2000);到循环将使它通过&不,所以为什么按主窗体上的按钮或模态对话框导致它成功?

顺便说一下,h/w用户指南没有提到CTS/RTS,唯一的代码示例也没有提供.

注意:如果我?data反复手动输入,它永远不会失败......

有任何想法吗?

Cos*_*und 5

您的串行设备需要时间来做出反应,因此显然您需要休息一下才能赶上设备.当您使用键盘按下按钮时,您需要提供所需的制动器,因为键盘重复速度并不快.

正如你所说Sleep(2000)应该提供足够的"休息",但还有两个潜在的问题你需要照顾:

  • 串口通信不需要缓冲:Sleep(2000)可能太长了!
  • 您正在使用的串行库可能正在使用Windows消息来处理传入的字节.Sleep()禁止消息泵,因此不再有消息传递给您的应用程序

尝试使用以下内容"休眠":

procedure BusyWait(ms: Cardinal);
var StopAt: TDateTime;
begin
  StopAt := Now + EncodeTime(0, 0, ms div 1000, ms mod 1000);
  while StopAt > Now do
  begin
   Application.ProcessMessages;
   Sleep(50); // per Micha? Niklas's suggestion, to keep the CPU from reaching 100%
  end;
end;
Run Code Online (Sandbox Code Playgroud)

此例程将等待,但它将保持消息泵的运行,允许您的串行库接收消息.如果这是问题......

  • 我会在循环体中添加"Sleep(50)".这样就可以处理消息,并且不会以100%的速度使用CPU. (3认同)