php串口通信编程问题

最近做个小项目,要远程控制一个水泵,编程只会一点儿php,正好方便远程控制。
开发环境 win7 ,一个usb转串口的转换器,淘宝上买的串口4路继电器板。
想最终整个atom的小板子加个u盘做系统,定制一个小linux+apache+php系统来做,硬件体积小,功耗低,应该可靠性比较高。
google了一下,看到大多都是用的php dio模块,我也用吧。
原来开发开发环境用的是 wamp server 2.1, 发现没有pecl dio模块,又google,发现 pecl4win.php.net当机了,郁闷。
又找,在 http://snaps.php.net/win32/找到了php5.2-win32-200808060430.zip和pecl5.2-win32-200808060430.zip这个是配套的。
要下班了,回家继续写!
继续,继续google,找到了个coreAMP,试试看,下载安装,包含2个php版本,5.2.17,和5.3.5,都没有扩展库,下载的php版本是 5.2.7,php版本不一样,
覆盖看看行不行,解压php5.2-win32-200808060430.zip覆盖coreamp的php5.2.17目录,解压
pecl5.2-win32-200808060430.zip到php5.2.17的ext目录,修改php.ini,改extension_dir = "C:\CoreAMP\server\php-5.2.17\ext"添加php_dio.dll扩展。开发环境配置完毕。
测试了一下,没问题。
程序开始,惨了,家里机器上没有代码啊。

