基于Linux/Qt的智能家居系統(tǒng)設(shè)計(jì)
針對(duì)智能家居的特點(diǎn)及應(yīng)用背景,設(shè)計(jì)了一種家庭多功能控制系統(tǒng)。該系統(tǒng)采用飛思卡爾公司ARM Cortex A8系列的i.MX51處理器作為MCU,在其上移植嵌入式Linux作為軟件開(kāi)發(fā)平臺(tái),并利用Qt相關(guān)技術(shù)為基礎(chǔ)設(shè)計(jì)友好的用戶界面,實(shí)現(xiàn)了ARM板的各功能模塊與服務(wù)器端的交互。系統(tǒng)同時(shí)具備數(shù)字可視對(duì)講、信息收發(fā)、家電控制、安防報(bào)警、家庭娛樂(lè)等功能。
本文引用地址:http://www.ex-cimer.com/article/148088.htm1 系統(tǒng)的架構(gòu)和功能
家庭智能控制系統(tǒng)主要由室內(nèi)分機(jī)、單元門(mén)口機(jī)、小區(qū)圍墻機(jī)、管理中心終端機(jī)、管理中心服務(wù)器以及附件組成。系統(tǒng)采用分布式網(wǎng)絡(luò)結(jié)構(gòu),可以根據(jù)住戶數(shù)量對(duì)系統(tǒng)的容量進(jìn)行擴(kuò)充。
(1)室內(nèi)機(jī)是用戶在室內(nèi)進(jìn)行操作的主要平臺(tái),其功能組成為:可視對(duì)講、信息服務(wù)、家電控制、安防報(bào)警、家庭娛樂(lè)等??梢晫?duì)講模塊主要實(shí)現(xiàn)雙向可視通話、視頻監(jiān)控、留言/留影、開(kāi)鎖等功能;信息服務(wù)模塊主要用來(lái)收發(fā)物業(yè)信息和小區(qū)廣播,支持文本、圖片形式,并實(shí)現(xiàn)與可視對(duì)講模塊的影音共享;家電控制模塊包括對(duì)燈光、窗簾、空調(diào)、電梯等設(shè)施的無(wú)線控制,并預(yù)設(shè)了情境模式;安防報(bào)警模塊支持對(duì)煙感、門(mén)磁、煤氣泄漏檢測(cè)等的自動(dòng)報(bào)警,并可通過(guò)GPRS/3G技術(shù)將報(bào)警信息傳送到用戶手機(jī)上;家庭娛樂(lè)模塊支持常見(jiàn)格式的音視頻文件的播放(主要依靠硬件解碼)以及對(duì)常見(jiàn)格式的圖片的瀏覽(電子相框)。
(2)單元門(mén)口機(jī)的主要功能是完成與所在單元樓的任意住戶以及管理中心機(jī)的可視通話,除了具備留言/留影功能外,還提供觸摸屏校準(zhǔn)、背光調(diào)節(jié)、密碼設(shè)置等功能。
(3)圍墻機(jī)的基本功能和單元門(mén)口機(jī)類似,但可視對(duì)講、留言/留影功能是針對(duì)小區(qū)內(nèi)所有住戶的。
(4)中心機(jī)是整個(gè)系統(tǒng)的神經(jīng)中樞,管理人員通過(guò)管理中心的控制設(shè)備管理各子系統(tǒng)的終端,其功能包括:可視對(duì)講、視頻監(jiān)控、查看報(bào)警信息、排除設(shè)備故障、信息服務(wù)、系統(tǒng)設(shè)置、遠(yuǎn)程管理等。
2 系統(tǒng)的實(shí)現(xiàn)方案
2.1 Qt的信號(hào)/槽機(jī)制
Qt是一個(gè)跨平臺(tái)的C++應(yīng)用程序框架,完全面向?qū)ο?、易于擴(kuò)展且允許真正的組件編程。Qt的C++類庫(kù)封裝了適應(yīng)不同操作系統(tǒng)的訪問(wèn)細(xì)節(jié),這使得它能夠快速地部署于各種桌面與嵌入式系統(tǒng)中[1]。
信號(hào)/槽機(jī)制是 Qt 的核心特性,這種機(jī)制真正實(shí)現(xiàn)了消息的封裝,完全可以取代原始的回調(diào)和消息機(jī)制。信號(hào)和槽的連接通過(guò)connect()函數(shù)完成,connect()函數(shù)是QObject類中的靜態(tài)函數(shù),其函數(shù)原型如下:
Bool QObject::connect(const QObject* sender,
const char*signal,const QObject* receiver,const char* member)
其中,sender和receiver是指向QObject的指針,signal和slot是不帶有參數(shù)的函數(shù)名。
2.2 基于XML格式的Socket多線程通信
Linux中的網(wǎng)絡(luò)編程主要通過(guò)Socket接口實(shí)現(xiàn),在Qt環(huán)境里,對(duì)Socket進(jìn)行了封裝,并建立了相應(yīng)的QTcpSocket類來(lái)實(shí)現(xiàn)TCP客戶端和服務(wù)器的通信。QTcpSocket繼承了QIODevice,所以QTcpSocket可以使用QDataStream進(jìn)行數(shù)據(jù)的讀取和寫(xiě)入。
可擴(kuò)展標(biāo)記語(yǔ)言XML(eXtensible Markup Language)是一種用于數(shù)據(jù)交換和數(shù)據(jù)存儲(chǔ)的多用途文本格式。對(duì)于XML格式的數(shù)據(jù),Qt中的QtXml模塊提供了DOM和SAX兩種處理方式。本文采用的DOM方式把XML文檔轉(zhuǎn)換成一個(gè)可以遍歷的樹(shù)形結(jié)構(gòu),這樣便可以隨意訪問(wèn)其中的節(jié)點(diǎn),因此要明顯簡(jiǎn)潔得多。
室內(nèi)機(jī)和中心機(jī)之間的通信采用多線程方式實(shí)現(xiàn)。多線程方式具有降低內(nèi)存、提高程序響應(yīng)速度等優(yōu)點(diǎn),特別適用于嵌入系統(tǒng)。系統(tǒng)中建立了三個(gè)主線程:(1)GUI線程:用于執(zhí)行main()主函數(shù),響應(yīng)用戶的界面操作;(2)tcpServer偵聽(tīng)線程:用于對(duì)指定端口進(jìn)行監(jiān)聽(tīng);(3)tcpSocket傳輸線程:負(fù)責(zé)消息的接收和回復(fù)。下面以用戶主動(dòng)更新小區(qū)廣播為例詳細(xì)說(shuō)明Socket通信的流程:(1)室內(nèi)機(jī)首先啟動(dòng)一個(gè)線程,將用戶的更新請(qǐng)求結(jié)構(gòu)轉(zhuǎn)化成標(biāo)準(zhǔn)的XML格式(如果是新設(shè)備第一次開(kāi)機(jī),要先手動(dòng)進(jìn)行IP的設(shè)置),(2)調(diào)用connectToHost()函數(shù)請(qǐng)求與中心機(jī)建立連接,處于監(jiān)聽(tīng)狀態(tài)的中心機(jī)接到請(qǐng)求后,就會(huì)分配一個(gè)Socket套接字來(lái)處理連接:首先根據(jù)解析出來(lái)的XML的Type節(jié)點(diǎn)判斷請(qǐng)求類型,如果是純文本則從數(shù)據(jù)庫(kù)的Text表讀取,如果是圖片則從硬盤(pán)讀取,然后調(diào)用QIODevice::write()函數(shù)發(fā)送;(3)室內(nèi)機(jī)接到應(yīng)答信號(hào)readyRead()后就開(kāi)始進(jìn)行信息的收取,根據(jù)消息的Type節(jié)點(diǎn)類型分別寫(xiě)入數(shù)據(jù)庫(kù)和硬盤(pán)。Socket多線程通信流程如圖1所示。
2.3 并行數(shù)據(jù)庫(kù)設(shè)計(jì)
為了實(shí)現(xiàn)數(shù)據(jù)庫(kù)的并行操作,使GUI界面與數(shù)據(jù)庫(kù)相分離,從而讓界面能更快地響應(yīng)用戶的一般操作,同樣要用到Qt的多線程編程。在系統(tǒng)啟動(dòng)時(shí),首先要建立一個(gè)全局對(duì)象m_query,以便于各個(gè)實(shí)體類與數(shù)據(jù)庫(kù)類進(jìn)行連接。這樣,每當(dāng)有數(shù)據(jù)庫(kù)操作請(qǐng)求時(shí)便會(huì)實(shí)例化一個(gè)m_query來(lái)創(chuàng)建一個(gè)線程用于處理該請(qǐng)求。m_query對(duì)象中包含兩個(gè)類:(1)QueryThread,用于為每個(gè)數(shù)據(jù)操作創(chuàng)建一個(gè)線程;(2)Worker,用于實(shí)現(xiàn)數(shù)據(jù)庫(kù)的相關(guān)操作,如加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)、進(jìn)行數(shù)據(jù)查詢/插入/刪除等。
圖2為數(shù)據(jù)庫(kù)的查詢操作流程。首先在實(shí)體類里創(chuàng)建兩個(gè)connect連接,分別用于發(fā)送和接收查詢結(jié)果,并生成SQL語(yǔ)句向QueryThread提交查詢請(qǐng)求信號(hào)。QueryThread收到請(qǐng)求后為其創(chuàng)建一個(gè)線程,并交由Worker類進(jìn)行具體數(shù)據(jù)庫(kù)查詢操作。Worker類得出查詢結(jié)果后,先傳遞給QueryThread,再由其將查詢結(jié)果返回到實(shí)體類。
關(guān)鍵代碼如下:
connect( this,SIGNAL(seek(const QString ) ),m_query,
SIGNAL(seek_execute(const QString )) );
connect( m_query,SIGNAL(seek(const QList
) ),this,SLOT( slotResult( const QList
…
void text:: database() {
QString sql = select * from Text order by date desc ;
emit seek_execute (sql);
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論