在 Windows 上使用 PHP 进行串行通信

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/627965/
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-24 23:18:43  来源:igfitidea点击:

Serial comm with PHP on Windows

phpserial-portcommunication

提问by syaz

I am looking for a way to communicate with RS232 serial COM port on windows. I have found 2 solutions on the net, onewhich is not totally free (introduces deliberate delays on the function) and anotherwith limited capability on Windows. The latter can only write to a COM port on Windows, not read.

我正在寻找一种与 Windows 上的 RS232 串行 COM 端口进行通信的方法。我在网上找到了 2 个解决方案,一个不是完全免费的(在功能上引入了故意延迟),另一个在 Windows上的功能有限。后者只能写入 Windows 上的 COM 端口,不能读取。

I can't look at the code of the first solution since it is compiled into a .dll (makes sense, otherwise people can just edit the delay and not purchase it...) and the second one seems only to use fopen() to open the port and later fwrite() to it for writing, just like one would do to a stream. But apparently freading it returns nothing.

我无法查看第一个解决方案的代码,因为它被编译成 .dll(有道理,否则人们只能编辑延迟而不购买它......)而第二个似乎只使用 fopen()打开端口,然后 fwrite() 用于写入,就像对流所做的一样。但显然害怕它没有任何回报。

I know it's possible as the first solution did it, although it does require Apache to use php-cgi module instead of php5module.

我知道这是可能的,因为第一个解决方案做到了,尽管它确实需要 Apache 使用 php-cgi 模块而不是 php5module。

Any ideas?

有任何想法吗?

回答by Dustin Oprea

Every solution above is either inefficient or too much work.

上面的每个解决方案要么效率低下,要么工作量太大。

You can just use the PHP-DIO library(dio_fcntl, dio_open, dio_read, dio_write, dio_seek, ...). It's also in the PHP manual's entry for DIO:

您可以只使用PHP-DIO 库(dio_fcntl、dio_open、dio_read、dio_write、dio_seek、...)。它也在PHP 手册的 DIO 条目中

This PECL package isn't available by default. To get it for Windows if you have PHP 5.2.x greater than 5.2.6, you can download it as part of a ZIP:

默认情况下,此 PECL 包不可用。如果您的 PHP 5.2.x 高于 5.2.6,要在 Windows 上获取它,您可以将其作为 ZIP 的一部分下载:

Both of these links were found in http://www.deveblog.com/index.php/download-pecl-extensions-for-windows/

这两个链接都可以在http://www.deveblog.com/index.php/download-pecl-extensions-for-windows/中找到

Here is the build from Linux, just get it and do the phpize/configure/make/make install thing.

这是来自 Linux 的构建,只需获取它并执行 phpize/configure/make/make 安装操作。

I don't know whether it should be used in an Apache session, but go for it.

我不知道是否应该在 Apache 会话中使用它,但还是去做吧。

回答by syaz

You need to set up the com port using a DOS-like command.

您需要使用类似 DOS 的命令设置 com 端口。

For example, the following line executes the command through php:

比如下面这行通过php执行命令:

$output = `mode COM1: BAUD=115200 PARITY=N data=8 stop=1 XON=off TO=on`;

To display the results you can use:

要显示结果,您可以使用:

echo "$output"; 

Create the resource id:

创建资源 ID:

$fp = fopen('COM1', 'r+');

if (!$fp)
{
      echo "Port not accessible";
}
else
{
     echo "Port COM1 opened successfully";
}

Write to port:

写入端口:

$writtenBytes = fputs($fp, "Hello");

echo"Bytes written to port: $writtenBytes";

Read from port:

从端口读取:

$buffer = fgets($fp);

echo "Read from buffer: $buffer";

Maybe someone can help me with the fgetsproblem. It stacks there for exactly one minute if TO=on, or stacks there forever if TO=off. It seems to be a "MODE COM" option so maybe a DOS expert can help.

也许有人可以帮助我解决这个fgets问题。如果TO=on,它会在那里堆叠一分钟,或者如果,它会一直堆叠在那里TO=off。这似乎是一个“ MODE COM”选项,所以也许 DOS 专家可以提供帮助。

Perhaps instead of fgets, one should use fgetc, since fgetscapture through to the newline, while fgetccaptures a single character. If a new line isn't encountered, it may block until there is one or until the buffer is flushed. The one minute delay may be windows flushing its buffer on an interval.