回单位了,上代码:

  1. <?php
  2. /**************************************************************
  3. *rs232.php            控制4路串口继电器演示程序           *
  4. *  作者 tiger92665@gmail.com        2011.04   *
  5. **************************************************************
  6.   采用232协议通信,波特率9600,8个数据位,一个停止位,无校验位。
  7. MODE COM1 9600, n, 8, 1
  8. 计算机到继电器板的数据帧说明:
  9. 数据头: 0x55  (作为标识)
  10. 地址:0x01(一个继电器板默认为1)
  11. 操作类型: 0x00(查询当前各继电器状态)0x01(写入新值)
  12. 数据(四个字节) 每个字节代表一个继电器,共四个;
  13. 数据值1:继电器断开;数据值2:继电器吸合;数据值0:继电器无动作。
  14. 校验           一字节和校验 0x56
  15.  
  16. 继电器板到计算机的数据帧说明:
  17. 数据头: 0x22  (作为标识)
  18. 地址:0x01(单个继电器默认为1)
  19. 操作类型: 与计算机发来的操作类型一致
  20. 数据(四个字节)      每个字节代表一个继电器,共四个;
  21. 数据值1:继电器断开,数据值2:继电器吸合。
  22. 校验           一字节和校验(用来防止数据出错)
  23. 计算机发送指令表(部分):
  24.  
  25. "55 01 01 02 00 00 00 59"; //  吸合第1路继电器
  26. "55 01 01 00 02 00 00 59"; //  吸合第2路继电器
  27. "55 01 01 00 00 02 00 59"; // 吸合第3路继电器
  28. "55 01 01 00 00 00 02 59"; // 吸合第4路继电器
  29.  
  30. "55 01 01 01 00 00 00 58"; // 断开第1路继电器
  31. "55 01 01 00 01 00 00 58"; // 断开第2路继电器
  32. "55 01 01 00 00 01 00 58"; // 断开第3路继电器
  33. "55 01 01 00 00 00 01 58"; // 断开第4路继电器
  34.  
  35. 55 01 01 02 02 02 02 5F  吸合所有继电器
  36. 55 01 01 01 01 01 01 5B  断开所有继电器
  37.  
  38. "55 01 01 00 00 00 00 57";  查询当前继电器板的状态 */
  39. //定义被操作的窜口
  40. $com="com4";
  41. //定义串口数据
  42. //                                      k1  k2   k3   k4  校验位
  43. $k1on="\x55\x01\x01\x02\x00\x00\x00\x59";
  44. $k2on="\x55\x01\x01\x00\x02\x00\x00\x59";
  45. $k3on="\x55\x01\x01\x00\x00\x02\x00\x59";
  46. $k4on="\x55\x01\x01\x00\x00\x00\x02\x59";
  47.  
  48. $k1off="\x55\x01\x01\x01\x00\x00\x00\x58";
  49. $k2off="\x55\x01\x01\x00\x01\x00\x00\x58";
  50. $k3off="\x55\x01\x01\x00\x00\x01\x00\x58";
  51. $k4off="\x55\x01\x01\x00\x00\x00\x01\x58";
  52.  
  53. $kon="\x55\x01\x01\x02\x02\x02\x02\x5f";
  54. $koff="\x55\x01\x01\x01\x01\x01\x01\x5b";
  55. $kstatus="\x55\x01\x00\x00\x00\x00\x00\x56";
  56. //定义接受的get 命令
  57. $ops = array("k1on", "k2on", "k3on", "k4on",
  58.                         "k1off","k2off","k3off","k4off","kon","koff","kstatus");
  59. //串口操作开始                       
  60. if ( isset($_GET['op']) and in_array($_GET['op'],$ops ) )
  61. {       
  62.         $data=${$_GET['op']};               
  63.         set_time_limit(3);
  64.         //echo 'windows下设置窜口参数<br>';
  65.         exec("mode ".$com."BAUD=9600 PARITY=n DATA=8 STOP=1 odsr=off");
  66.        
  67.         //echo "打开端口$com<br>";
  68.         $f =  dio_open ($com, O_RDWR | O_NOCTTY | O_NONBLOCK);
  69.         if(!$f)
  70.         {
  71.                 die("Error when open $com");
  72.         }
  73.         //echo "向串口发送数据<br>".$data.'<br>';
  74.         dio_write ($f, $data);
  75.         //echo "接收数据<br>";
  76.         $str="";
  77.         for ($i = 0; $i <= 7; $i++)
  78.         {
  79.                 $str.=bin2hex(dio_read( $f,1));
  80.         }       
  81.         //echo $str;
  82.         $k1=$str[7];
  83.         $k2=$str[9];
  84.         $k3=$str[11];
  85.         $k4=$str[13];
  86.        
  87.         //echo "关闭端口<br>";       
  88.         dio_close($f);
  89.         //串口操作结束
  90.        
  91. //输出开始       
  92.  
  93. //简单控制界面       
  94. $output='串口继电器控制演示程序 2011年4月<br><br>
  95.         <a href="'.$_SERVER[’PHP_SELF’].'?op=k1on">k1开</a>
  96.         <a href="'. $_SERVER[’PHP_SELF’].'?op=k1off">k1关</a>
  97.         <a href="'.$_SERVER[’PHP_SELF’].'?op=k2on">k2开</a>
  98.         <a href="'. $_SERVER[’PHP_SELF’].'?op=k2off">k2关</a>
  99.         <a href="'.$_SERVER[’PHP_SELF’].'?op=k3on">k3开</a>
  100.         <a href="'. $_SERVER[’PHP_SELF’] .'?op=k3off">k3关</a>
  101.         <a href="'.$_SERVER[’PHP_SELF’].'?op=k4on">k4开</a>
  102.         <a href="'. $_SERVER[’PHP_SELF’] .'?op=k4off">k4关</a>       
  103.         <a href="'. $_SERVER[’PHP_SELF’] .'?op=kon">全开</a>
  104.         <a href="'. $_SERVER[’PHP_SELF’] .'?op=koff">全关</a>       
  105.         <a href="'. $_SERVER[’PHP_SELF’] .'?op=kstatus">查询</a>
  106.         <a href="'. $_SERVER[’PHP_SELF’] .'?op=kstatus&out=xml">XML格式查询</a>
  107.         <br><br>
  108.         开关状态 1关 2开<br><br>
  109.         <br>k1:'.$k1.'<br>
  110.         <br>k2:'.$k2.'<br>
  111.         <br>k2:'.$k3.'<br>
  112.         <br>k2:'.$k4.'<br>';               
  113.        
  114. echo $output;               
  115. }
  116. ?>

复制代码

我的问题在哪里呢?
必须要用串口控制程序初始化一下窜口,我的php程序才能正常工作。不明白,google了N次,也google不出来。
自己分析是用win自己的mode命令设置的参数还不完整,可是要怎么设置呢?自己cmd下用mode测试,结果居然蓝屏死机了。
哪位大侠能给个解决方法?

================================================================================================================================

 

