魏元焜,吳丹陽
(遼寧機電職業技術學院,遼寧丹東, 118009)
在貨物裝箱統計、人流量分析等領域中,計數統計或計數報警功能使用廣泛。尤其在對數據分析有要求的背景下,單一的數據統計的價值相對較低,更多時候人們期望對統計到的計數數據進行時段、峰谷平等更加智能的分析。這一需求要求系統具備多點控制能力,且需要一個高度可制定的數據分析平臺。針對這一需求,本文設計了基于虛擬儀器和Arduino的多路物體計數報警統計分析系統。虛擬儀器的靈活性,使系統具有高度的可制定特性。為實現多點管理,以Modbus協議構建數據通信網絡,以Arduino作為終端主控芯片,簡化終端的設計。
系統分為采集終端和數據分析平臺兩個部分。采集終端負責檢測物體的經過,在完成指定個次數的計數后,發出報警信號,并將報警信息也上傳到數據分析平臺。報警可選擇由采集終端的操作人員手動解除或由數據分析平臺解除。
數據分析平臺記錄各個終端的報警參數和歷史數據。除了可以查詢各個終端的實時數據外,還可以根據各個平臺的歷史數據給出分析結果,以適應不同終端的特殊計數和報警需求,并分析出不同終端位置的數據量特點。
多個終端和平臺之間以Mod bus總線連接。分析平臺作為Modbus主機,掛接由采集終端構成的Modbus從機。Modbus為平臺與終端之間提供了規范化的接口,既便于系統的擴展,也方便終端尋址、報警類型區分等個性化控制。系統整體設計框圖如圖1所示。

圖1 系統整體設計框圖
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.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),循環往復。
分析平臺基于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總線。從而有效地避免了數據沖突。每一個采集中端的消息處理循環可按其優先級設置不同的采樣周期,以最大化提升信息傳輸效率。
傳統的技術報警設備通常是主機和從機的一對一控制,對于一個主機掛有多個從機的情況,則需要對數據通信進行統一調度。Modbus總線為這種消息集中管理提供了硬件基礎,而LabVIEW的QMH軟件架構為消息統一調度提供了軟件基礎。本文的設計方法擴展性強,有望應用于實際的產品設計當中。