【PHP】PHP通过串口与硬件通讯,向硬件设备发送数据并接收硬件返回的数据

一、前言

之前写过两篇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博客。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/435527.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云2核4G服务器支持人数并发测试,2核4G主机测评

阿里云2核4G服务器多少钱一年&#xff1f;2核4G配置1个月多少钱&#xff1f;2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

C++ LRU缓存

题目&#xff1a; //构建双向链表的节点结构&#xff08;要有两个构造函数&#xff09; struct Node{int key, val;Node* pre;Node* next;Node():key(0), val(0), pre(nullptr), next(nullptr) {}Node(int _key, int _val): key(_key), val(_val), pre(nullptr), next(nullpt…

基础小白快速入门web前端开发技术------>web概述

Web概述 我们在编程的学习中&#xff0c;随着学习的深入&#xff0c;我们会理解到WEB这个东西&#xff0c;那么 web究竟是个啥&#xff0c;到底该咋用&#xff1f; web&#xff0c;是网站的英文意思&#xff0c;又被称作“下一代Web3.0&#xff0c;互联网”&#xff0c;是在We…

简洁实用的wordpress外贸网站模板

坚果蜜饯wordpress跨境电商模板 木瓜干、菠萝干、夏威夷果、芒果干、椰片、巴旦木等wordpress跨境电商模板。 https://www.jianzhanpress.com/?p3944 珠宝手饰wordpress外贸网站模板 金银手饰、珍珠手饰、翡翠手饰、钻石手饰、玉石珠宝手饰wordpress外贸网站模板。 https:…

docker无法运行问题

场景如下&#xff1a; 执行运行docker命令出现如下错误&#xff1a;systemctl start docker 出现该问题的原因&#xff1a;是因为我们配置的镜像加速器用不了了 去修改我们的镜像加速器&#xff0c; 去到配置镜像加速器的目录 cd /etc/docker 修改镜像加速器 vim daemon.j…

记一次 .NET某设备监控自动化系统 CPU爆高分析

一&#xff1a;背景 1. 讲故事 先说一下题外话&#xff0c;一个监控别人系统运行状态的程序&#xff0c;结果自己出问题了&#xff0c;有时候想一想还是挺讽刺的&#xff0c;哈哈&#xff0c;开个玩笑&#xff0c;我们回到正题&#xff0c;前些天有位朋友找到我&#xff0c;说…

二叉树进阶leetcode

606. 根据二叉树创建字符串 要点&#xff1a;前序遍历&#xff0c;当左子树为空时&#xff0c;右结点有数字时要给左边加括号 class Solution { public:string tree2str(TreeNode* root) {string s;//创建一个字符串if(rootnullptr){return s;}sto_string(root->val);//保存…

LLM | GPT-NEOX论文详解

GPT-NEOX使用旋转位置编码。模型权重使用float16表示。最大序列长度为2048。 论文题目&#xff1a;2022.04.14_GPT-NeoX-20B: An Open-Source Autoregressive Language Model 论文地址&#xff1a;2204.06745.pdf (arxiv.org) 论文代码&#xff1a;EleutherAI/gpt-neox: An imp…

go语言基础 -- 文件操作

基础的文件操作方法 go里面的文件操作封装在os包里面的File结构体中&#xff0c;要用的时候最好去查下官方文档&#xff0c;这里介绍下基本的文件操作。 打开关闭文件 import("os" ) func main() {// Open返回*File指针&#xff0c;后续的操作都通过*File对象操作…

Unsupervised Learning of Monocular Depth Estimation and Visual Odometry 论文阅读

论文链接 Unsupervised Learning of Monocular Depth Estimation and Visual Odometry with Deep Feature Reconstruction 0. Abstract 尽管基于学习的方法在单视图深度估计和视觉里程计方面显示出有希望的结果&#xff0c;但大多数现有方法以监督方式处理任务。最近的单视图…

归并排序总结

1.归并排序 归并排序的步骤如下&#xff1a; ①枚举中点&#xff0c;将区间分为左右两段&#xff1b; ②对左右两段区间分别排序&#xff1b; 这个过程以递归的方式进行。 ③合并两段区间。 是一个模拟的过程。用两个指针分别指向左右区间&#xff0c;判断当前哪个数小&…

FPGA——三速自适应以太网设计(2)GMII与RGMII接口

FPGA——以太网设计&#xff08;2&#xff09;GMII与RGMII 基础知识&#xff08;1&#xff09;GMII&#xff08;2&#xff09;RGMII&#xff08;3&#xff09;IDDR GMII设计转RGMII接口跨时钟传输模块 基础知识 &#xff08;1&#xff09;GMII GMII:发送端时钟由MAC端提供 下…

k近邻分类算法实现(KNN)

KNN算法实现 最近要用到对 某些数据进行自动识别分类&#xff0c;简单学习了一下k近邻算法&#xff0c;分享一下。 例如&#xff1a;电影动作片爱情片分类识别 这里我们使用了sklearn库&#xff0c;它用起来简单方便。 先提供代码如下&#xff1a; import numpy as np imp…

docker的简单使用

在一些进行使用靶场或者工具的时候&#xff0c;我们可以用docker在线拉取&#xff0c;就可以省去手动搭建靶场的过程 一、docker的配置 因为docker是默认从docker的官网进行拉取&#xff0c;所以拉取经常速度很慢或者失败&#xff0c;我们先要进行一下配置&#xff0c;让他优…

欧科云链:角力Web3.0,香港如何为合规设线?

在香港拥抱Web3.0的过程中,以欧科云链为代表的合规科技企业将凸显更大重要性。 ——据香港商报网报道 据香港明报、商报等媒体报道&#xff0c;港区全国政协兼香港选委界立法会议员吴杰庄在日前召开的全国两会上提出在大湾区建设国际中小企业创新Web3融资平台等提案&#xff0…

《系统架构设计师教程(第2版)》第6章-据库设计基础知识-01-数据库基本概念

文章目录 1. 概述1.1 基本概念1&#xff09;信息 (Information)2&#xff09;数据 (Data)3&#xff09;数据库 (DB)4&#xff09;数据库系统(DBS)5&#xff09;数据库管理系统&#xff08;DBMS&#xff09; 1.2 数据库技术的发展1.2.1 人工管理阶段1.2.2 文件系统阶段1&#xf…

C++中OpenMP的使用方法

适用场景 OpenMP是一种用于共享内存并行系统的多线程程序设计方案&#xff1b;简单地说&#xff0c;OpenMP通过一种较为简单的使用方式&#xff0c;实现代码的CPU并行化处理&#xff0c;从而最大化利用硬件的多核性能&#xff0c;成倍地提升处理效率&#xff1b; OpenMP适用场…

springboot3.x集成SpringDoc Swagger3

近期将springboox2.x升级到了3.x&#xff0c;索性将swagger2也同步升级到swagger3&#xff0c;具体过程如下。 一、添加maven依赖 <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>…

每日力扣——滑动窗口与前 K 个高频元素

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害。 滑动窗口最大值 给定一个数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑…

uni app 微信小程序微信支付

使用方法 接口传参 使用wx.requestPayment方法是一个统一各平台的客户端支付API&#xff0c;不管是在某家小程序还是在App中&#xff0c;客户端均使用本API调用支付