聶 斐,殷興輝
(河海大學(xué) 計(jì)算機(jī)與信息學(xué)院,江蘇 南京 211100)
在工業(yè)控制和測(cè)量探測(cè)等領(lǐng)域中,對(duì)于一些時(shí)刻變化的物理量(如:溫度,壓力,速度等),我們常常要進(jìn)行實(shí)時(shí)地監(jiān)測(cè)。這就需要在測(cè)量測(cè)試的儀器儀表或控制系統(tǒng)的界面上,畫出實(shí)時(shí)曲線圖,供使用人員觀測(cè)。本文基于太陽(yáng)爆發(fā)活動(dòng)實(shí)時(shí)監(jiān)測(cè)系統(tǒng)的應(yīng)用,對(duì)太陽(yáng)溫度進(jìn)行實(shí)時(shí)顯示。而通常的軟件界面上,只是實(shí)時(shí)顯示根據(jù)數(shù)據(jù)繪制的曲線,但是坐標(biāo)幅度(縱坐標(biāo))上往往是恒定的[1]。當(dāng)太陽(yáng)出現(xiàn)爆發(fā)活動(dòng)時(shí),實(shí)測(cè)溫度達(dá)到幾萬(wàn)度,而爆發(fā)活動(dòng)結(jié)束時(shí),實(shí)測(cè)溫度又回到幾百度,因此,被監(jiān)測(cè)的數(shù)據(jù)在不斷變化,幅度的變化范圍很大。當(dāng)被監(jiān)測(cè)數(shù)據(jù)從一個(gè)很大的波動(dòng)幅度(幾萬(wàn)度)突降到一個(gè)很小的波動(dòng)幅度(幾百度)時(shí),就會(huì)導(dǎo)致繪制出的曲線縮在一起,在幅值較小的地方。這種曲線極不便于觀測(cè)者實(shí)時(shí)觀看與監(jiān)測(cè)。本文在界面設(shè)計(jì)時(shí),不僅實(shí)時(shí)監(jiān)測(cè)數(shù)據(jù)繪制曲線,而且坐標(biāo)幅度也根據(jù)實(shí)測(cè)數(shù)據(jù)在動(dòng)態(tài)變化,非常利于觀測(cè)者觀測(cè),使得人機(jī)交互界面更加友好便捷。
MFC(Microsoft Foundation Class,微軟基礎(chǔ)類庫(kù))是微軟公司為了簡(jiǎn)化程序員的開發(fā)工作所開發(fā)的一套C++類的集合,是一套面向?qū)ο蟮暮瘮?shù)庫(kù),以類的方式提供給用戶使用??梢杂盟鼇?lái)編寫Windows應(yīng)用程序,該類的集合是按層次結(jié)構(gòu)組織起來(lái)的,其中封裝了大部分Windows API(Application Programming Interface)函數(shù)和Windows控件,它所包含的功能涉及到整個(gè)Windows操作系統(tǒng)。MFC不僅為用戶提供了Windows圖形環(huán)境下應(yīng)用程序的框架,而且還提供了創(chuàng)建應(yīng)用程序的組件。使用MFC類庫(kù)和Visual C++提供的高度可視的應(yīng)用程序開發(fā)工具,可使應(yīng)用程序開發(fā)變得更簡(jiǎn)單,極大地縮短開發(fā)周期,提高代碼的可靠性和可重用性[2-4]。
軟件界面的開發(fā)依托微軟公司推出的Visual C++6.0為開發(fā)平臺(tái),使用MFC的單文檔視圖框架來(lái)設(shè)計(jì)整個(gè)應(yīng)用程序。為了監(jiān)測(cè)太陽(yáng)溫度,軟件界面上需要顯示太陽(yáng)溫度的實(shí)時(shí)窗口。在觀測(cè)太陽(yáng)溫度的實(shí)時(shí)窗口中,需要實(shí)時(shí)繪制太陽(yáng)溫度曲線圖?;诿嫦?qū)ο蟮脑O(shè)計(jì)理念,我們可以用一個(gè)類來(lái)完成這樣的工作。MFC中沒有直接提供這樣的類[5],JanVidar Berger編寫的clPlot類可以畫實(shí)時(shí)曲線,派生于CWnd類。但是并不能滿足本系統(tǒng)的要求,本文進(jìn)行了修改,加以改進(jìn),進(jìn)而實(shí)現(xiàn)了實(shí)時(shí)數(shù)據(jù)的動(dòng)態(tài)顯示。
不同于Jan Vidar Berger所寫的clPlot類,本文在serie類的成員變量中構(gòu)建了一個(gè)CList類的對(duì)象m_valuelist。CList類支持可訪問順序或按值排列的非獨(dú)一對(duì)象的有序鏈表[6]。用這樣一個(gè)鏈表,來(lái)存放實(shí)時(shí)監(jiān)測(cè)的數(shù)據(jù)。該數(shù)據(jù)為一個(gè)結(jié)構(gòu)體。定義如下:
以X軸(橫坐標(biāo))為時(shí)間軸,Y軸(縱坐標(biāo))為太陽(yáng)溫度。在界面上,我們顯示的是一分鐘內(nèi)的溫度曲線。由于下位機(jī)設(shè)定的采樣速率為一秒鐘采集一個(gè)數(shù)據(jù),傳到上位機(jī)上,一分鐘內(nèi)為60個(gè)數(shù)據(jù)。那么,我們就將鏈表元素的個(gè)數(shù)設(shè)定為60個(gè)。每接收到一個(gè)新的數(shù)據(jù),則添加在鏈表的尾部。如果接收到的數(shù)據(jù)超過(guò)60個(gè)了,則將鏈表的頭元素去掉。這樣,就使得鏈表的元素個(gè)數(shù)始終為60個(gè),并且是最新的60個(gè)數(shù)據(jù)。這樣即可以保證觀測(cè)數(shù)據(jù)的實(shí)時(shí)性。另外,在添加新數(shù)據(jù)之后,我們還要判斷其幅值的大小,即value結(jié)構(gòu)體中的成員變量dValue。我們要把鏈表中所有數(shù)據(jù)的幅值的最大值和最小值,作為設(shè)定Y軸(縱坐標(biāo))標(biāo)尺的依據(jù)。這樣,坐標(biāo)幅度就會(huì)根據(jù)數(shù)據(jù)幅值的變化而變化,繪制出的曲線圖總是會(huì)占據(jù)整個(gè)坐標(biāo)平面,即使數(shù)據(jù)幅值突降至某個(gè)小的幅度波動(dòng),曲線圖也不會(huì)“擠”在一起,極大方便了使用人員的觀測(cè)。
添加新數(shù)據(jù)使用的是clPlot類的AddPoint()函數(shù),該函數(shù)調(diào)用serie類的成員函數(shù)AddPoint()。在serie::AddPoint()中,將新接收的數(shù)據(jù)添加入鏈表中。本文定義了兩個(gè)全局變量m_max和m_min,用來(lái)存放Y軸坐標(biāo)標(biāo)尺的最大值和最小值。這兩個(gè)值如何得到呢?先找出鏈表中數(shù)據(jù)幅值的最大值和最小值,將它們作差,得到一個(gè)差值。m_max即為鏈表中數(shù)據(jù)幅值的最大值加上差值的1%;m_min即為鏈表中數(shù)據(jù)幅值的最小值減去差值的1%。那么將m_max和m_min作為參數(shù),在clPlot::AddPoint()調(diào) 用 函 數(shù)SetLYRange()時(shí),傳 遞 進(jìn)去,來(lái)設(shè)定Y軸的坐標(biāo)標(biāo)尺。根據(jù)新數(shù)據(jù)添加的時(shí)間,調(diào)用函數(shù)SetBXRange(),設(shè)定X軸標(biāo)尺。最后調(diào)用函數(shù)Invalidate(),該函數(shù)的作用是讓窗口的整個(gè)客戶區(qū)無(wú)效,當(dāng)下一個(gè)WM_PAINT消息發(fā)生時(shí),窗口就會(huì)重繪[7]。這樣,每添加一個(gè)新的數(shù)據(jù),就重新畫一次曲線圖,即達(dá)到實(shí)時(shí)顯示的效果。
設(shè)計(jì)流程圖如圖1所示。
圖1 設(shè)計(jì)流程圖Fig.1 Flow chart of design
關(guān)鍵代碼如下:
圖2為非動(dòng)態(tài)顯示。由圖2(a)可以看到,太陽(yáng)處于爆發(fā)時(shí)期,太陽(yáng)溫度在大約45 000度左右波動(dòng)。但是由于浮動(dòng)相對(duì)較小,看不出具體的范圍。等到爆發(fā)活動(dòng)結(jié)束,太陽(yáng)溫度大幅下降??墒怯捎诜莿?dòng)態(tài)顯示的局限性,在圖2(b)上幾乎看不出太陽(yáng)溫度值,更看不清楚波動(dòng)范圍。
圖2 非動(dòng)態(tài)顯示Fig.2 Non-dynamic displaying
圖3 為動(dòng)態(tài)顯示。由圖3(a)可以清晰的反映出太陽(yáng)溫度浮動(dòng)在45 000-45 500度。在14點(diǎn)13分的時(shí)候,太陽(yáng)爆發(fā)活動(dòng)結(jié)束,如圖3(b),太陽(yáng)溫度突降至較小的幅值范圍(300~800度)波動(dòng),坐標(biāo)標(biāo)尺幅值也跟隨變化,如圖3(c),曲線圖也跟隨動(dòng)態(tài)變化,不似圖2那樣壓縮在一起,無(wú)法看清波動(dòng)的范圍。非常便于使用者觀測(cè)。
圖3 動(dòng)態(tài)顯示Fig.3 Dynamic displaying
文中在Visual C++6.0開發(fā)平臺(tái)上,利用MFC類庫(kù),設(shè)計(jì)了太陽(yáng)爆發(fā)活動(dòng)實(shí)時(shí)監(jiān)測(cè)的軟件界面,不僅實(shí)現(xiàn)了對(duì)太陽(yáng)溫度的實(shí)時(shí)監(jiān)測(cè),而且實(shí)現(xiàn)了實(shí)時(shí)數(shù)據(jù)曲線圖的動(dòng)態(tài)顯示。極大地方便了用戶的使用與觀測(cè)。該方法已經(jīng)應(yīng)用于太陽(yáng)爆發(fā)活動(dòng)實(shí)時(shí)監(jiān)測(cè)系統(tǒng)項(xiàng)目中,效果顯著,因而,也可以應(yīng)用在其他工程控制或探測(cè)測(cè)量等領(lǐng)域。
[1]趙融冰,艾力·玉蘇甫,張晉,等.采用VC++的射電望遠(yuǎn)鏡控制軟件在Windows XP下的設(shè)計(jì)和實(shí)現(xiàn)[J].天文研究與技術(shù),2007,4(1):64-71.ZHAO Rong-bing,Aili Yu,ZHANG Jin,et al.Design and realization of radio telescope control software in windows XP system with VC++[J].Astronomical Research&Technology,2007,4(1):64-71.
[2]梁普選.Visual C++程序設(shè)計(jì)與實(shí)踐[M].北京:清華大學(xué)出版社,北京交通大學(xué)出版社,2005.
[3]劉雄鷹.MFC中顯示數(shù)據(jù)控件手工編程綁定數(shù)據(jù)控件[J].電腦與信息技術(shù),2012,20(4):49-51.LIU Xiong-ying.Displaying data control binding data control with manual programming in MFC[J].Computer and Information Technology,2012,20(4):49-51.
[4]仇巍,邢建國(guó).基于MFC的產(chǎn)品結(jié)構(gòu)樹管理系統(tǒng)的實(shí)現(xiàn)[J].中國(guó)制造業(yè)信息化,2012,41(3):11-13.QIU Wei,XING Jian-guo.Development of product structure tree management system based on MFC [J].Manufacture Information Engineering of China,2012,41(3):11-13.
[5]申閆春.Visual C++案例教程[M].北京:清華大學(xué)出版社,北京交通大學(xué)出版社,2010.
[6]陳元琰.Visual C++.NET MFC類庫(kù)應(yīng)用詳解[M].北京:科學(xué)出版社,2004.
[7]孫鑫.VC++深入詳解[M].北京:電子工業(yè)出版社,2012.