使用 perl 或 PHP 在 Linux 上通过 USB 读写串行设备

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5014451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:52:43  来源:igfitidea点击:

Reading and writing to/from serial device via USB on Linux with perl or PHP

phplinuxserial-portusb

提问by MeLight

I'm having a problem reading from a serial device on Linux. The problem is rather weird, and I wasn't able to nail down the causes.

我在 Linux 上从串行设备读取时遇到问题。这个问题很奇怪,我无法确定原因。

I'm opening the /dev/ttyUSB0 filewith PHP and beginning to communicate with the device according to the device's protocol. Many times I encountered a situation where the PHP script waits for the device to respond. When I ran a Perl script in parallel which supposed to do the same it sent a request to the same device, and quit supposedly without getting a response. Then I saw that the PHP script got the response (only after the Perl script sent a request).

我正在/dev/ttyUSB0 file用 PHP打开并开始根据设备的协议与设备通信。很多时候我遇到过PHP脚本等待设备响应的情况。当我并行运行一个 Perl 脚本时,它应该做同样的事情,它向同一个设备发送一个请求,并在没有得到响应的情况下退出。然后我看到PHP脚本得到了响应(只有在Perl脚本发送请求之后)。

I encountered a similar matter when trying to read Arduino with PHP. The PHP got no response from the port, but Arduino IDE's Serial Monitor printed it.

我在尝试用 PHP 读取 Arduino 时遇到了类似的问题。PHP 没有收到来自端口的响应,但 Arduino IDE 的串行监视器打印了它。

I think I'm missing a crucial thing about Linux files and USB ports here. What might be the problem? How can I tell which programs use the port/file?

我想我在这里遗漏了一个关于 Linux 文件和 USB 端口的关键信息。可能是什么问题?我如何知道哪些程序使用了端口/文件?

    $usb = 'ttyUSB0';        
    `stty -F /dev/$usb 9600`;
    `stty -F /dev/$usb -parity`;
    `stty -F /dev/$usb cs8`;
    `stty -F /dev/$usb -cstopb`;
    $f = fopen("/dev/$usb", "r+");
    if(!$f) {
        echo "error opening file\n";
        exit;
    }

    statusRequest($f);
    sleep(1);
    $c = readPort($f);
    echo "$c\n";

function statusRequest($port) {
    $data = "request";
    fwrite($port, $data);
    fflush($port);
}

function readPort($port) {
    $read = 1;
    $c = '';
    while($read > 0) {
        $bytesr = unpack("h*", fread($port, 1));
        $c .= $bytesr[1];
        //echo $bytesr[1];
        if($bytesr[1] == 'ff') {
            $read = 0;
        }
    }    
    return $c;
}

回答by jippie

Check these two articles on my wiki. The first article describes how to set useful permissions on the device node. The second article is an example that prints out all data that the remote sends to the PC. Although written for Arduino it is easily ported for other uses.

在我的维基上查看这两篇文章。第一篇文章介绍了如何在设备节点上设置有用的权限。第二篇文章是打印出远程发送到PC的所有数据的示例。虽然是为 Arduino 编写的,但它很容易移植到其他用途。

Using lsofyou can find out which program is currently using the port:

使用lsof您可以找出当前正在使用该端口的程序:

lsof | grep /dev/ttyUSB0 cat_ttyUS 19182 jhendrix 3u CHR 188,0 0t0 14519955 /dev/ttyUSB0

lsof | grep /dev/ttyUSB0 cat_ttyUS 19182 jhendrix 3u CHR 188,0 0t0 14519955 /dev/ttyUSB0

With the stty commands you don't lock the port for exclusive use.

使用 stty 命令,您不会锁定端口以供独占使用。