用 PHP 寫 RS232 串列通訊程式

十月 2nd, 2007

相信經常在翻 PHP 手冊的人應該都有察覺,PHP 不只是可以用來開發網頁程式而已,很多其他語言能完成的工作 PHP 也都做的到,例如透過 PHP 的 Direct IO Functions 就可以對 Serial port 溝通,而且可以在 Windows 下執行,一般在 Windows 要實做 com port 通訊程式,大多是透過像 VB/VC++/C++ Builder 這類程式所提供的元件來撰寫,不過用 PHP 就可以很快實做出一般的功能囉!

在開始之前要先讓 PHP 支援 dio 才行,5.1.0 版之後已經將 dio 移至 PECL 了,可以到 PHP 官網下載編譯好的 PECL,解壓縮後將裡面的 php_dio.dll 放到 PHP 目錄的 ext 底下,接著修改 php.ini 加入 extension=php_dio.dll 即可。

在 Windows 底下讀取 COM1 的例子:


<?php
exec('mode COM1: baud=19200 data=8 stop=1 parity=n');
$fd = dio_open('COM1:', O_RDWR);
while (1) {
    $data = dio_read($fd, 1);
    if ($data) {
        echo $data;
    }
}
dio_close($fd);
?>

寫法跟在 Linux 用 C 寫 serial 通訊程式差不多,其中 mode 是 Windows 命令列一個設定 serial port 組態的工具(類似 Linux 的 stty),可以打 mode /? 看詳細說明,設定好傳輸率等,接著用 dio_open 開啟裝置,然後就可以做存取的動作囉!

※ 2009/04/10 補充:
有不少人看了這篇之後,問我要怎麼用 PHP 讀取 GPS 資料。
在這邊要跟各位補充的是,如果您想要用瀏覽器在網頁執行 PHP,然後去讀取 GPS,這的確可以抓到資料,但其實是存在很多問題的,因為 Web 架構並不適合應用在這類有「持續連接」行為的地方,所以有可能發生 timeout、資源佔用、搶奪,嚴重的話會導致伺服器 crash。

但是如果一定要用 PHP 實作,建議應該是利用 command line 的方式執行,在背景專門負責抓 GPS 資料 ,並且將座標資料存入檔案或資料庫,然後網頁再去存取座標資料,如此一來便不會影響到 Web 運作。

PHP, 程式筆記 ,

  1. CHRIS
    十一月 11th, 2008 at 02:06 | #1

    我也是發生權限問題阿?不過我是在DIO_OPEN()底下~是不是VISTA還要修改哪邊阿?

  2. 十一月 11th, 2008 at 09:18 | #2

    Chris:
    試了一下在 Vista 也是 ok 的。
    會出現 Permission denied 大多是 port 被佔用無法釋放,
    例如 PHP 在執行期間被強制停止或關閉,這時 port 就會被 block 住,
    必須停止 Web server 才會釋放。
    所以建議先用 Access Port 之類的測試工具去確認您的設備如何溝通運作,再來寫程式可以減少很多問題。

  3. max
    十二月 10th, 2008 at 18:16 | #3

    請問一下要是要寫入一個字元到RS232裝置裡讓裝置可以啟動是要該如何寫呢?
    我是這樣寫(寫入D這一個字元裝置才會啟動)
    $data="D";
    dio_write($fd,$data);
    但是這一行程式會跟我說無法寫入~這樣的訊息給我
    warning: dio_write: cannot write data to file descriptor 3 , No space left on device in
    我有試過了dio_open這是OK的
    就卡再這裡沒辦法寫入一個字給裝置啟動不了
    希望您可以幫幫我~謝謝了

  4. focus
    一月 22nd, 2009 at 15:52 | #4

    謝謝版主. 在多人共同使用的情況下會搶COM port. 可用以下open方法避免:
    ...
    error_reporting(0);
    while (1) {
    $fd = dio_open('COM3:', O_RDWR | O_NOCTTY | O_NONBLOCK) ;
    if ($fd) break;
    // echo(".");
    sleep(1);
    }
    error_reporting(E_ALL);
    ...

  5. air
    二月 5th, 2009 at 18:39 | #5

    請問如果linux
    要怎麼改??

  6. 二月 6th, 2009 at 22:15 | #6

    @air
    確定已經掛上 DIO 模組後,可以參考官網手冊這篇底下的範例:
    http://tw2.php.net/manual/en/function.dio-tcsetattr.php

  7. station2
    四月 10th, 2009 at 10:12 | #7

    請問大大一下
    1.如果出現Fatal error: Call to undefined function dio_open() in C:\AppServ\www\rs232.php on line 13
    這種錯誤是不是表示我PECL那邊沒設定好呢?
    2.還有在php.ini裡面放的extension=php_dio.dll是要放在那堆extension裏面嗎?前面也要加;號嗎?
    3.可以麻煩大大解釋一下exec設定值以外的程式嗎?

    非常謝謝大大了T.T小弟為了能用php抓gps找了2個禮拜的方法了...麻煩你了T.T

  8. 四月 10th, 2009 at 22:21 | #8

    @station2
    1. 應該是 dio 沒有正確載入所以找不到 function,PECL 和 PHP 版本要對應,不能差太多,例如 PHP 5.2.x 要搭配 5.2.x PECL,否則也會發生無法載入情形。
    2. 是的,放在 ext 裡面,前面不要分號。
    3. Device open 之後就可以對其存取(read、write...),範例中是持續由裝置讀取1個字元,有讀取到東西就直接印出來。所以像是 GPS 應該可以讀到資料,但是如果要對資料做處理是不會這樣寫的^^"
    我當初學習是參考這篇教學,裡面寫得很完整。

Comment pages
  1. 十一月 25th, 2009 at 10:51 | #1