boxmoe_header_banner_img

Hello! 欢迎来到悠悠畅享网!

文章导读

PHP 串口通信读取超时处理教程


avatar
作者 2025年8月22日 2

PHP 串口通信读取超时处理教程

本文旨在解决在使用 lepiaf/SerialPort 库进行 php 串口通信时,因读取串口数据无限循环等待分隔符而导致程序阻塞的问题。通过修改 read 方法,添加超时参数,实现更灵活的串口数据读取,避免程序因长时间等待而挂起,并提供相应的代码示例和注意事项,帮助开发者更好地处理串口通信中的超时情况。

在使用 PHP 进行串口通信时,经常会遇到需要等待串口数据的情况。lepiaf/SerialPort 是一个常用的 PHP 串口通信库,但其默认的 read 方法会无限循环等待分隔符,这可能导致程序阻塞,尤其是在没有数据输入或数据不完整的情况下。本文将介绍如何修改 lepiaf/SerialPort 库的 read 方法,添加超时参数,从而避免程序长时间等待,提高程序的健壮性。

修改 lepiaf/SerialPort 库

首先,找到 lepiaf/SerialPort/SerialPort.php 文件,并修改 read 方法。原始的 read 方法会一直循环读取串口数据,直到找到分隔符。我们需要在循环中添加超时判断,如果超过指定时间仍未找到分隔符,则返回 false。

修改后的 read 方法如下:

立即学习PHP免费学习笔记(深入)”;

public function read($maxElapsed = 'infinite') {     $this->ensuredeviceOpen();      $chars = [];     $timeout = $maxElapsed == 'infinite' ? 1.7976931348623E+308 : (microtime(true) + $maxElapsed);     do {         $char = fread($this->fd, 1);         if ($char === '') {             if (microtime(true) > $timeout) return false;             usleep(100);    //Why waste CPU?             continue;         }         $chars[] = $char;     } while ($char !== $this->getParser()->getSeparator());      return $this->getParser()->parse($chars); }

代码解释:

  • $maxElapsed: 新增的超时参数,用于指定最大等待时间,单位为秒。如果设置为 ‘infinite’,则表示无限等待。
  • $timeout: 根据 $maxElapsed 计算出的超时时间戳。
  • fread($this->fd, 1): 从串口读取一个字符。
  • if ($char === ”): 判断是否读取到字符。如果未读取到字符,则判断是否超时。
  • if (microtime(true) > $timeout) return false;: 判断是否超时。如果超时,则返回 false。
  • usleep(100);: 在每次循环中暂停 100 微秒,避免 CPU 占用过高。

使用修改后的 read 方法

修改 read 方法后,就可以在代码中使用超时参数了。

$data2 = $this->serialPort->read(15); if ($data2 === false) {     //Timeout occurred     //处理超时情况,例如:     $this->serialPort->write("C,STOPn"); // STOP vending     $aborted = true;     $this->alert("vending sequence stopped"); } elseif (Str::contains($data2, "Whatever I want to check for")) {     //String found     //处理找到指定字符串的情况 } else {     //Data received but string not found     //处理接收到数据但未找到指定字符串的情况 }

代码解释:

  • $this->serialPort->read(15): 调用 read 方法,并设置超时时间为 15 秒。
  • if ($data2 === false): 判断是否超时。如果超时,则执行相应的处理逻辑。
  • elseif (Str::contains($data2, “Whatever I want to check for”)): 判断是否找到指定字符串。如果找到,则执行相应的处理逻辑。
  • else: 处理接收到数据但未找到指定字符串的情况。

注意事项

  • 确保已经安装了 lepiaf/SerialPort 库。
  • 根据实际情况调整超时时间。
  • 在处理超时情况时,需要考虑程序的整体逻辑,例如是否需要重试、是否需要记录日志等。
  • 在循环中添加 usleep 可以有效降低 CPU 占用率。

总结

通过修改 lepiaf/SerialPort 库的 read 方法,添加超时参数,可以有效避免 PHP 串口通信程序因长时间等待而阻塞。这对于提高程序的健壮性和稳定性非常有帮助。在实际应用中,需要根据具体情况调整超时时间,并合理处理超时情况,以确保程序的正常运行。



评论(已关闭)

评论已关闭