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