再研究,google,发现不用php 的dio 也成。别人的代码如下

  1. <?php
  2. // HOW TO USE PHP TO WRITE TO YOUR SERIAL PORT: TWO METHODS
  3. $serproxy=true;
  4. if ($serproxy) {
  5.     // Use this code in conjunction with SERPROXY.EXE
  6.     // (http://www.lspace.nildram.co.uk/freeware.html)
  7.     // which converts a Serial stream to a TCP/IP stream
  8.     $fp = fsockopen ("localhost", 5331, $errno, $errstr, 30);
  9.     if (!$fp) {
  10.         echo "$errstr ($errno)";
  11.     } else {
  12.         $e = chr(27);
  13.         $string  = $e . "A" . $e . "H300";
  14.         $string .= $e . "V100" . $e . "XL1SATO";
  15.         $string .= $e . "Q1" . $e . "Z";
  16.         echo $string;
  17.         fputs ($fp, $string );
  18.         fclose ($fp);
  19.     }
  20. } elseif ($com1) {
  21.     // Use this code to write directly to the COM1 serial port
  22.     // First, you want to set the mode of the port. You need to set
  23.     // it only once; it will remain the same until you reboot.
  24.     // Note: the backticks on the following line will execute the
  25.     // DOS 'mode' command from within PHP
  26.     `mode com1: BAUD=9600 PARITY=N data=8 stop=1 xon=off`;
  27.     $fp = fopen ("COM1:", "w+");
  28.     if (!$fp) {
  29.         echo "Uh-oh. Port not opened.";
  30.     } else {
  31.         $e = chr(27);
  32.         $string  = $e . "A" . $e . "H300";
  33.         $string .= $e . "V100" . $e . "XL1SATO";
  34.         $string .= $e . "Q1" . $e . "Z";
  35.         echo $string;
  36.         fputs ($fp, $string );
  37.         fclose ($fp);
  38.     }
  39. }
  40. ?>

复制代码

