一、前言
之前写过两篇PHP实现与硬件串口交互的文章,一篇是【PHP】PHP实现与硬件串口交互,接收硬件发送的实时数据(上)_php串口通信-CSDN博客,另一篇是【PHP】PHP实现与硬件串口交互,向硬件设备发送指令数据(下)-CSDN博客。上篇是介绍怎样通过RS232接口接收硬件发送的数据,下篇是介绍通过USB转RS232线怎样向硬件设备发送数据。
本篇把两个功能综合一起介绍,成为一个完整的功能。
二、开发前说明
需求:PHP通过串口与天平通信,PHP能够向天平发送指令,并接收天平返回的响应信息。
硬件设备:天平。
传输线:USB转RS232接口,USB插到电脑上,RS232接到天平单片机上。
指令集:由天平供应商提供。
开发语言:PHP。
业务逻辑是:PHP先向硬件设备发送指令,硬件设备接收到指令后,返回响应结果,PHP再去接收返回的响应结果,进行后续业务处理。
三、效果图
四、代码
后端代码说明:
1、接收前端穿过来的指令,根据天平供应商给的文档拼接要发送的数据格式,这里是以“\r\n”为结束符,同时返回的数据也带有"\r\n",所以需要对接收的数据进行处理后才能使用;
2、定义串口、波特率、数据位、停止位等参数,这样按照硬件开发文档填写;
3、打开串口,并向串口发送指令;
4、发送成功后,等待0.5s,再去接收设备返回的数据,因为软件发送数据给硬件,硬件再接收处理,返回响应数据,中间需要点时间,如果不设置等待时间而是直接读取,是没有数据的,因为硬件还没来得及返回;
5、关闭串口连接;
6、其中“TLog()”方法是我用来记录整个执行流程调试使用的,就是往txt写下执行内容。
PHP代码
/**
* 发送数据 页面
*/
public function put()
{
$list = array(
array("num" => "1", "gongneng" => "测试", "commond" => "AT"),
array("num" => "3", "gongneng" => "清零", "commond" => "AT+ZERO"),
array("num" => "4", "gongneng" => "获取重量", "commond" => "AT+WEI"),
array("num" => "5", "gongneng" => "设置获取重量方式", "commond" => "AT+AUTO=X"),
array("num" => "6", "gongneng" => "查看当前重量获取方式", "commond" => "AT+AUTO?"),
array("num" => "7", "gongneng" => "设置开机清零方式", "commond" => "AT+OPENC=X"),
array("num" => "8", "gongneng" => "查看当前开机清零方式", "commond" => "AT+OPENC?"),
array("num" => "9", "gongneng" => "校准及校准参数", "commond" => "AT+CAL=X"),
array("num" => "10", "gongneng" => "发送校准砝码指令", "commond" => "AT+CALW"),
array("num" => "11", "gongneng" => "校准参数查询", "commond" => "AT+CAL?"),
array("num" => "12", "gongneng" => "切换重量输出格式", "commond" => "AT+PRINTX=X"),
array("num" => "13", "gongneng" => "查看当前输出格式", "commond" => "AT+PRINTX?")
);
$this->assign(['list'=>$list]);
return $this->fetch();
}
/**
* 发送指令
* com9接收端
*/
public function putCom(){
if (request()->isPost()) {
set_time_limit(0);
// 接收指令 原指令
$commond = trim(input('post.commond'));
// $commond = "AT";
if (!empty($commond)) {
// 要发送的指令
$commond_send = $commond."\r\n";
TLog(">>>> start <<<<");
TLog('输入指令:'.$commond);
//定义com接收端口 baud 波特率 data 数据位 stop 停止位 由供应商提供
$com='COM9'; $baud = '9600'; $data='8'; $stop = '1'; $output = array();
exec('mode '.$com.': baud='.$baud.' data='.$data.' stop='.$stop.' parity=n xon=on',$output);
//打开串口 O_RDWR读写模式 O_RDONLY只读
$ck = @fopen($com, 'w+');
TLog("准备打开串口" . $com);
//如果打开串口失败,停止脚本,并输出“打开串口COM3失败”
if(!$ck){
TLog("打开串口" . $com . "失败");
return apiResponse('110',"打开串口" . $com . "失败");
}
TLog("打开串口" . $com . "成功");
TLog("准备向串口".$com."发送指令:【" . $commond."】");
//向串口发送数据;
$rs = fwrite($ck, $commond_send);
if ($rs) {
TLog("向串口".$com."发送指令发送成功:【" . $commond."】");
// 等待0.5秒
usleep(500000);
// 接收设备的响应
$response = fread($ck, 128);
TLog("准备读取串口".$com."的响应结果");
if ($response) {
// 过滤掉返回结果中的\r\n
$response = str_replace(array("\r", "\n"), '', $response);
TLog("读取串口".$com."的响应结果成功:【".$response."】");
}else{
TLog("读取串口".$com."的响应结果失败");
}
}else{
TLog("向串口".$com."发送指令发送失败:【" . $commond."】");
return apiResponse('110',"向串口".$com."发送指令发送失败:【" . $commond."】");
}
TLog(">>>> end <<<<");
TLog("\r\n");
//关闭端口
fclose($ck);
return apiResponse('200','success',$response);
}else{
return apiResponse('110','指令不能为空');
}
}else{
return apiResponse('110','非法请求');
}
}
前端代码
<html>
<head>
<title>实时发送并接收COM串口数据</title>
<script type="text/javascript" src="/static/index/js/jquery-1.11.3.min.js" ></script>
<script type="text/javascript" src="/static/index/layui/layui.js"></script>
<link rel="stylesheet" type="text/css" href="/static/index/layui/css/layui.css">
</head>
<body>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend>实时发送并接收COM串口数据</legend>
</fieldset>
<div class="layui-row" style="width:60%; margin: 0 auto;">
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item" >
<div class="layui-inline" >
<label class="layui-form-label">发送指令</label>
<div class="layui-input-inline" style="width: 500px;">
<input type="text" name="commond" autocomplete="off" class="layui-input" value="AT">
</div>
</div>
<div class="layui-inline">
<button type="submit" class="layui-btn layui-btn-normal" lay-submit="" lay-filter="demo1">提交指令</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-row layui-col-space10" style="width:60%; margin: 0 auto;">
<div class="layui-col-md4">
<div class="layui-form-item" style=" padding: 10px; background-color: #F2F2F2; " >
<div class='layui-card'>
<div class='layui-card-header' style="font-size: 18px">响应结果</div>
<div class='layui-card-body' id="result" style="font-size: 16px">
</div>
</div>
</div>
</div>
<div class="layui-col-md8">
<table class="layui-table">
<colgroup>
<col width="20%">
<col width="40%">
<col width="40%">
</colgroup>
<thead>
<tr>
<th>序号</th>
<th>功能</th>
<th>指令</th>
</tr>
</thead>
<tbody>
{volist name="list" id="vo"}
<tr>
<td>{$vo.num}</td>
<td>{$vo.gongneng}</td>
<td>{$vo.commond}</td>
</tr>
{/volist}
</tbody>
</table>
</div>
</div>
</body>
<script>
layui.use(['form','element'], function(){
var form = layui.form
,$ = layui.jquery
,element = layui.element;
// 提交
form.on('submit(demo1)', function(data){
var commond = $("input[name='commond']").val()
$.ajax({
url:'putCom',
type:'POST',
dataType:'JSON',
data:{commond:commond},
success:function (res) {
console.log(res)
if (res.code == '200') {
layer.msg(res.message)
$('#result').empty();
var html = ''
html = '<div>输入指令:'+commond+'</div><div style="color:green">返回内容:'+res.data+'</div>'
$('#result').append(html)
}else{
layer.msg(res.message)
}
}
})
return false
});
})
</script>
</html>
两篇PHP实现与硬件串口交互的文章,【PHP】PHP实现与硬件串口交互,接收硬件发送的实时数据(上)_php串口通信-CSDN博客,【PHP】PHP实现与硬件串口交互,向硬件设备发送指令数据(下)-CSDN博客。