[周边教程]使用OHSCE控制MODBUS-RTU设备
最后更新于:2022-04-01 23:45:16
OHSCE入门教程(四)-大肚函数PHP轻松搞HTTP(S)API(URL/REST)
最后更新于:2022-04-01 23:45:14
OHSCE入门教程(三)-PHP串口通信、构建高可靠性的总线应用
最后更新于:2022-04-01 23:45:11
(写于OHSCE_V0.1.25)
终于等到这篇文章了吧,其实之所以先写了TCP/UDP的是因为在现在的环境下它俩是相辅相成的,其实在控制领域我们所说的TCP/UDP和串口总线应用非常接近,和普通的互联网网络应用还是有着很大区别的,毕竟绝大部分网络控制产品都是从总线控制产品升级而来或沿袭了可靠的设计而产出的,本质上基本是一样的(这也就是为什么在使用OHSCE完成您的需求能够让您“稀里糊涂”的顺利躲过了很多使用其它办法时的坑)。控制领域是个很宽的领域,它包含了或有交集于时下热门的物联网万物互联、工业4.0智能制造、行业智能化、人工智能、各种与控制相关的云等云云种种。
有人表达说"控制的世界没有异步",这句话说来也对也错,一个继电器或是开或是闭同一时间只有一种状态,每一步逻辑都是缜密的,工艺越复杂系统越庞大对可靠性的要求越高。随着系统集成的需求越来越深,互联网+的概念侵入和发展,事情被诠释的越来越多元化。不过话又说回来,对高可靠性的要求是永远一成不变的,毕竟是控制。虽然现在一些诸如采集手环,随身血压采集等物联网应用因业务场景简单所以一些不可靠的问题暂时不会酿成事故,但随着业务复杂度的提升和系统集成度的提高开发者很快就会意识到这个道理。
一、OHSCE中的封装函数。
主要分为封装函数和基础函数,绝大多数的需求使用封装函数即可完成,但是OHSCE也提供给您了操作更接近底层的基础函数库。
Ohsce_eng_serial_X 是您在构建串口总线应用时主要应用的封装函数。
绝大多数情况,任何串口设备或总线网络在上位机/网关的角度上看,通信的门就是那几个电气接口首先你先要高清你使用的是哪个串口,我们演示使用COM7(由USB转发485)。
(*设备上常见直接有的接口:RS232<俗称9针>、RS485、RS422、USB<通用串行总线基本是机器都有>、TTL(常见于单片机)等等等等等....)
想使用OHSCE中的所有函数很简单,只需要引入OHSCE的加载文件即可。
函数参考
Ohsce_eng_serial_creat(&$OHSCESerial,$com,$flags="1",$mode=0,$baud=9600,$parity='n',$data=8,$stop=1,$fc='none',$xon='off',$to='off',$octs='off',$odsr='off',$idsr='off',$dtr='on',$rts='on',$space=0)
当您创建完成这个资源的时候其实默认载入了3ms的发送延迟,这是一个全局值,在创建时被写入资源。若要改变这个间隔除了改变space参数外(注意为0时失效),需要使用Ohsce_eng_serial_setspace函数(0值有效)。但是不建议您消除这个间隔,近乎任何情况下它的存在只会有益无害。
三、打开一个串口资源并占用这个接口
非常简单的一行,就可以让您的进程打开一个资源并占用所指定的串口。
Ohsce_eng_serial_open (内置函数)
Ohsce_eng_serial_open($hscecom);
值得注意的是,一般情况下一个串口同一时间只能被一个资源所占用,当您需要在两个进程之间交替时需要先使用close释放。(_M_X系版本提供的多进程共同占用一个串口实际上是提供了一个缓冲进程做到,本质上还是一个由一个进程占用。)
四、写与读的操作
大部分总线设备均是上位机轮询的模式,虽然也有一些设备是主动上报但是我们认为轮询的模式设计更为合理故我们演示的也是先写后读。
此时我们演示一次在RS485总线上使用MODBUS-RTU协议读取设备保持寄存器的操作。
Ohsce_eng_serial_write($hscecom,"01030001000415c9",true);
向串口设备发送数据,后面的true表示是以16进制发送。(这个以16禁止发送的意思是您发送的数据输入的是16进制格式的"01030001000415c9"而不是"100000011000000000000000100000000000001000001010111010000"的意思。)
读取设备的返回。
usleep(3000);
Ohsce_eng_serial_read($hscecom,$data,null,true);
读取串口数据 返回数据长度为未知 以16进制返回。其中$data变量中存的就是返回的数据。
五、记得关闭您的串口资源。
Ohsce_eng_serial_close($hscecom);
关闭一个资源并不会将这个资源清空删除,只是释放了此串口的控制权方便另一个进程继续调用使用此串口。当然如果您需要让您的这个进程保持占有此接口的话就不要调用这个函数啦。
六、花絮函数
Ohsce_eng_serial_comwr -进行一次连续的写读操作
Ohsce_eng_serial_npcomwr-使用额外的全新的进程进行一次连续的写读操作(基础环境必须运行中)。操作结束后额外的进程会立即结束。
(OHSCE的PRO扩展也会带来一些函数如ohsce_ext_modbus_x ohsce_ext_profibus_x等等,我们会在扩展的说明书详细阐述。)
七、打磨您的工艺细化您的控制流程,并保持更新您的OHSCE框架至最新的稳定版本。
OHSCE愿每一名控制工程师都可以搭上互联网+的翅膀,每一名PHPWEB工程师都可以冲在物联网的前言,我们的程序是您可靠的基石。
官方网站:http://www.ohsce.org & http://www.ohsce.com
开发者QQ群:374756165
GITHUB:https://github.com/OpenIBC/Ohsce
手册地址:http://www.ohsce.com/index.php/book/
';
OHSCE入门教程(二)-TCP/UDP应用
最后更新于:2022-04-01 23:45:09
(写于OHSCEV0.1.23)
面对以太网我们需要使用TCP/UDP进行通信,TCP/UDP在世界互联网范围内被广泛使用,同时它也被广泛应用于物联网、工业网等控制通信网上。不过区别于互联网上的极致追求高并发高效率普通应用,更偏重的是与浏览器/应用客户端交互。我们的应用场景是与控制设备交互,更注重准确性、可靠性、稳定性。也正是因此目前纯粹的基于TCP/UDP的NCS控制系统在大型系统基本是不可行的,但是事情不是一成不变的,总要动态的去看问题。随着网络技术的发展越来越成熟,我们越来越多的要去接触它,在控制领域对它的使用和在普通应用中对它的使用是有很多不同的,OHSCE为您平衡了它们。另外个人认为复合型的控制系统是相对科学的。
一、OHSCE中的TCP/UDP函数族。
主要分为封装函数和基础函数,绝大多数的需求使用封装函数即可完成,但是OHSCE也提供给您了操作更接近底层的基础函数库。
封装函数Ohsce_eng_socket_X。
首先在建立一个SERVER/CLIENT之前需要先构建一个链接预备资源,其实此资源在OHSCE中就是一个数组结构,存储了这个资源在调用和运行中需要的各个数据。构建一个链接预备资源非常简单,只需要一个函数就可以解决。
CLIENT: Ohsce_eng_socket_client
SERVER: Ohsce_eng_socket_server
DO: Ohsce_eng_socket_send Ohsce_eng_socket_recv Ohsce_eng_socket_server_runtcp Ohsce_eng_socket_server_runudp Ohsce_eng_socket_server_close
二、我们先构建一个CLIENT:
TCP:
Ohsce_eng_socket_client($ohsceclient,'tcp',7628,'127.0.0.1'); //创建一个TCP客户端资源并连接127.0.0.1:7626
UDP:
Ohsce_eng_socket_client($ohsceclient,'udp',7628,'127.0.0.1'); //创建一个UDP客户端资源并绑定127.0.0.1:7628
这样一个变量名为$ohsceclient的链接资源就创建完成了,是不是很简单,实际上Ohsce_eng_socket_client函数还可以很强大,它有很多输入量都被OHSCE自动为您填充了。Ohsce_eng_socket_client(&$OhsceClient,$protocol,$port,$ip=null,$AF='ipv4',$sync=true,$mode='defalut') 函数支持您创建不同协议的客户端模式链接资源,支持IPV4和IPV6(默认为IPV4),支持同步和异步,和多种预设定模式(默认为default)
三、再构建相应的SERVER
其实TCP是有链接的而UDP是无链接的,而所谓UDPSERVER资源只是在告诉OHSCE应该以SERVER姿态去运行这个资源。
Ohsce_eng_socket_server函数能够帮助你轻松的创建一个SERVER预备资源。但是在创建这个资源之前我们还需要两件件事情要做。
第一件是为SERVER资源预备回调函数。其中TCP需要两个回调函数,UDP需要一个回调函数。
TCP回调函数分别为新客户端到达函数(callbackaccept)和旧客户端回调函数(callback),新客户端到达回调函数其实就是TCP握手后第一个信息。因为这个信息很多时候是一个硬件登陆信息,如果您的设备没有登陆动作那您可以不准备此函数。旧客户端回调函数是每次有数据到达都会调用的一个函数。
举个栗子:
function example(&$socket,$buf,$len,$zv){ //收到数据时的回调函数
echo $buf;
Ohsce_socketwrite($socket,'hi '.$buf);
return true;
}
function exampleaccept(&$socket,$ip,$port,$zv){ //新客户端到访时的回调函数
Ohsce_socketwrite($socket,'Welcome'.$ip.':'.$port);
return true;
}
其中example函数会被传入本次连接的socket资源的指针,$buf为数据内容,$len为数据长度,$zv为OHSCE固定结构体(数组形式)。
&$oibc_clients,"ip"=>&$oibc_clients_id_ip,"id"=>&$oibc_clients_id);
这个数组会由OHSCE自动生成并传递给您。其中clients是客户端列表(包含一个占位符,这个您不用管),ip是客户端ip表,id是客户端表备份便于您回滚。您可以操作它管理各数据,包含手动进行心跳操作(如果您的需求需要)。
另一个函数exampleaccept(&$socket,$ip,$port,$zv)是在新客户端到访时被调用的。
第二件事是构建常驻函数
常驻函数是每次循环都会被执行的函数,如果您不需要完全可以直接写成。
'example','accept'=>'exampleaccept','fap'=>'fap'),'example');
其中$ohsceserver就是我们构建好的server。后面依次是tcp协议,7627端口,回调函数组(只需要传入函数名即可),最后一个回调函数名是0.1.X兼容写法。其实OHSCE的SERVER远比演示强大,可以参考文档。
四、让SERVER运转起来并使用CLIENT去连接
在OHSCE中运转一个SERVER是非常容易的事情,对于基础的需求只需要一个函数你的SERVER就被激活并开始运转了。
Ohsce_eng_socket_server_runtcp($ohsceserver); //开始运行
这时候,一个服务端口是7627占用IP是127.0.0.1,回调函数是example()欢迎函数exampleaccept(),并且每各循环都会运行一个fap()常驻函数的TCPSERVER就启动啦。
现在我们可以CLIENT文件添加读写操作。
Ohsce_socketsend($ohsceclient['socket'],'hello'); //发送数据
echo Ohsce_socketread($ohsceclient['socket'],1024)[1]; //收取回复数据
运行CLIENT文件,其实客户端资源在创建时默认就进行了连接(至少目前版本是这样设计的),所以直接就可以进行读写操作了。
六、有关UDP
UDP和TCP的区别是UDP是无连接的通信协议而TCP是有链接的通信协议,所以理论上TCP比UDP更可靠一些。但是在本机或可靠的设备内网,其可靠性方面的差异并不大但毕竟UDP风险还是略高一些,但是对于非关键位置的查询型设备设计上下位机通信是还是可以考虑此协议。所以还是能见到UDP控制设备的,虽然其很少见,笔者就遇到过,我们举一个UDP的使用例子。
UDPSERVER
ini_set('memory_limit',"88M");//重置php可以使用的内存大小为88M
set_time_limit(0);
ob_implicit_flush(1);
include('loadohsce.php');
$trya='ohsce_server_Example ';
function example(&$socket,$buf,$from,$port,$zv){ //收到数据时的回调函数
global $trya;
echo $buf;
Ohsce_socketsend($socket,$trya.'hi '.$buf,0,0,$from,$port);
return true;
}
function fap(&$zv){
return true;
}
Ohsce_eng_socket_server($ohsceserver,'udp',7626,'127.0.0.1',array('callback'=>'example','fap'=>'fap'));//创建一个UDP服务端资源 绑定127.0.0.1:7626 并传入回调函数
@Ohsce_eng_socket_server_runudp($ohsceserver); //开始运行
其实UDP没有SERVER概念,所谓SERVER只是我们的逻辑SERVER罢了。
UDPCLIENT
ini_set('memory_limit',"88M");//重置php可以使用的内存大小为64M
set_time_limit(0);
ob_implicit_flush(1);
include('loadohsce.php');
Ohsce_eng_socket_client($ohsceclient,'udp',7628); //创建一个UDP客户端资源并绑定7628
Ohsce_socketsend($ohsceclient['socket'],'hello',0,0,'127.0.0.1',7626);
Ohsce_socketrecvfrom($ohsceclient['socket'],$buf,0,0,$from,$port); //收取回复数据
echo $buf.'|'.$from.':'.$port;
sleep(30);
同样,这只不过是逻辑客户端罢了。
显而易见,UDP带来了高效、简单、迅捷的优点,但是别忘了它的硬伤它并不确保数据可靠到达和到达顺序。不过一般情况下,UDP设备均有应答机制。
七、科学的拆分你的逻辑到回调函数和常驻函数中去。
';
OHSCE入门教程(一)-高可靠性PHP通信&控制框架
最后更新于:2022-04-01 23:45:07
"PHP是最好的(互联网+物联网)语言!",据说发布PHP开源产品都要惯例的喊上这么一句。 -2016.10.17 发此文之际是OHSCEV0.1.22版本
开启第一篇教程前总要卖点情怀,本人本科学习建筑电气与智能化专业(即电气工程及其自动化专业),一直是名正经的电气工程师。其实本来和这个号称是“Web语言”的PHP八竿子打不着,可是随着国家所谓“互联网+“的引导,也翻山越岭的将WEB领域逐渐和各行各业拉到了一起。从很多行业的角度看“互联网+“很大程度就是“WEB+”,于是PHP这门最好的语言便进入了我的技术栈,我发现PHP是最具潜力的工控、物联网&智能化语言。
打开PHP的官网,我们可以看见两行白色的欢迎语:“PHP is a popular general-purpose scripting language that is especially suited to web development.Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.” -意译:PHP是一各流行且全能的脚本语言,特别合适于与互联网相关的领域。它快速、灵活且实用,健壮的PHP能驱动小到你的博客大到著名的FACEBOOK、百度等每个事物。
工控工业4.0、物联网、行业智能化将是PHP的下一个最具潜力的领域。本着不造轮子多改进的原则我曾用款现有的PHP通信框架(不含串口通信功能)做过一次控制系统的实现,结果那几天搅合的我一团糟,很多奇怪的问题和很高的失误率,其实人家的框架是非常优秀的WEB框架可能是控制领域的技术栈和传统的WEB领域有着很大的区别,传统的web工程师更多的工作内容和一个强大的浏览器或APP交互而控制工程师则不是,于是我决定从底层重写一套代码(同时也加上了串口通信和共享内存辅助托管功能)。这套代码专为控制环境量身定制,是专业针对工控工业4.0、物联网、行业智能化场景(当然兼备了做WEB的能力,毕竟“”互联网+“”嘛)。其实母程序已几经实布和商布,我们将其核心部分剥离出来继而做了开源化改动并合并了OpenIAC计划成为了为控制场景量身定制的高可靠性PHP通信&控制框架-OHSCE。它简单高效并且特别亲切于工业自动化工程师、硬件工程师、物联网工程师、追求效率的PHP工程师的写法风格,也能让传统的PHP-WEB工程师轻松上手。
言归正传我们以搭建一个简单的串口服务器作为第一教程的内容,一个简单的串口服务器包含了上行网络(以太网)和现场总线(这里是RS485通信)。
以太网做上行网络是大势所趋,RS485是目前使用最普遍广泛也是最具性价比的现场通信手段,当然很多其它通信手段都可以和RS232/485转接,故我们以它做例。
#用UDP还是TCP?
UDP是一个非常好的选择,它无链接、高效并且节约资源,但是缺点是会有丢包的可能性,不过您可以通过主从应答来保证您的数据的可靠性,而且您可以灵活的掌握是否应答,甚至这各特性都可以逻辑中的一部分。不过对于串口服务器这个场景来说TCP是更合适的选择,因为做一个串口的需求很简单,可靠连接读写数据并转发到串口上,串口写读数据并回转回来。我们确定使用TCP
示例所使用的机器的COM7是将使用的串口。
#欲善其事必利其器
下载最新版本的OHSCE:
您可以到OHSCE的官网(http://www.ohsce.org)或GITHUB(https://github.com/OpenIBC/Ohsce)下载到最新的OHSCE。PS.记得支持我一下哦
安装PHP5.4+ 并配置PHP.INI至可用状态。
配置OHSCE的配置文件 位于.../config/
开启Curl扩展、Shmop扩展、Sockets扩展
创建OhsceComserver.php文件
加载OHSCE
0)){
foreach($oibc_clients_zv['clients'] as $okey => $osclient){
if($okey=="0"){
continue;
}
Ohsce_socketwrite($osclient,$data);
}
}
return true;
}
其中comserveralways函数是每圈循环都会执行一次的函数,也就是常驻函数。在我们的串口服务器程序中,他会将最新收到的串口数据转发广播出去。
comservera(&$socket,$buf,$len,$zv)和comserveraccept(&$socket,$ip,$port,$zv)函数会被固定传入这些变量。其中$socket是本次活动的socket资源的指针。$buf是收到的数据。$len是数据长度。$ip是新到客户端的ip地址。$port是其端口。$zv是固定结构体,其结构如下:$oibc_clients_zv=array("clients"=>&$oibc_clients,"ip"=>&$oibc_clients_id_ip,"id"=>&$oibc_clients_id)
其中$oibc_clients数组为当前所有socket资源,key值为0者为服务监听者。$ip数组为ip对照表。$id数组为id备份表。当然如果有需要您也可以print_r之一探究竟。
小提示:print_r函数是您的好帮手,很多时候文档很难面面俱到QQ群我也很难随时关注,这时候print_r可能比度娘还亲切。
#赋予它生命的力量
好了,回调函数和常驻函数都造好了,下面我们改让它拥有跑起来的能力了。首先先创建一个可复用的TCP服务端资源,第二步传入让它跑起来,就那么简单。
'comservera','accept'=>'comserveraccept','fap'=>'comserveralways'),'comserveraccept');
//创建一个可以复用的SOCKETSERVER资源$ohsceserver,协议为TCP,监听端口为7626,绑定IP127.0.0.1,回调函数为comservera,首次回调函数为comserveraccept,常驻函数为comserveralways.最后一个comserveraccept是为了兼容OHSCEV0.1.22以前的版本。
Ohsce_eng_socket_server_runtcp($ohsceserver); //运行它
当然更详细的可以参考手册文档: Ohsce_eng_socket_server Ohsce_eng_socket_server_runtcp
PS:一个彩蛋,当你的实际生产中最好不要使用7626端口,因为它太著名了,曾经我们漫游在整个互联网上寻找开了7626端口的小伙伴。简单的来说,容易招黑,而且招来的都是老黑:)
#一个个人认为的好习惯
无论您的程序多么的完美,最后记得阻截并跳转去抛出错误。这样当您的程序扩展和改动其它部分时至少能保证某一部分运行的不错。
0)){
foreach($oibc_clients_zv['clients'] as $okey => $osclient){
if($okey=="0"){
continue;
}
Ohsce_socketwrite($osclient,$data);
}
}
return true;
}
Ohsce_eng_socket_server($ohsceserver,'tcp',intval(trim($oibc_cnp_csa['p'])),OHSCE_MYIP_SYSTEM,array('callback'=>'comservera','accept'=>'comserveraccept','fap'=>'comserveralways'),'comserveraccept');
Ohsce_eng_socket_server_runtcp($ohsceserver); //开始运行
goto terror;
//.......................................
好了下面我们启动它并使用TCP连接串口服务器在COM7串口上使用MODBUS-RTU协议读取一台压力变送器的数据。
tcpComClient.php:
"01030001000415c9",'bin'=>true));
echo Ohsce_socketread($ohsceclient['socket'],1024)[1]; //收取回复数据
sleep(30);
运行效果:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/11742f1251690d1f172c70d6aaea69fc_1072x611.gif)
PHP是一个健壮的全能脚本语言,特别适合于网络有关的场景。工业控制、物联网、行业智能化方向,OHSCE是您强大的战舰。
OHSCE官方网站: HTTP://WWW.OHSCE.ORG
技术&交流:Q群-374756165 (随风星海@作者)
手册地址:http://www.ohsce.com/index.php/book/ohscelib/
GITHUB:https://github.com/OpenIBC/Ohsce
GIT@OSC:https://git.oschina.net/SFXH/Ohsce
捐助&支持:http://www.ohsce.com/index.php/company/
';
快速入门
最后更新于:2022-04-01 23:45:04
快速入门
一、检查环境是否支持OHSCE
系统:Windows / Linux / OSX
建议:WINDOWSSERVER2008及以上 UbuntuServer14.04LTS及以上
PHP:5.4及以上
建议PHP5.4.28及以上
PHP扩展:
Socket,Shmop,Curl
二、修改配置文件
/config/oibc_sce_config.php
三、运行测试程序
3.1工作在以太网上
一个TCP服务端测试程序:
';
简介
最后更新于:2022-04-01 23:45:02
OHSCE高可靠性的PHP通信框架-.Open HI-REL Signal Communication Engine
PHP以太网(TCP/UDP/ICMP)、RS232、RS485通信,可广泛直接或桥接各种网络工程通信。
特别合适于对可靠性要求较高、上位机与末端协同工作的场景。如物联网设备通信、智能化系统、工业与自动化系统、可靠网络服务器。
可运行于Windows、Linux、OS X。对Windows提供了全项功能支持,与自动化生态亲和。
不过分追求高性能,充分平衡了可靠性与高性能。
天生支持分布式,可大规模部署。
在保证您的网络可靠性的前提下能跑出强悍的性能。
过程化函数风格的框架具备高效的特性。
特别亲切于工业自动化工程师、硬件工程师、物联网工程师、追求效率的PHP工程师的写法风格。
OHSCE开放源代码,在OHSCE授权协议框架下您可以免费使用!
*采用高效的多进程模型,进程独立。
*支持Windows平台串口完美读取(无需指定长度)。
*支持Windows平台进程守护。
*支持Windows平台进程间内存通信,小型数据内存中转。
#即将支持多个进程同时伺服一个端口
# ** 教程陆续补充中!本文档跟随官方文档同步更新!**
';