李菊葉
(陜西理工學(xué)院計算機科學(xué)與技術(shù)系,漢中723003)
在藥品生產(chǎn)工藝流程中,將藥物原料加工制成具有一定規(guī)格的藥物制品,其中溫度是影響藥品質(zhì)量的一個重要因素.為避免藥品有效成分損失或破壞,在藥物加工過程中,我們需要對反應(yīng)罐的溫度進行實時監(jiān)測.本文實現(xiàn)了對陜西漢江藥業(yè)公司化學(xué)車間生產(chǎn)過程中的化學(xué)反應(yīng)罐溫度的實時監(jiān)測.
在Windows平臺下搭建以IPC為核心的多通道實時數(shù)據(jù)采集系統(tǒng),硬件上選用高速數(shù)據(jù)采集卡,軟件上采用多線程編程技術(shù)及數(shù)字濾波技術(shù),以滿足高速度、高精度的數(shù)據(jù)采集、處理、顯示等多任務(wù)要求.
系統(tǒng)硬件由工控機系統(tǒng)、多功能數(shù)據(jù)采集卡,信號調(diào)理電路組成.采集卡選用研華科技生產(chǎn)的PCI-9113A.每片 PCI-9113A具有 32位 PCI總線,32通道單端或16通道差動輸入;卡上帶有可存儲1024個數(shù)據(jù)的FIFO,即插即用 .
硬件結(jié)構(gòu)上由溫度采集模塊和數(shù)據(jù)處理模塊兩部分組成.采集模塊通過溫度傳感器將實時溫度物理量轉(zhuǎn)換成模擬信號,再由A/D轉(zhuǎn)換器轉(zhuǎn)換為數(shù)字信號并傳至計算機,由計算機進行溫度連續(xù)采集.一個采集模塊可以控制29個溫度傳感器,為了是采樣數(shù)據(jù)更準(zhǔn)確,在每個檢測單元中設(shè)置多個采樣傳感器,并將其放置在制藥罐內(nèi)部不同位置上.硬件原理框圖如圖1所示.
圖1 硬件原理框圖
溫度采集系統(tǒng)的軟件設(shè)計包括參數(shù)設(shè)置、采集、處理、顯示等模塊.參數(shù)設(shè)置模塊主要負責(zé)對數(shù)據(jù)采集系統(tǒng)的運行參數(shù)進行設(shè)置.運行的參數(shù)有:采樣通道號、采樣點數(shù)、采樣周期及各路的上下限報警參數(shù)等;采集模塊負責(zé)從數(shù)據(jù)采集卡上連續(xù)不斷地讀取采樣數(shù)據(jù);顯示模塊實時溫度、溫度曲線等數(shù)據(jù)的實時變化.基于實時性的要求,采樣需要不間斷運行,顯示也同樣需要連續(xù)不間斷,而且顯示模塊所需要的數(shù)據(jù)必須來源于采樣模塊.因此,兩個模塊不僅需要各自同時獨立運行,還要互相協(xié)作,并能實時響應(yīng)用戶發(fā)來的指令,為了滿足這種采樣需求,我們需要運用多線程技術(shù).
PCI-9113A數(shù)據(jù)采集卡具有很完善的軟件支持.在各種軟件環(huán)境下均可使用,本系統(tǒng)所使用的軟件開發(fā)工具C++Builder,其具備功能強大、高效及界面友好等特點,但并不具備直接對硬件I/O地址進行訪問的能力,需要調(diào)用DLL函數(shù)實現(xiàn)對I/O口的訪問和控制.PCI-9113A的開發(fā)商為該卡提供了標(biāo)準(zhǔn)動態(tài)連接庫文件,通過調(diào)用動態(tài)連接庫中的函數(shù)很容易對硬件設(shè)備進行底層的操作.
bool__fastcall TMainForm::StartSample(void)//啟動數(shù)據(jù)采集卡
{
if(DemoFlag)return true;//測試
Card_9113=Register_Card(PCI_9113,0);
if(Card_9113<0)
return false;
else
{
AI_9113_Config(Card_9113,TRIG_INT_PACER);
AI_AsyncDblBufferMode(Card_9113,FALSE);
return true;
}
}
在Windows NT和Window s 9x中,多線程的編程實現(xiàn)需要調(diào)用一系列的 API函數(shù),如 CreateThread、ResumeThread等,比較麻煩且容易出錯.我們使用Inprise公司的新一代RAD開發(fā)工具C++Builder,可以方便地實現(xiàn)多線程的編程.我們利用C++Builder提供的TThread對象,多線程的編程變得非常簡便易用.具體實現(xiàn)方法如下:
在C++Builder IDE環(huán)境下選擇菜單File New,在New 欄中選中Thread Object,按OK,接下來彈出輸入框,輸入 TThread對象子類的名字My Thread,這樣C++Builder自動為你創(chuàng)建了一個名為TMy Thread的 TThread子類.同時編輯器中多了一個名為Unit2.cpp的單元,這就是我們創(chuàng)建的TMy Thread子類的原碼.
制藥罐溫度檢測系統(tǒng)的應(yīng)用程序設(shè)計中的三大部分即(數(shù)據(jù)采集模塊、數(shù)據(jù)處理模塊及顯示模塊)作以介紹,其它部分從略.
2.2.1 采集子線程
在C++Builder環(huán)境下,利用 GlobalAllocPtr函數(shù)來獲得一段內(nèi)存空間,主要用來存放采樣來的數(shù)據(jù).但Windows操作系統(tǒng)中采用的是虛擬存儲的管理機制,通過GlobalAllocPtr函數(shù)獲得的這段內(nèi)存空間隨時都有可能被置換到硬盤上,在讀寫硬盤時所耗費的時間,會導(dǎo)致采樣的不連續(xù)性.為了消除這種不利因素,可以在將緩沖區(qū)的數(shù)據(jù)送往輸入設(shè)備之前,首先調(diào)用GlobalAllocPtr函數(shù)以確保緩沖區(qū)的數(shù)據(jù)不會直接被置換到硬盤上.但是,如果僅僅只為輸入設(shè)備開辟一個新的緩沖區(qū),則當(dāng)該緩沖區(qū)的空間被采樣的數(shù)據(jù)填充滿后,輸入設(shè)備就沒有緩沖區(qū)可以利用,結(jié)果導(dǎo)致采樣的停止,從而造成了采樣的不連續(xù),所以在實際應(yīng)用中 ,至少要為輸入設(shè)備準(zhǔn)備兩個緩沖區(qū)才是合理的.采集模塊的流程圖見圖2.
圖2 采集子線程的流程圖
void__fastcall My Thread::Execute()
PCI-9113A數(shù)據(jù)采集卡提供了非常豐富的采集函數(shù),通過直接調(diào)用其自身攜帶的驅(qū)動程序來啟動數(shù)據(jù)采集卡,并控制其工作.采集過程中,函數(shù)調(diào)用過程如下:調(diào)用PCI-9113A_CreateDevice函數(shù)創(chuàng)建設(shè)備對象,采集卡進入待機狀態(tài),監(jiān)視溫度的變化并同時等待用戶的指令;當(dāng)用戶發(fā)出開始采集的命令后,采集、顯示子線程創(chuàng)建并啟動,采集子線程調(diào)用PCI22300_Read DevBulk AD,批量讀取數(shù)據(jù),一輪采集完成后調(diào)用SetEvent函數(shù)向顯示子線程發(fā)出指令,并開始下一輪的采集.
2.2.2 信號處理子線程
因為在檢測現(xiàn)場傳感器所測到的模擬信號無法完全避免要混雜一些干擾信號,采用數(shù)字濾波來減弱或消除干擾的影響,提高測量的精度和可靠性.以及對分廠32個點的溫度、濕度(實際使用29個點)進行實時監(jiān)測、定期巡檢并可以對任意采集點設(shè)置不同的報警上下限,使其超限報警.采集系統(tǒng)應(yīng)可以周期(周期應(yīng)小于等于5 min)自動采集、存儲數(shù)據(jù).并具有采集點方便擴充能力.32個點的溫度、濕度誤差應(yīng)≤±0.2℃(-25~175℃).采集速度應(yīng)大于32個點/min.所選擇的計算機應(yīng)具有足夠大的空間,以存儲龐大的溫度數(shù)據(jù).部分代碼如下:
AI_ContScanChannels(Card_9113,31,AD_U_10_V,AI_Buf,512*32,(F64)80000,SYNCH_OP);//均值濾波后換算為溫度保存
for(int i=0;i<32;i++)Sum[i]=0;
for(int k=0;k<16384;)
{
for(int i=0;i<32;i++,k++)
{
Sum[i]=Sum[i]+(AI_Buf[k*2]&0x0fff);//************
}
}
for(int i=0;i<32;i++)//采樣、保存、顯示全部通道,存入數(shù)據(jù)庫時只存入已經(jīng)開始批號的通道
{
//temp=Sum[i]/512.0*200/4095-25;
//str=str.FormatFloat("0.00",temp);
//RealTimeArray[i].TempData[RealTime-Array[i].SampleCount]=str.ToDouble();
//Temp Val[i]=Sum[i]/512.0*10/4095*19.858721-24.761047;
Temp Val[i]=(Sum[i]/512.0/4095*200-25)*k[i]+b[i];
if(TimerCount==0)
{
if(RealTimeArray[i].SampleCount==Max-Count)RealTimeArray[i].SampleCount=0;//數(shù)組中最多保存Max Count個數(shù),超過則從頭開始存儲
2.2.3 顯示子線程
數(shù)據(jù)實時顯示模塊主要是為現(xiàn)場工作人員提供很大的方便,他們可以實時觀察各個參數(shù)之間的關(guān)系,為了將數(shù)據(jù)實時的用曲線圖顯示出來,同時又不能影響到數(shù)據(jù)采集的連續(xù)不間斷性,因此顯示模塊就需要作為一個獨立運行的子線程.然而繪圖所必須的數(shù)據(jù)信息完全依附于采集子線程,即顯示模塊必須等待采集子線程的一次數(shù)據(jù)采集任務(wù)完成之后,才能執(zhí)行一次繪圖任務(wù).為了實現(xiàn)這一功能則需要顯示模塊和采集模塊運行時,在兩者之間進行協(xié)調(diào),我們可以通過調(diào)用多線程函數(shù) WaitForSingleObject(hEv2ent,IN FIN I T E)函數(shù)實現(xiàn),IN FIN I T E表示永遠等待,即顯示線程永遠等待采集線程的繪圖指令.顯示模塊流程如圖3所示.
圖3 顯示模塊流程圖
部分代碼如下:
void__fastcall TMainForm::Show ChannelData(bool Draw,bool All)//顯示該實時通道或查詢結(jié)果溫度數(shù)據(jù)及曲線
{
int x,y,num;
float high,low,MaxVal,MinVal,DiffVal;
TColor PenColor;
String str,str1;
TDateTime time1,time2;
long difftime;
if(!Draw)return;
bit1->Canvas->Brush->Color=clWhite;//clMoneyGreen;////clBlack;//clInfoBk;
bit1->Canvas->Fill Rect(Rect(0,0,bit1->W(wǎng)idth-1,bit1->Height-1));//清除原圖形
Label49->Caption="";
Label48->Caption="";
Label53->Caption="";
bit1->Canvas->Pen->W(wǎng)idth=1;//繪上、下限曲線
bit1->Canvas->Pen->Mode=pmCopy;//pmXor
……….}
程序中多個線程同時運行,難免要遇到使用同一系統(tǒng)資源,或者一個線程的運行要依賴另一個線程的完成等,這樣需要在線程間進行同步的問題.在C++Builder中,為我們提供了用于創(chuàng)建Event的TEvent對象供我們使用.首先創(chuàng)建一個全局的TEvent對象作為所有線程可監(jiān)測的標(biāo)志.當(dāng)一個線程完成某項特定的操作時,調(diào)用 TEvent對象的SetEvent()方法,這樣將設(shè)置這個標(biāo)志,其他的線程可以通過監(jiān)測這個標(biāo)志獲知操作的完成.相反,要取消這個標(biāo)志,可以調(diào)用ResetEvent()方法.在需要等待操作完成的線程中使用WaitFor()方法,將一直等待這個標(biāo)志被設(shè)置為止.部分事件同步代碼如下:
hEvent=CreateEvent(NULL,FAUSE,TRUE,NULL);
//采集線程請求事件的對象
WaitForSingleObject(hEvent,INFINITE);
//處理采集任務(wù)
SetEvent(hEvent);//重置事件對象
系統(tǒng)以工業(yè)控制計算機為核心,采用具有多功能數(shù)據(jù)采集卡PCI-9113A,利用C++Builder的多線程編程技術(shù)實現(xiàn)了多通道實時任務(wù)數(shù)據(jù)采集.系統(tǒng)已經(jīng)投入使用,運行穩(wěn)定,可靠性高.
[1]馬建明.數(shù)據(jù)采集與處理技術(shù)[M].西安交通大學(xué)出版社,2005:15-20.
[2]張旭東,付 強,何松華,等.基于PCI接口的多通道高速數(shù)據(jù)采集系統(tǒng)數(shù)據(jù)采集與處理[J].系統(tǒng)工程與電子技術(shù),2000,(6):240-244.
[3]張?zhí)N玉,宋宇明,胡修林,等.多通道高速數(shù)據(jù)采集系統(tǒng)PCI接口的結(jié)構(gòu)設(shè)計[J].華中科技大學(xué)學(xué)報(自然科學(xué)版),2004,32(8):73-75.
[4]王常力.工業(yè)控制計算機系統(tǒng)[J].電子工業(yè)出版社,1993.
[5]陳寬達.C++Builder深度歷險[M].武漢:華中科技大學(xué)出版社,2002.
[6]石學(xué)文,陳 梅,武玉強,等.基于C++Builder的過程控制系統(tǒng)設(shè)計[D].華中科技大學(xué)碩士論文,2002.
[7]喬宗立.一種在C++Builder環(huán)境中調(diào)用Matlab數(shù)據(jù)的方法[J].湖北汽車工業(yè)學(xué)院學(xué)報,2002,15(4):30-33.
[8]劉森林 ,寇光杰.一種基于C++Builder的過程控制系統(tǒng)設(shè)計與實現(xiàn)[J].東南大學(xué)學(xué)報,2003,33(9):158-161.