这样也成?不用dio的话,配置服务器就方便多了。改吧!

  1. <?php
  2. /**************************************************************
  3. *rs232new.php            控制4路串口继电器程序                          *
  4. *  作者 tiger92665@gmail.com        2011.04                  *
  5. **************************************************************/
  6.  
  7. /*  采用232协议通信,波特率9600,8个数据位,一个停止位,无校验位。
  8. MODE COM1 9600, n, 8, 1
  9. 计算机到继电器板的数据帧说明:
  10. 数据头: 0x55  (作为标识)
  11. 地址:0x01(一个继电器板默认为1)
  12. 操作类型: 0x00(查询当前各继电器状态)0x01(写入新值)
  13. 数据(四个字节) 每个字节代表一个继电器,共四个;
  14. 数据值1:继电器断开;数据值2:继电器吸合;数据值0:继电器无动作。
  15. 校验           一字节和校验 0x56
  16.  
  17. 继电器板到计算机的数据帧说明:
  18. 数据头: 0x22  (作为标识)
  19. 地址:0x01(单个继电器默认为1)
  20. 操作类型: 与计算机发来的操作类型一致
  21. 数据(四个字节)      每个字节代表一个继电器,共四个;
  22. 数据值1:继电器断开,数据值2:继电器吸合。
  23. 校验           一字节和校验(用来防止数据出错)
  24. 计算机发送指令表(部分):
  25. //                                 k1 k2 k3 k4        校验位
  26. "55 01 01 02 00 00 00 59"; //  吸合第1路继电器
  27. "55 01 01 00 02 00 00 59"; //  吸合第2路继电器
  28. "55 01 01 00 00 02 00 59"; // 吸合第3路继电器
  29. "55 01 01 00 00 00 02 59"; // 吸合第4路继电器
  30.  
  31. "55 01 01 01 00 00 00 58"; // 断开第1路继电器
  32. "55 01 01 00 01 00 00 58"; // 断开第2路继电器
  33. "55 01 01 00 00 01 00 58"; // 断开第3路继电器
  34. "55 01 01 00 00 00 01 58"; // 断开第4路继电器
  35.  
  36. 55 01 01 02 02 02 02 5F  吸合所有继电器
  37. 55 01 01 01 01 01 01 5B  断开所有继电器
  38.  
  39. "55 01 01 00 00 00 00 57";  查询当前继电器板的状态 */
  40. //定义被操作的窜口
  41. $com="com4";
  42. //定义串口数据
  43. $k1on="\x55\x01\x01\x02\x00\x00\x00\x59";
  44. $k2on="\x55\x01\x01\x00\x02\x00\x00\x59";
  45. $k3on="\x55\x01\x01\x00\x00\x02\x00\x59";
  46. $k4on="\x55\x01\x01\x00\x00\x00\x02\x59";
  47.  
  48. $k1off="\x55\x01\x01\x01\x00\x00\x00\x58";
  49. $k2off="\x55\x01\x01\x00\x01\x00\x00\x58";
  50. $k3off="\x55\x01\x01\x00\x00\x01\x00\x58";
  51. $k4off="\x55\x01\x01\x00\x00\x00\x01\x58";
  52.  
  53. $kon="\x55\x01\x01\x02\x02\x02\x02\x5f";
  54. $koff="\x55\x01\x01\x01\x01\x01\x01\x5b";
  55. $kstatus="\x55\x01\x00\x00\x00\x00\x00\x56";
  56. //定义接受的get 命令
  57. $op = array("k1on", "k2on", "k3on", "k4on",
  58.                         "k1off","k2off","k3off","k4off","kon","koff","kstatus");
  59. //串口操作开始                       
  60. if ( isset($_GET['op']) and in_array($_GET['op'],$op ) )
  61. {       
  62.         $data=${$_GET['op']};               
  63.         set_time_limit(3);
  64.         //echo 'windows下设置窜口参数<br>';
  65.         exec("mode ".$com."BAUD=9600 PARITY=n DATA=8 STOP=1 odsr=off");
  66.        
  67.         //echo "打开端口$com<br>";
  68.         $f =  fopen ($com, 'w+');
  69.         if(!$f)
  70.         {
  71.                 die("Error when open $com");
  72.         }
  73.         //echo "向串口发送数据<br>".$data.'<br>';
  74.         fwrite ($f, $data);
  75.         //echo "接收数据<br>";
  76.         $str="";
  77.         for ($i = 0; $i <= 7; $i++)
  78.         {
  79.                 $str.=bin2hex(fread( $f,1));
  80.         }       
  81.         //echo $str;
  82.         $k1=$str[7];
  83.         $k2=$str[9];
  84.         $k3=$str[11];
  85.         $k4=$str[13];
  86.        
  87.         //echo "关闭端口<br>";       
  88.         fclose($f);
  89.         //串口操作结束
  90.        
  91.         //输出开始       
  92.         if ( isset($_GET['out']) and ($_GET['out']=="xml" ) )
  93.         {
  94.         //xml输出
  95.                 $output        =
  96.                 '<?xml version="1.0" ?>
  97.                 <k1>'.$k1.'</k1>
  98.                 <k2>'.$k2.'</k2>
  99.                 <k3>'.$k3.'</k3>
  100.                 <k4>'.$k4.'</k4>';
  101.         }
  102.         else
  103.         {
  104.         //简单控制界面       
  105.                 $output='串口继电器控制演示程序 2011年4月<br><br>
  106.                                 <a href="'.$_SERVER[’PHP_SELF’].'?op=k1on">k1开</a>
  107.                                 <a href="'. $_SERVER[’PHP_SELF’].'?op=k1off">k1关</a>
  108.                                 <a href="'.$_SERVER[’PHP_SELF’].'?op=k2on">k2开</a>
  109.                                 <a href="'. $_SERVER[’PHP_SELF’].'?op=k2off">k2关</a>
  110.                                 <a href="'.$_SERVER[’PHP_SELF’].'?op=k3on">k3开</a>
  111.                                 <a href="'. $_SERVER[’PHP_SELF’] .'?op=k3off">k3关</a>
  112.                                 <a href="'.$_SERVER[’PHP_SELF’].'?op=k4on">k4开</a>
  113.                                 <a href="'. $_SERVER[’PHP_SELF’] .'?op=k4off">k4关</a>       
  114.                                 <a href="'. $_SERVER[’PHP_SELF’] .'?op=kon">全开</a>
  115.                                 <a href="'. $_SERVER[’PHP_SELF’] .'?op=koff">全关</a>       
  116.                                 <a href="'. $_SERVER[’PHP_SELF’] .'?op=kstatus">查询</a>
  117.                                 <a href="'. $_SERVER[’PHP_SELF’] .'?op=kstatus&out=xml">XML格式查询</a>
  118.                                 <br><br>
  119.                                 开关状态 1关 2开<br><br>
  120.                                 <br>k1:'.$k1.'<br>
  121.                                 <br>k2:'.$k2.'<br>
  122.                                 <br>k2:'.$k3.'<br>
  123.                                 <br>k2:'.$k4.'<br>';               
  124.         }
  125.         echo $output;               
  126. }
  127. ?>

复制代码

测试也成功了,可以控制继电器动作!不过还是那个问题,要用串口程序初始化串口!

=======================================================================================================

你买的买的串口4路继电器板有DEMO程序给你吗?

如果有建议将DEMO改成PHP可调用交互的exe文件,通过exec 执行这类DELPHI或VB等写的程序和串口通信,相对PHP直接通讯要稳定的多。

我原先的一些PHP读写串口的应用都是通过购买的相应硬件厂方提供的DEMO改写的程序作通讯中介的。

-------------------------

有的,是vb做的,是调用 一个mscomm32.ocx控件实现的,不过好像与win7不兼容,它的程序跑不起来。
程序最终要到linux下运行,所以就不能用你的方法啦。

-----------------------------

NB啊,也有过类似的经历,找了一些PHP的串口资料,后面也没有搞到,倒是用了网络转COM口代替了.NPORT类产品.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人间四月天美丽春色

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值