基于虚拟仪器和Arduino的多路物体计数报警统计分析系统设计
2023-02-19魏元焜吴丹阳
魏元焜,吴丹阳
(辽宁机电职业技术学院,辽宁丹东, 118009)
0 引言
在货物装箱统计、人流量分析等领域中,计数统计或计数报警功能使用广泛。尤其在对数据分析有要求的背景下,单一的数据统计的价值相对较低,更多时候人们期望对统计到的计数数据进行时段、峰谷平等更加智能的分析。这一需求要求系统具备多点控制能力,且需要一个高度可制定的数据分析平台。针对这一需求,本文设计了基于虚拟仪器和Arduino的多路物体计数报警统计分析系统。虚拟仪器的灵活性,使系统具有高度的可制定特性。为实现多点管理,以Modbus协议构建数据通信网络,以Arduino作为终端主控芯片,简化终端的设计。
1 系统概述
系统分为采集终端和数据分析平台两个部分。采集终端负责检测物体的经过,在完成指定个次数的计数后,发出报警信号,并将报警信息也上传到数据分析平台。报警可选择由采集终端的操作人员手动解除或由数据分析平台解除。
数据分析平台记录各个终端的报警参数和历史数据。除了可以查询各个终端的实时数据外,还可以根据各个平台的历史数据给出分析结果,以适应不同终端的特殊计数和报警需求,并分析出不同终端位置的数据量特点。
多个终端和平台之间以Mod bus总线连接。分析平台作为Modbus主机,挂接由采集终端构成的Modbus从机。Modbus为平台与终端之间提供了规范化的接口,既便于系统的扩展,也方便终端寻址、报警类型区分等个性化控制。系统整体设计框图如图1所示。
图1 系统整体设计框图
2 系统实现
■2.1 制定Modbus-RTU通信规则
Modbus是一种工业协议标准,由Modicon(现为施耐德电气)于20世纪70年代后期创建,如今已普遍用于可编程控制器、智能仪表之间的通信,是连接工业设备的最广泛使用的协议。Modbus协议规范是公开发布的,该协议的使用是免费的[1~3]。
本文采用的是RS-485上的Modbus-RTU协议,这是Modbus协议中一种常用的、相对简单的串行协议,可以通过传统的UART技术进行传输。
系统实现Modbus-RTU通信的关键在于采集终端上Modbus寄存器的布局使用情况,以及采集终端和分析平台上的Modbus软件实现。本文系统中的计数报警采集终端的Modbus寄存器布局如表1所示。
采集终端和分析平台分别采用不同的软件平台实现,因此Modbus的实现方式有所不同。但只要都遵循表1的寄存器布局规则,则上下位机就可以建立统一的通信规则,进而实现计数和报警数据的分布存储和分析。
表1 计数报警采集终端中的Modbus寄存器布局
■2.2 采集终端
2.2.1 采集端硬件构成
采集终端采用Arduino Leonardo作为主控。Arduino Leonardo是基于ATmega32u4一个微控制器板。它有20个数字输入/输出引脚(其中7个可用于PWM输出、12个可用于模拟输入),一个16 MHz的晶体振荡器,一个Micro USB接口,一个DC接口,一个ICSP接口,一个复位按钮。它包含了支持微控制器所需的常用功能,可以简单地通过将其连接到计算机的USB接口,或者使用AC-DC适配器,再或者用电池来驱动它[4]。
Leonardo与其他Arduino控制器的不同之处在于直接使用了ATmega32u4的USB通信功能,取消了USB转UART芯片。这使得Leonardo不仅可以作为一个虚拟的(CDC)串行/COM端口,还可以作为鼠标或者键盘连接到计算机[5]。
为实现采集终端的功能,将Arduino与光电开关模块、LED和按键连接,光电开关模块数据由D2引脚读取,LED由D3引脚输出控制信号,按键信号由D7引脚读取。图2给出了采集终端的实物图。
图2 采集终端实物图
2.2.2 采集端软件实现
Modbus在采集终端采用Arduino官方提供的Arduino Modbus库来实现。这一工具库可在ArduinoI DE的库管理器中搜索并直接安装。另外需要同时安装Arduino Modbus库依赖的Arduino RS485库。由于Modbus总线的通信主要是主机发出查询指令,从机被动应答,因此Arduino的Modbus库将Modbus从机看作服务器,Modbus主机看作客户端,从机的Modbus对象被命名为Modbus RTUServer。从机利用Arduino Modbus库实现Modbus通信分为初始化、查询和更新几个阶段,涉及modbusServer对象的常用方法有:begin()、poll()、end()以及一些寄存器的配置和读写方法。
采集终端的软件分为初始化和主循环两个部分。初始化部分需要完成计数变量、报警变量等数据初始化以及LED状态初始化,以及Modbus总线和寄存器的初始化。主循环部分包括光电开关数据更新、按键数据更新、LED状态更新、计数变量、报警变量等数据的更新,以及Modbus请求查询和按硬件情况更新Modbus寄存器。
采集终端的功能主要由以下几个步骤实现:(1)初始化变量和引脚
(2)初始化Modbus总线
ModbusRTUServer.begin(0x33, 9600); //指 定Modbus从机的设备号和通信波特率。
ModbusRTUServer.configureCoils(0x00, 2); //按表1为光电开关状态和当前报警状态开辟Modbus线圈寄存器空间。
ModbusRTUServer.configureHoldingRegisters(0x00,2); //按表1为当前计数值和计数报警值开辟Modbus保持寄存器空间。
(3)开始主循环,更新硬件状态
利用digitalWrite和digitalRead更新硬件状态。其中,PeStateOld和PeStateNew分别记录相邻两次的光电开关状态,光电开关输出的上升沿代表有物体经过,则PassState被赋值为HIGH。PassState的上升沿使当前计数值CurCnt自增1,CurCnt也可由分析平台或采集终端的按键清零。当CurCnt数值超过AlmNum规定的报警上限时,则AlarmState置1,并以此数值驱动LED,使其点亮0.5s。
(4)硬件状态映射到Modbus寄存器
按表1映射关系,将光电开关状态和报警状态映射到线圈寄存器,关键代码如下:
按表1映射关系,将当前计数值和计数报警值映射到保持寄存器,关键代码如下:
获取ModbusClient(Modbus主机)的数据查询请求,关键代码如下:
返回步骤(3),循环往复。
■2.3 分析平台
分析平台基于Windows PC运行,利用NI LabVIEW软件编写实现。LabVIEW具有所见即所得的界面设计特点,可缩减软件设计周期;配合LabVIEW成熟的设计模式(软件设计框架),可以提高软件的可维护性,便于功能的增加或删减。
2.3.1 分析平台软件框架
旅游开发价值-充分挖掘古建筑本身具有的历史文化与象征意义,将其开发打造成旅游观光场所,不仅可以促进地方经济发展,而且是打造地方特色的重要实物载体。
本文采用LabVIEW的队列消息处理器(Queued Message Handler,QMH)设计模式搭建分析平台的软件框架。
QMH可由模板创建。创建好的QMH模板中,Main.vi是整个程序的入口。Main.vi包含两个while循环,类似于两个线程,它们是CPU分配时间的最小单位,可以共享局部变量。两个while循环中,一个负责处理来自界面和用户自定义的事件。根据具体事件要求,发送不同消息给另一个while循环— 消息处理循环。根据设计需要,也可以建立多个消息处理循环,根据设计规划,将同一类消息发送给不同的循环。在本文中,保留了模板中的事件处理循环和消息处理循环。消息处理循环用于统一处理Modbus通信,因此称为Modbus通信循环。另外,为每一个采集终端单独设置一个while循环,用于处理不用采集终端的消息,这一设计方式对平台对不同采集终端数据的独立分析是有利的。
QMH中的第二个要素是消息队列,在模板中以库的形式出现,被命名为Message Queue.lvlib。LabVIEW中的库类似于面向对象编程中的类,在消息队列库中,封装了消息队列的数据类型、对外可见的公有函数和私有函数。对外的公有函数包括:Create All Message Queues(创建所有消息队列)、Obtain Message Queue(获取消息队列)、Enqueue Message(消息入队)和Dequeue Message(消息出队)。Create All Message Queues函数一次性创建Main.vi所需的所有消息队列,并以簇的形式将所有消息队列的引用打包输出。Obtain Message Queue可以创建单一的消息队列。Enqueue Message将一个或多个消息压入指定消息队列,这是一个多态VI,可向指定队列一次性压入一个或多个消息,因而可以一次性发送多个连续的指令,这一特性在状态机设计模式中可以用于一次性指定后续的连续多个状态。消息入队时可选择消息入队优先级,低优先级入队,是将消息压入队尾,而高优先级入队是将消息压入消息队列队首,便于在消息出队时优先出队。Dequeue Message用于从指定队列中从队首提取一个消息。
本文为实现系统功能,为N个采集终端创建了N+1个消息队列。即为每个采集终端独立创建一个消息队列,多出的一个消息队列用于Modbus通信,即Modbus通信循环的专用消息队列。
消息的数据类型是一个簇(类似于C语言中的结构体),包含了消息本身(字符串类型)和一个消息参数(变体类型,类似于C语言中的空类型,即void)。这样的设计方式可以将任意类型的数据以变体的形式发送,在接收时按对应数据类型从变体中恢复出来。但这种类型的数据发送需要开辟大量内存空间,因此对于大量数据,最好发送引用,以减少不必要的内存开销。
2.3.2 分析平台Modbus通信实现
分析平台的Modbus通信可通过NI的Modbus库1.21实现。NI Modbus库不是LabVIEW自带的,但安装过程相对简单,其提供了较为完整的功能。NI Modbus库提供了LabVIEW 7.1、8.2、8.5以及8.6几个早期关键版本,但8.6版的兼容性较好,可以使其兼容LabVIEW2019乃至更高版本的LabVIEW。因此安装时将86文件夹中的三个文件夹:help、user.lib以及vi.lib复制到安装目录下,并直接与同名文件夹合并即可。重启LabVIEW软件,在程序框图右击,调出函数选板,在用户库大类下,看到NI Modbus项则表明安装成功。
工具包中有几个关键函数,是实现分析平台作为Modbus主机(即Arduino Modbus库中的Modbus Client)与作为Modbus从机的采集终端进行Modbus通信所必需的,包括:
(1)MB Serial Init:用于对初始化Modbus总线所在的串口资源,包括指定串口号、波特率、校验位、是否采用流控、超时毫秒以及Modbus模式等信息,完成初始化后,即输出初始化成功的串口资源号。
(2)MB Serial Master Query:用于Modbus主机向从机发起查询指令。这是一个多态VI,可根据查询寄存器类型选择对应参数类型的重写VI。其中的关键参数包括指定从机号、寄存器类型对应的起始寄存器地址和要读写的数量。
2.3.3 分析平台数据分析功能实现
就实现单一采集终端数据读取而言,LabVIEW的程序框图非常简单,如图3所示。
图3 单一采集终端的数据查询的LabVIEW程序
图中给出的示例分为初始化、数据读写和资源回收三个阶段。在初始化阶段,利用MB Serial Init函数指定Modbus主机所连接的串口号,从而打开所在串口资源引用,后续的Modbus操作都需要利用这个引用找到需要读写的硬件资源。在数据读写阶段,相应的Modbus从机寄存器进行读写,同时需要指定Modbus通信模式(RTU)和从机号。由于Modbus从机有运行周期,所以主机的读写频率应适应从机读写周期。当程序退出后,需要回收相应的硬件资源,关闭打开的串口。
但当采集中端数量变多时,主机对从机的请求数据就会出现积压,因此必须分类管理,否则会出现通信冲突。这时就需要利用分析平台的QMH软件框架对数据通信进行规划管理。即为每一个采集终端设置一个消息请求循环(while循环实现的消息处理循环),每个采集终端的消息处理循环将自己的Modbus请求发送给QMH的Modbus消息循环,即使出现消息积压,所有消息也都会在Modbus消息处理循环的队列中被有序组织,并依次发送给Modbus总线。从而有效地避免了数据冲突。每一个采集中端的消息处理循环可按其优先级设置不同的采样周期,以最大化提升信息传输效率。
3 结束语
传统的技术报警设备通常是主机和从机的一对一控制,对于一个主机挂有多个从机的情况,则需要对数据通信进行统一调度。Modbus总线为这种消息集中管理提供了硬件基础,而LabVIEW的QMH软件架构为消息统一调度提供了软件基础。本文的设计方法扩展性强,有望应用于实际的产品设计当中。