原帖地址 : http://bbs.chinaunix.net/thread-2306104-1-1.html
最近做个小项目,要远程控制一个水泵,编程只会一点儿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扩展。开发环境配置完毕。
测试了一下,没问题。
程序开始,惨了,家里机器上没有代码啊。
回单位了,上代码:
<?php
/**************************************************************
*rs232.php 控制4路串口继电器演示程序 *
* 作者 tiger92665@gmail.com 2011.04 *
**************************************************************
采用232协议通信,波特率9600,8个数据位,一个停止位,无校验位。
MODE COM1 9600, n, 8, 1
计算机到继电器板的数据帧说明:
数据头: 0x55 (作为标识)
地址:0x01(一个继电器板默认为1)
操作类型: 0x00(查询当前各继电器状态)0x01(写入新值)
数据(四个字节) 每个字节代表一个继电器,共四个;
数据值1:继电器断开;数据值2:继电器吸合;数据值0:继电器无动作。
校验 一字节和校验 0x56继电器板到计算机的数据帧说明:
数据头: 0x22 (作为标识)
地址:0x01(单个继电器默认为1)
操作类型: 与计算机发来的操作类型一致
数据(四个字节) 每个字节代表一个继电器,共四个;
数据值1:继电器断开,数据值2:继电器吸合。
校验 一字节和校验(用来防止数据出错)
计算机发送指令表(部分):"55 01 01 02 00 00 00 59"; // 吸合第1路继电器
"55 01 01 00 02 00 00 59"; // 吸合第2路继电器
"55 01 01 00 00 02 00 59"; // 吸合第3路继电器
"55 01 01 00 00 00 02 59"; // 吸合第4路继电器"55 01 01 01 00 00 00 58"; // 断开第1路继电器
"55 01 01 00 01 00 00 58"; // 断开第2路继电器
"55 01 01 00 00 01 00 58"; // 断开第3路继电器
"55 01 01 00 00 00 01 58"; // 断开第4路继电器55 01 01 02 02 02 02 5F 吸合所有继电器
55 01 01 01 01 01 01 5B 断开所有继电器"55 01 01 00 00 00 00 57"; 查询当前继电器板的状态 */
//定义被操作的窜口
$com="com4";
//定义串口数据
// k1 k2 k3 k4 校验位
$k1on="\x55\x01\x01\x02\x00\x00\x00\x59";
$k2on="\x55\x01\x01\x00\x02\x00\x00\x59";
$k3on="\x55\x01\x01\x00\x00\x02\x00\x59";
$k4on="\x55\x01\x01\x00\x00\x00\x02\x59";$k1off="\x55\x01\x01\x01\x00\x00\x00\x58";
$k2off="\x55\x01\x01\x00\x01\x00\x00\x58";
$k3off="\x55\x01\x01\x00\x00\x01\x00\x58";
$k4off="\x55\x01\x01\x00\x00\x00\x01\x58";$kon="\x55\x01\x01\x02\x02\x02\x02\x5f";
$koff="\x55\x01\x01\x01\x01\x01\x01\x5b";
$kstatus="\x55\x01\x00\x00\x00\x00\x00\x56";
//定义接受的get 命令
$ops = array("k1on", "k2on", "k3on", "k4on",
"k1off","k2off","k3off","k4off","kon","koff","kstatus");
//串口操作开始
if ( isset($_GET['op']) and in_array($_GET['op'],$ops ) )
{
$data=${$_GET['op']};
set_time_limit(3);
//echo 'windows下设置窜口参数<br>';
exec("mode ".$com."BAUD=9600 PARITY=n DATA=8 STOP=1 odsr=off");
//echo "打开端口$com<br>";
$f = dio_open ($com, O_RDWR | O_NOCTTY | O_NONBLOCK);
if(!$f)
{
die("Error when open $com");
}
//echo "向串口发送数据<br>".$data.'<br>';
dio_write ($f, $data);
//echo "接收数据<br>";
$str="";
for ($i = 0; $i <= 7; $i++)
{
$str.=bin2hex(dio_read( $f,1));
}
//echo $str;
$k1=$str[7];
$k2=$str[9];
$k3=$str[11];
$k4=$str[13];
//echo "关闭端口<br>";
dio_close($f);
//串口操作结束
//输出开始//简单控制界面
$output='串口继电器控制演示程序 2011年4月<br><br>
<a href="'.$_SERVER[’PHP_SELF’].'?op=k1on">k1开</a>
<a href="'. $_SERVER[’PHP_SELF’].'?op=k1off">k1关</a>
<a href="'.$_SERVER[’PHP_SELF’].'?op=k2on">k2开</a>
<a href="'. $_SERVER[’PHP_SELF’].'?op=k2off">k2关</a>
<a href="'.$_SERVER[’PHP_SELF’].'?op=k3on">k3开</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=k3off">k3关</a>
<a href="'.$_SERVER[’PHP_SELF’].'?op=k4on">k4开</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=k4off">k4关</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=kon">全开</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=koff">全关</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=kstatus">查询</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=kstatus&out=xml">XML格式查询</a>
<br><br>
开关状态 1关 2开<br><br>
<br>k1:'.$k1.'<br>
<br>k2:'.$k2.'<br>
<br>k2:'.$k3.'<br>
<br>k2:'.$k4.'<br>';
echo $output;
}
?>
我的问题在哪里呢?
必须要用串口控制程序初始化一下窜口,我的php程序才能正常工作。不明白,google了N次,也google不出来。
自己分析是用win自己的mode命令设置的参数还不完整,可是要怎么设置呢?自己cmd下用mode测试,结果居然蓝屏死机了。
哪位大侠能给个解决方法?
再研究,google,发现不用php 的dio 也成。别人的代码如下
<?php
// HOW TO USE PHP TO WRITE TO YOUR SERIAL PORT: TWO METHODS
$serproxy=true;
if ($serproxy) {
// Use this code in conjunction with SERPROXY.EXE
// (http://www.lspace.nildram.co.uk/freeware.html)
// which converts a Serial stream to a TCP/IP stream
$fp = fsockopen ("localhost", 5331, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)";
} else {
$e = chr(27);
$string = $e . "A" . $e . "H300";
$string .= $e . "V100" . $e . "XL1SATO";
$string .= $e . "Q1" . $e . "Z";
echo $string;
fputs ($fp, $string );
fclose ($fp);
}
} elseif ($com1) {
// Use this code to write directly to the COM1 serial port
// First, you want to set the mode of the port. You need to set
// it only once; it will remain the same until you reboot.
// Note: the backticks on the following line will execute the
// DOS 'mode' command from within PHP
`mode com1: BAUD=9600 PARITY=N data=8 stop=1 xon=off`;
$fp = fopen ("COM1:", "w+");
if (!$fp) {
echo "Uh-oh. Port not opened.";
} else {
$e = chr(27);
$string = $e . "A" . $e . "H300";
$string .= $e . "V100" . $e . "XL1SATO";
$string .= $e . "Q1" . $e . "Z";
echo $string;
fputs ($fp, $string );
fclose ($fp);
}
}
?>
这样也成?不用dio的话,配置服务器就方便多了。改吧!
<?php
/**************************************************************
*rs232new.php 控制4路串口继电器程序 *
* 作者 tiger92665@gmail.com 2011.04 *
**************************************************************//* 采用232协议通信,波特率9600,8个数据位,一个停止位,无校验位。
MODE COM1 9600, n, 8, 1
计算机到继电器板的数据帧说明:
数据头: 0x55 (作为标识)
地址:0x01(一个继电器板默认为1)
操作类型: 0x00(查询当前各继电器状态)0x01(写入新值)
数据(四个字节) 每个字节代表一个继电器,共四个;
数据值1:继电器断开;数据值2:继电器吸合;数据值0:继电器无动作。
校验 一字节和校验 0x56继电器板到计算机的数据帧说明:
数据头: 0x22 (作为标识)
地址:0x01(单个继电器默认为1)
操作类型: 与计算机发来的操作类型一致
数据(四个字节) 每个字节代表一个继电器,共四个;
数据值1:继电器断开,数据值2:继电器吸合。
校验 一字节和校验(用来防止数据出错)
计算机发送指令表(部分):
// k1 k2 k3 k4 校验位
"55 01 01 02 00 00 00 59"; // 吸合第1路继电器
"55 01 01 00 02 00 00 59"; // 吸合第2路继电器
"55 01 01 00 00 02 00 59"; // 吸合第3路继电器
"55 01 01 00 00 00 02 59"; // 吸合第4路继电器"55 01 01 01 00 00 00 58"; // 断开第1路继电器
"55 01 01 00 01 00 00 58"; // 断开第2路继电器
"55 01 01 00 00 01 00 58"; // 断开第3路继电器
"55 01 01 00 00 00 01 58"; // 断开第4路继电器55 01 01 02 02 02 02 5F 吸合所有继电器
55 01 01 01 01 01 01 5B 断开所有继电器"55 01 01 00 00 00 00 57"; 查询当前继电器板的状态 */
//定义被操作的窜口
$com="com4";
//定义串口数据
$k1on="\x55\x01\x01\x02\x00\x00\x00\x59";
$k2on="\x55\x01\x01\x00\x02\x00\x00\x59";
$k3on="\x55\x01\x01\x00\x00\x02\x00\x59";
$k4on="\x55\x01\x01\x00\x00\x00\x02\x59";$k1off="\x55\x01\x01\x01\x00\x00\x00\x58";
$k2off="\x55\x01\x01\x00\x01\x00\x00\x58";
$k3off="\x55\x01\x01\x00\x00\x01\x00\x58";
$k4off="\x55\x01\x01\x00\x00\x00\x01\x58";$kon="\x55\x01\x01\x02\x02\x02\x02\x5f";
$koff="\x55\x01\x01\x01\x01\x01\x01\x5b";
$kstatus="\x55\x01\x00\x00\x00\x00\x00\x56";
//定义接受的get 命令
$op = array("k1on", "k2on", "k3on", "k4on",
"k1off","k2off","k3off","k4off","kon","koff","kstatus");
//串口操作开始
if ( isset($_GET['op']) and in_array($_GET['op'],$op ) )
{
$data=${$_GET['op']};
set_time_limit(3);
//echo 'windows下设置窜口参数<br>';
exec("mode ".$com."BAUD=9600 PARITY=n DATA=8 STOP=1 odsr=off");
//echo "打开端口$com<br>";
$f = fopen ($com, 'w+');
if(!$f)
{
die("Error when open $com");
}
//echo "向串口发送数据<br>".$data.'<br>';
fwrite ($f, $data);
//echo "接收数据<br>";
$str="";
for ($i = 0; $i <= 7; $i++)
{
$str.=bin2hex(fread( $f,1));
}
//echo $str;
$k1=$str[7];
$k2=$str[9];
$k3=$str[11];
$k4=$str[13];
//echo "关闭端口<br>";
fclose($f);
//串口操作结束
//输出开始
if ( isset($_GET['out']) and ($_GET['out']=="xml" ) )
{
//xml输出
$output =
'<?xml version="1.0" ?>
<k1>'.$k1.'</k1>
<k2>'.$k2.'</k2>
<k3>'.$k3.'</k3>
<k4>'.$k4.'</k4>';
}
else
{
//简单控制界面
$output='串口继电器控制演示程序 2011年4月<br><br>
<a href="'.$_SERVER[’PHP_SELF’].'?op=k1on">k1开</a>
<a href="'. $_SERVER[’PHP_SELF’].'?op=k1off">k1关</a>
<a href="'.$_SERVER[’PHP_SELF’].'?op=k2on">k2开</a>
<a href="'. $_SERVER[’PHP_SELF’].'?op=k2off">k2关</a>
<a href="'.$_SERVER[’PHP_SELF’].'?op=k3on">k3开</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=k3off">k3关</a>
<a href="'.$_SERVER[’PHP_SELF’].'?op=k4on">k4开</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=k4off">k4关</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=kon">全开</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=koff">全关</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=kstatus">查询</a>
<a href="'. $_SERVER[’PHP_SELF’] .'?op=kstatus&out=xml">XML格式查询</a>
<br><br>
开关状态 1关 2开<br><br>
<br>k1:'.$k1.'<br>
<br>k2:'.$k2.'<br>
<br>k2:'.$k3.'<br>
<br>k2:'.$k4.'<br>';
}
echo $output;
}
?>
测试也成功了,可以控制继电器动作!不过还是那个问题,要用串口程序初始化串口!
发表评论