隨著我國儲運(yùn)行業(yè)的不斷發(fā)展和人們對于儲運(yùn)環(huán)節(jié)的關(guān)注度不斷提高, 安全可靠的監(jiān)控系統(tǒng)對現(xiàn)代化倉儲管理系統(tǒng)十分必要。隨著多種各樣的監(jiān)控設(shè)備及其安防預(yù)警系統(tǒng)這些硬件逐步發(fā)展地越來越智能化, 意味著軟件上的設(shè)計要同步跟上硬件的發(fā)展需求。同時我國的自動化、智能化的檢測水平也在不斷提高, 在這種良好的社會環(huán)境下, 基于C++/Qt的倉儲環(huán)境監(jiān)控系統(tǒng)將逐步被廣泛采用, 并將實現(xiàn)普及, 從而將我國的儲運(yùn)行業(yè)的環(huán)境監(jiān)管提高到更安全的標(biāo)準(zhǔn)。
Qt由奇趣科技在90年代研制的集編輯、編譯、調(diào)試與一起的集成開發(fā)環(huán)境。簡單點(diǎn)說Qt就是設(shè)計圖形界面的軟件, 當(dāng)然它自己本身也是一個圖形界面。由于Qt底層是C++代碼實現(xiàn), 它不同于C語言, C++是面向?qū)ο缶幊? 相對于C語言面試過程編程, Qt更具有貼近用戶的思想。Qt的優(yōu)勢在于具有優(yōu)秀的跨平臺特性、繼承了C++面向?qū)ο蟮某绦蛟O(shè)計思想、豐富的API接口供應(yīng)用層調(diào)用??缙脚_特性是指Qt支持包括Windows、Linux在內(nèi)的大部分操作系統(tǒng);由于Qt底層實質(zhì)是C++編程, 所以C++具有的面向?qū)ο缶幊趟枷朐赒t編程里能夠得到更好的體現(xiàn);Qt包含了多達(dá)250個以上的C++類庫, 可以這樣說Qt其實就是一個大型的C++函數(shù)庫, 這樣豐富的API幾乎可以實現(xiàn)操作人員對界面設(shè)計的大部分想法。最重要的一點(diǎn)是Qt是開源的, 這一點(diǎn)對于界面開發(fā)者來說是最吸引的, 開源意味著你可以隨時看到底層源碼, 可以更改源碼設(shè)計出自己的界面。
倉儲監(jiān)控系統(tǒng)是嵌入式具體應(yīng)用的方向之一, 嵌入式系統(tǒng)最廣泛的定義為:主要把中心放在貼近用戶的需求, 同時要求以通用PC技術(shù)為基礎(chǔ), 在軟件和硬件的設(shè)計上要盡可能的模塊化, 需要更多的應(yīng)用設(shè)計的時候可以擴(kuò)大其軟硬件的功能;在不需要一些功能的時候可以剪裁部分功能以滿足嵌入式系統(tǒng)的功耗小、體積小的要求。本設(shè)計主要在嵌入式硬件基礎(chǔ)上的軟件開發(fā)設(shè)計。嵌入式發(fā)展空間相對較大, 嵌入式系統(tǒng)是當(dāng)前社會發(fā)展必不可少的技術(shù)要求, 主要應(yīng)用在現(xiàn)代化發(fā)展地方方面面, 小到我們平常使用的mp3、手機(jī)等電子設(shè)備, 大到一些汽車電子、工廠設(shè)備、航天航空設(shè)備??傊? 嵌入式系統(tǒng)與我們平常使用的通用PC系統(tǒng)不一樣, 嵌入式設(shè)備更像一個專用計算機(jī)系統(tǒng), 在總的性能方面可能沒有PC機(jī)那么強(qiáng)大, 但是在個別功能方面卻比通用PC的性能強(qiáng)大很多。
Qt的網(wǎng)絡(luò)編程和Windows下的網(wǎng)絡(luò)編程機(jī)制很相似, 都是基于C/S網(wǎng)絡(luò)編程模型。網(wǎng)絡(luò)編程套接字是通信端點(diǎn)的一種抽象, 它有兩種形式:流式套接字和數(shù)據(jù)報文套接字。本實驗采用的是面向連接的流式套接字, 它采用的是傳輸控制協(xié)議TCP。如圖1所示, 采用TCP協(xié)議的服務(wù)器端程序框架圖;如圖2所示是客戶端程序框架圖。
在概述里我們說到Qt包含了多達(dá)250個C++類庫, 在Qt客戶端設(shè)計程序里建立和服務(wù)器的連接我們需要使用QTcp Socket類。這里我們用到Qt里的信號與槽機(jī)制, 信號與槽機(jī)制和Windows下的消息機(jī)制十分類似, 消息機(jī)制是基于回調(diào)函數(shù), Qt中用信號與槽來代替函數(shù)指針, 使程序安全簡潔。信號與槽機(jī)制是Qt的核心機(jī)制, 可以讓編程人員將互不關(guān)心的對象綁定在一起, 實現(xiàn)對象之間的通信??蛻舳嗽趧?chuàng)建和服務(wù)器連接之前首先我們需要創(chuàng)建QTcp Socket類的對象socket, 然后通過信號與槽機(jī)制的connect函數(shù)連接服務(wù)器。
客戶端程序啟動之前做的任務(wù)是和服務(wù)器建立連接, 當(dāng)客戶端連接上服務(wù)器之后出現(xiàn)如圖3所示的客戶端登錄界面, 我們在用戶名和密碼的編輯框中輸入信息, 點(diǎn)擊立即登錄后, Qt中的轉(zhuǎn)到槽機(jī)制啟動, 程序會去調(diào)用相應(yīng)的登錄函數(shù), 該函數(shù)里主要是把用戶名和密碼欄的信息提取出來, 放在一個自定義結(jié)構(gòu)體中, 在結(jié)構(gòu)體前面加上協(xié)議頭發(fā)送到服務(wù)器。服務(wù)器讀取客戶端發(fā)送的信息先去提取協(xié)議頭出來, 然后判斷消息類型, 如果是登錄請求, 服務(wù)器再去把用戶名和密碼信息提取出來。服務(wù)器通過和My SQL數(shù)據(jù)庫中的信息比對來確認(rèn)登錄信息的正確性。
數(shù)據(jù)庫 (DB) 嚴(yán)格的說是按照一定的數(shù)據(jù)結(jié)構(gòu)來管理數(shù)據(jù)的倉庫, 數(shù)據(jù)庫的種類有很多, 比如目前流行的My SQL、sqlite等都是數(shù)據(jù)庫的一種。相對sqlite來說My SQL是比較適合本設(shè)計的一種數(shù)據(jù)庫, 優(yōu)勢在于My SQL比sqlite更具有完善的服務(wù)器數(shù)據(jù)庫, 功能相比而言更全面, 而sqlite更適合于手機(jī)端開發(fā)的數(shù)據(jù)庫。前面我們提取了用戶名和密碼, 將這些信息傳入到我們編寫的一個API函數(shù)里, 函數(shù)內(nèi)部主要調(diào)用了一些My SQL語句來檢測信息在不在數(shù)據(jù)庫中。如果用戶信息在服務(wù)器的數(shù)據(jù)庫中, 則Qt界面就會跳轉(zhuǎn)到控制臺控制界面。
客戶端控制臺界面起來后相當(dāng)于一個主程序, 獨(dú)立運(yùn)行的主程序也叫進(jìn)程, 這個主進(jìn)程在運(yùn)行的時候可以拆分多個不同的執(zhí)行路徑, 每個路徑嚴(yán)格上應(yīng)該稱為線程, 每個線程都是相對獨(dú)立的, 一個線程崩潰不會影響到其他進(jìn)程甚至是主進(jìn)程的運(yùn)行。如今任何一個系統(tǒng)都是多線程或者多進(jìn)程設(shè)計的, 由于多進(jìn)程設(shè)計的程序在系統(tǒng)調(diào)度和資源回收上要占用太多的CPU, 所以想對于多進(jìn)程設(shè)計的客戶端, 多線程設(shè)計的客戶端很少產(chǎn)生卡頓甚至死機(jī)的情況。如今的軟件設(shè)計行業(yè)已經(jīng)很多是單進(jìn)程處理任務(wù)事件了。單進(jìn)程意味著你在接收圖片信息的同時不能去發(fā)送控制室內(nèi)設(shè)備的命令了, 這在現(xiàn)實監(jiān)控客戶端應(yīng)用來說是難以想象的。
Qt的C++類庫提供了一些線程相關(guān)的類, 本程序中我們使用的是QThread類, 它提供了開始一個新線程的方法。如圖4所示是控制臺控制界面, 此界面采用的是信號與槽機(jī)制中最簡單的轉(zhuǎn)到槽機(jī)制, 通俗的來說當(dāng)我們點(diǎn)擊任何一個按鈕時, 此機(jī)制就會運(yùn)行該按鈕對應(yīng)的槽函數(shù)。
控制臺界面中主程序負(fù)責(zé)向服務(wù)器發(fā)送獲取溫濕度和光照度的請求。此外, 當(dāng)點(diǎn)擊控制界面開始錄制的按鈕時, Qt的信號與槽機(jī)制啟動與此相關(guān)的槽函數(shù), 在這個槽函數(shù)里我們開辟一個新線程用于錄制視頻信息保存到電腦上位機(jī)中。Qt創(chuàng)建一個新線程其實很簡單, 首先我們需要通過QThread類創(chuàng)建一個對象, 與此同時, 需要重寫編寫里面的run () 函數(shù), 程序示例如下:
接著需要建立上面線程實例對象, 這時需要調(diào)用QThread::start () 函數(shù)。程序執(zhí)行到start () 函數(shù)時, 創(chuàng)建的新的線程就會去執(zhí)行run () 函數(shù)。在run函數(shù)中, 我們實現(xiàn)的就是保存視頻圖片的操作代碼。正是因為線程的特點(diǎn), 本設(shè)計才可以在保存視頻圖片的同時還可以去做其他任務(wù), 比如我們可以在保存信息的同時可以向服務(wù)器發(fā)送控制LED燈開的命令, 服務(wù)器通過Zig Bee協(xié)議向室內(nèi)終端發(fā)送LED燈開控制命令。當(dāng)保存視頻圖像的線程崩潰了并不會影響客戶端向服務(wù)器發(fā)送控制命令。
本GUI界面程序中我們使用了兩個線程, 第一個線程就是上述的保存視頻圖片的線程, 第二個線程我們創(chuàng)建用于獲取服務(wù)器端發(fā)送來的圖片信息之后通過QPixmap類將圖片顯示到視頻加載框中。多線程并發(fā)執(zhí)行是可以提高CPU運(yùn)行效率, 但凡事都有利弊, 帶來便利的同時, 如何控制線程間的同步就是需要解決的問題之一。
QMutex, QRead Write Lcok等是用于同步線程的類庫。同步簡單點(diǎn)說就是任務(wù)執(zhí)行的需要按照設(shè)定好的流程來執(zhí)行, 就像我們走路一樣邁完左腳邁右腳, 不可能邁完左腳后還邁左腳, 這樣一來我們右腳一直不動, 是不可能完成任務(wù)設(shè)定的要求的。我們在程序中使用線程主要是用來控制多個任務(wù)并發(fā)的執(zhí)行, 所以控制多個任務(wù)執(zhí)行的順序即我們需要控制的同步。假如兩個不同的線程同時訪問一個全局變量 (線程通信的方式之一) , 這個時候問題就產(chǎn)生了, 線程一在執(zhí)行過程中使用這個全局變量, 而線程二在線程一執(zhí)行過程中去更改該全局變量在內(nèi)存中的變量值, 線程一會前后使用的值不一樣會造成程序崩潰。所以我們需要上面的控制線程同步的類來實現(xiàn)整個進(jìn)程安全高效的運(yùn)行。
整個項目框架圖如圖5所示, 用戶登錄時向服務(wù)器發(fā)送登錄用戶名和密碼, 服務(wù)器調(diào)用My SQL接口檢測用戶名和密碼是否正確, 成功則登錄界面會關(guān)閉, 控制臺界面會展現(xiàn)出來??刂婆_界面布滿顯示倉儲環(huán)境的控制按鈕, 通過點(diǎn)擊相應(yīng)的Button向服務(wù)器發(fā)送控制室內(nèi)換氣扇、LED開關(guān)的命令, 同時客戶端控制臺界面還可以獲取室內(nèi)溫濕度和光照度的信息顯示到控制臺相應(yīng)的QLine Edit類的對象中。線程一、二分別向服務(wù)器獲取圖片視頻和保存圖片視頻信息到本地備份。
通過具體的模型分析與設(shè)計應(yīng)用, 該客戶端在電腦上位機(jī)中可以正常運(yùn)行, 本設(shè)計的不足之處在于客戶端的局限性只能在電腦上運(yùn)行。要實現(xiàn)隨時隨地的去監(jiān)控倉儲環(huán)境信息我們需要利用Qt的Webkit集成與Qt Network模塊, Qt Webkit模塊使得Qt widget能夠通過HTML的object標(biāo)簽加入到web頁面中, 并通過Java Script代碼進(jìn)行訪問, 而Qt對象也能相應(yīng)的訪問web頁面元素。
本文就目前熱門的倉儲環(huán)境監(jiān)控系統(tǒng)提供了一種客戶端設(shè)計方案??紤]到單進(jìn)程系統(tǒng)在運(yùn)行和調(diào)度的局限性, 這里我們采用了多線程設(shè)計客戶端, 很大程度上提高了客戶端在與服務(wù)器交互過程中的實時性和高效性。通過移植My SQL數(shù)據(jù)庫來檢測用戶登錄信息的正確性, 保證了整個監(jiān)控系統(tǒng)的安全性和可控性。鑒于本設(shè)計主要闡述了客戶端的設(shè)計和應(yīng)用細(xì)節(jié), 所以對服務(wù)終端只提及了少量和客戶端交互的協(xié)議和過程, 這里是本文的有待改進(jìn)之處。這里我們基本實現(xiàn)了一個監(jiān)控系統(tǒng)所具備的所有因素要求, 獲取視頻代碼實現(xiàn)就是每一秒中向服務(wù)器申請十張圖片的信息, 能夠?qū)崟r快速的對倉儲環(huán)境的變化做出應(yīng)對, 保證了整個嵌入式系統(tǒng)穩(wěn)定高效的運(yùn)行。
權(quán)所有©:上海陽合儲運(yùn)
專業(yè)承接上海倉庫租賃、上海倉儲配送物流、上海電商倉儲企業(yè)服務(wù)與微笑同在"的先進(jìn)理念不斷發(fā)展壯大。