• 常用
  • 百度
  • google
  • 站内搜索

数码

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

  • 更新日期:2025-11-29
  • 查看次数:4782
PHP串口通信读取超时处理教程:当使用PHP进行串口通信时,超时处理是确保程序稳定性和数据完整性的重要步骤。教程中介绍了如何设置超时时间、检测超时事件以及处理超时情况。通过合理配置串口通信参数和设置超时时间,可以避免因通信延迟或设备故障导致的程序卡顿或数据丢失。提供了示例代码和常见问题解答,帮助开发者更好地理解和应用超时处理技术。

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

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

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

修改 lepiaf/SerialPort 库

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

修改后的 read 方法如下:

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,STOP\n"); // 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 串口通信程序因长时间等待而阻塞。这对于提高程序的健壮性和稳定性非常有帮助。在实际应用中,需要根据具体情况调整超时时间,并合理处理超时情况,以确保程序的正常运行。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

imtoken下载 im钱包 imtoken imtoken 快连官网 imtoken imtoken imtoken imtoken imtoken wallet imtoken imtoken官网 imtoken钱包 imtoken下载 imtoken官网 imtoken钱包 imtoken安卓下载 imtoken下载 imtoken官方下载 imtoken官网 imtoken安卓下载 imtoken下载 imtoken下载 imtoken imtoken imtoken imtoken imtoken imtoken imtoken imtoken imtoken bitget wallet telegram下载 quickq VPN trust wallet v2rayn imtoken