使用 Perl 或 PHP 在 Linux 上通过 USB 读写串行设备
我在 Linux 上读取串行设备时遇到问题。这个问题很奇怪,我无法确定原因。
我正在使用 PHP 打开 /dev/ttyUSB0 文件
并开始根据设备的协议与设备进行通信。很多时候我遇到了PHP脚本等待设备响应的情况。当我并行运行一个 Perl 脚本时,它应该执行相同的操作,它向同一设备发送了一个请求,并且据称在没有得到响应的情况下退出。然后我看到PHP脚本得到了响应(只有在Perl脚本发送请求之后)。
我在尝试用PHP读取Arduino时遇到了类似的问题。 PHP 没有从端口得到响应,但 Arduino IDE 的串行监视器打印了它。
我认为我在这里遗漏了有关 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;
}
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.
I'm opening the /dev/ttyUSB0 file
with 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).
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.
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?
$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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在我的维基上查看这两篇文章。第一篇文章介绍了如何在设备节点上设置有用的权限。第二篇文章是打印出远程发送到PC的所有数据的示例。虽然是为 Arduino 编写的,但它很容易移植用于其他用途。
使用
lsof
您可以找出当前哪个程序正在使用该端口:lsof | grep /dev/ttyUSB0
cat_ttyUS 19182 jhendrix 3u CHR 188,0 0t0 14519955 /dev/ttyUSB0
使用 stty 命令,您不会锁定端口以供独占使用。
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.
Using
lsof
you can find out which program is currently using the port: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.