也许fgets应该使用代替fgetc,因为fgets捕获到newline,而fgetc捕获单个字符。如果没有遇到新行,它可能会阻塞,直到有新行或缓冲区被刷新为止。一分钟的延迟可能是窗口每隔一段时间刷新其缓冲区。

回答by SoapBox

The easiest way to tackle this would be to write a program in another language (such as C++) and then execute it from your php script with system(). Doing Comm I/O in C++ is trivial.

解决这个问题的最简单方法是用另一种语言(例如 C++)编写程序,然后使用system(). 在 C++ 中执行 Comm I/O 是微不足道的。

This assumes you have enough access to the server to configure it to allow the executable to be run by php, etc.

这假设您对服务器有足够的访问权限来配置它以允许可执行文件由 php 等运行。

回答by lpfavreau

Another possible way would be to use the Win32 API through something like w32api_register_function()or ffiand then use serial communications callsto get it to work under Windows.

另一种可能的方法是通过诸如w32api_register_function()ffi 之类的东西使用 Win32 API ,然后使用串行通信调用使其在 Windows 下工作。

回答by Michael

I had the same problem and already considered writing my own php extension when I came across this solution which is popular with Arduino developers - 'serproxy' (found it at many places, ie. http://www.lspace.nildram.co.uk/freeware.html) sets up a tcp stack to/from the serial ports and allowed me to use the php socket functions to communicate with it.

当我遇到这个在 Arduino 开发人员中很流行的解决方案时,我遇到了同样的问题,并且已经考虑编写自己的 php 扩展程序 - 'serproxy'(在很多地方都可以找到,即http://www.lspace.nildram.co. uk/freeware.html) 设置了一个到/从串行端口的 tcp 堆栈,并允许我使用 php 套接字函数与其进行通信。

回答by adi

If you want to deal with sms using com port then here is the most famous php serial communication class by Rémy Sanchezwith google sample code. Here is a threadwhich includes that topic.

如果您想使用 com 端口处理 sms,那么这里是Rémy Sanchez最著名的php 串行通信类google 示例代码这是一个包含该主题的线程

回答by Tracker1

Another option is to use an object via ActiveX on windows. There are several, mostly commercial serial objects for COM on windows. You can also expose a .Net based object and register it for COM use as well. Of course, this does presume you have control on the server to register a COM control, as you would need a serial interface.

另一种选择是通过 Windows 上的 ActiveX 使用对象。有几个,主要是用于 Windows 上的 COM 的商业串行对象。您还可以公开基于 .Net 的对象并将其注册以供 COM 使用。当然,这确实假设您可以控制服务器以注册 COM 控件,因为您需要串行接口。

Another issue is resource contention if this is for use via the Web. If this is for a serial printer, for instance, then a print queue manager would be your best option over direct communication.

另一个问题是资源争用,如果这是通过 Web 使用的话。例如,如果这是用于串行打印机,那么打印队列管理器将是直接通信的最佳选择。

回答by RobertoFRey

I used the solution of David Refoua and Giorgos Pap with some modifications to connect with Arduino UNO. In the PC side, I have an AJAX to receive the measurements from Arduino and show them in a form. Now I am trying to update, programmatically, the COM port (in this case, COM3),

我使用了 David Refoua 和 Giorgos Pap 的解决方案,并进行了一些修改以连接 Arduino UNO。在 PC 端,我有一个 AJAX 来接收来自 Arduino 的测量值并以表格形式显示它们。现在我正在尝试以编程方式更新 COM 端口(在本例中为 COM3),

<?php
$output = exec("mode COM2: BAUD=115200 PARITY=N data=8 stop=1 XON=off TO=on dtr=off odsr=off octs=off rts=on idsr=off");
$fp = fopen("COM2", "r+");
if (!$fp)
{
  exit("Unable to establish a connection");
}
// RX form PC**************
$t = $_POST['text1'];
// TX to Arduino****************
$writtenBytes = fputs($fp, $t);
sleep(1); 
// RX from Arduino**************
$j=0;
$dataset1 = [];
while(!$buffer=stream_get_line($fp,400,"\n")) { 1; }
// TX to PC***************
$piecesa = explode(",", $buffer);
foreach ($piecesa as $value) {  
    $dataset1[$j] = $value;
    $j++;
}
$myJSON = json_encode($dataset1);
echo $myJSON;
fclose($fp);
?>

The program is working very well with a short delay, around 8 sec. maximum. This is Windows OS.

该程序运行良好,延迟很短,大约 8 秒。最大值。这是 Windows 操作系统。