syaz
syaz

Reputation: 2679

Serial comm with PHP on Windows

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

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.

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

Any ideas?

Upvotes: 11

Views: 54129

Answers (9)

The biggest problem is to read the port. And it doesn't matter which method it is done, stream_get_line(), fgets() or dio_read() - they all work great.

Actually the problem is that at this point the code "hangs forever" or "hangs for a minute" depending on "xon" or "to".

According to several experiments, this happens when there is no data, as the usual terminal php does not work, and if there is no incoming data, it freezes on reading.

This can be avoided, as in the example above, after sending data to the port, execute sleep(time) to wait until the data to be read is definitely there, in which case it will be read and returned without any delay.

Upvotes: 1

RobertoFRey
RobertoFRey

Reputation: 744

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),

<?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.

Upvotes: 0

Giorgos Pap
Giorgos Pap

Reputation:

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

For example, the following line executes the command through 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:

$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 fgets problem. 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.

Perhaps instead of fgets, one should use fgetc, since fgets capture through to the newline, while fgetc captures 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.

Upvotes: 6

Dustin Oprea
Dustin Oprea

Reputation: 10276

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:

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:

Both of these links were found in 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.

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

Upvotes: 15

Adil
Adil

Reputation: 22431

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

Upvotes: 1

Michael
Michael

Reputation: 379

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.

Upvotes: 3

Tracker1
Tracker1

Reputation: 19344

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.

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.

Upvotes: 1

lpfavreau
lpfavreau

Reputation: 13211

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

Upvotes: 3

SoapBox
SoapBox

Reputation: 20609

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.

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

Upvotes: 5

Related Questions