用VB開發(fā)多通道儀表數(shù)據(jù)采集程序
發(fā)表時間:2023-07-27 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]1.前言 實時數(shù)據(jù)采集系統(tǒng)過去在DOS操作系統(tǒng)下一般是采用匯編語言開發(fā)制作。隨著Windows操作系統(tǒng)的普及應(yīng)用,數(shù)據(jù)采集及工業(yè)控制等軟件的開發(fā)也上升到 Windows環(huán)境下?梢暬浖_發(fā)平臺...
1.前言
實時數(shù)據(jù)采集系統(tǒng)過去在DOS操作系統(tǒng)下一般是采用匯編語言開發(fā)制作。隨著Windows操作系統(tǒng)的普及應(yīng)用,數(shù)據(jù)采集及工業(yè)控制等軟件的開發(fā)也上升到 Windows環(huán)境下。可視化軟件開發(fā)平臺的出現(xiàn),為軟件開發(fā)提供了強大的圖形界面功能,使得開發(fā)出來的各種應(yīng)用軟件具有良好的人機交互功能。匯編語言的特點是功能強、運行速度快,但編程復(fù)雜、調(diào)試難,而高級語言具有良好的可讀性及方便的調(diào)試手段。
Visual Basic 是Windows環(huán)境下簡單、易學(xué)、高效的可視化編程語言開發(fā)系統(tǒng),以其所見即所得的可視化界面設(shè)計風(fēng)格和32位面向?qū)ο蟮某绦蛟O(shè)計等特點,已廣泛地應(yīng)用于各個領(lǐng)域,是很多計算機軟件開發(fā)人員采用的開發(fā)工具。VB不但提供了良好的界面設(shè)計能力,而且在微機串口通信方面也有很強的功能。采用 VB開發(fā)Winodws下的數(shù)據(jù)采集和工業(yè)控制應(yīng)用軟件十分方便,尤其軟件界面設(shè)計非常便捷,編程工作量較小,開發(fā)周期短,特別適合非計算機專業(yè)的工程技術(shù)人員掌握和使用。
2.MSComm控件特點
MSComm控件是Microsoft提供的擴展控件,用于支持 VB程序?qū)Υ诘脑L問,該控制“隱藏”了大部分串口通訊的底層運行過程和許多煩瑣的處理過程,同時支持查詢方法和事件驅(qū)動通訊的機制,事件驅(qū)動通訊是交互方式處理串口事務(wù)的一種非常有效的方法,特別適合 Windows程序的編寫。在串口通訊過程中,當發(fā)送數(shù)據(jù)、收到數(shù)據(jù)或產(chǎn)生傳輸錯誤時,觸發(fā)MSComm控件的OnComm事件,然后可以通過判斷 CommEvent屬性值獲得事件類型,再根據(jù)事件類型進行相應(yīng)數(shù)據(jù)處理。因此用其實現(xiàn)微機串口的數(shù)據(jù)通訊相當簡單,以很少的程序代碼就可以輕松實現(xiàn)串口的訪問和數(shù)據(jù)通訊。
3.實時數(shù)據(jù)采集示例程序
下面給出的應(yīng)用實例,通過對一臺工業(yè)八通道實時檢測儀表數(shù)據(jù)通訊協(xié)議進行分析,利用VB6.0開發(fā)微機通過串口對多通道工業(yè)儀表進行實時數(shù)據(jù)采集的編程技術(shù)。給出的程序代碼具有通用性,并有詳示,可以直接或稍加改動后用于其它數(shù)據(jù)采集或?qū)崟r控制程序中。
3.1 儀表及其數(shù)據(jù)通訊協(xié)議
這臺工業(yè)用八通道實時檢測儀表,最多可同時接八路高精度位移傳感器,用于測量多點微小形變或微量位移,儀表測量精度為0.01毫米,測量范圍最大值為50毫米。該儀表帶有一個9針的RS-232C串口,能與微機進行串口數(shù)據(jù)通訊,實時傳送檢測數(shù)據(jù),通過微機軟件處理可實現(xiàn)工業(yè)實時監(jiān)控。
該儀表的串口數(shù)據(jù)通訊協(xié)議是:數(shù)據(jù)傳輸速率為9600bps,1位開始位,8位數(shù)據(jù)位,1位停止位,無奇偶校驗位。儀表每秒通過串口發(fā)送200個字節(jié)數(shù)據(jù),由于接入的位移傳感器數(shù)量在 1-8路可調(diào),所以發(fā)送的每幀數(shù)據(jù)長度不定長,隨傳感器數(shù)量多少而變化。儀表數(shù)據(jù)傳輸首先發(fā)送每幀數(shù)據(jù)的開始標志字節(jié),該字節(jié)定義為二進制常數(shù)0FAH;然后發(fā)送1個字節(jié)的通道狀態(tài)字節(jié),該字節(jié)按位順序每位代表相應(yīng)的一路通道狀態(tài),某位是1則代表該通道接有位移傳感器,某位是0則代表該通道未接位移傳感器;從第三個字節(jié)開始按位移傳感器接通的通道順序發(fā)送采集數(shù)據(jù)字節(jié),每道數(shù)據(jù)有三個字節(jié),前2個數(shù)據(jù)字節(jié)采用壓縮的BCD碼編碼方式,第1個數(shù)據(jù)字節(jié)是高位,第2個數(shù)據(jù)字節(jié)是低位,即一個字節(jié)表示兩位十進制數(shù),則兩個字節(jié)表示四位十進制數(shù),小數(shù)點采用固定形式,定義在兩字節(jié)中間;第3個數(shù)據(jù)字節(jié)為符號字節(jié),該字節(jié)第八位為1,即1xxxxxxx則為負數(shù),第八位為0,即0xxxxxxx則為正數(shù)。
例如發(fā)送的字節(jié)數(shù)據(jù)為:0FAH 0B1H 26H 87H 8H 34H 62H 00H 37H 76H 0H 42H 53H 80H
0FAH為幀開始標志字節(jié),第一道,第五道,第六道,第八道接有位移傳感器,表示 -26.87 34.62 37.76 -42.53。
3.2 部分參數(shù)的技術(shù)分析
3.2.1 儀表通訊傳輸速率為9600bps,則最快速度為1.0417ms發(fā)送一個字節(jié);儀表每秒發(fā)送200個字節(jié),平均5.0ms發(fā)送一個字節(jié),在查詢方式或連續(xù)讀取串口數(shù)據(jù)時要在程序中添加循環(huán)等待程序,等待接收緩沖區(qū)收到足夠的字節(jié)才能進行數(shù)據(jù)處理。
3.2.2 儀表發(fā)送每幀數(shù)據(jù)長度不定長,為了實現(xiàn)實時監(jiān)測功能,接收數(shù)據(jù)的讀取要盡可能的快速,則在程序開始運行時設(shè)置MSComm1的屬性
RThreshold = 26 接收緩沖區(qū)收到26個字節(jié)產(chǎn)生OnComm事件
InputLen = 1 Input每次讀取一個字節(jié)
等到程序接收到一幀完整數(shù)據(jù)后,計算出當前幀數(shù)據(jù)長度,再將Rthreshold屬性修改為幀長度,則接收緩沖區(qū)在收到一幀數(shù)據(jù)后,MSComm控件才會觸發(fā)一個OnComm事件,這樣就會有更多的時間進行數(shù)據(jù)的計算和處理。
3.2.3 儀表每秒發(fā)送200個字節(jié)數(shù)據(jù),微機收到一完整幀數(shù)據(jù)至少需要t(ms)時間(只接一道傳感器t=25ms;接八道傳感器t=130ms),然后再進行數(shù)據(jù)處理。如果微機在下一幀數(shù)據(jù)接收前即t ms內(nèi)能將數(shù)據(jù)計算處理完畢,則接收緩沖區(qū)內(nèi)只會保存有一幀數(shù)據(jù),不會存有兩幀以上數(shù)據(jù),接收緩沖區(qū)的大小不會影響實時監(jiān)測效果(接收緩沖區(qū)>=一完整幀長度),這時完全可以實現(xiàn)實時監(jiān)測或?qū)崟r控制;如果微機在t ms內(nèi)不能將數(shù)據(jù)計算處理完畢,接收緩沖區(qū)設(shè)置的又很大,在數(shù)據(jù)計算處理完畢前,接收緩沖區(qū)內(nèi)就會保存有兩幀以上數(shù)據(jù),而且一次工作時間越長,緩沖區(qū)內(nèi)滯留數(shù)據(jù)幀就越多,數(shù)據(jù)采集和數(shù)據(jù)處理之間產(chǎn)生逐漸增大的額外時間差,當接收緩沖區(qū)充滿后,時間差不再增大,固定在某一值,部分數(shù)據(jù)因不能及時采集到接收緩沖區(qū)中,數(shù)據(jù)產(chǎn)生丟失現(xiàn)象,真實工作情況就會和微機處理結(jié)果產(chǎn)生較大的時間差,對實時監(jiān)測和實時控制很不利,這種情況下接收緩沖區(qū)的大小就會影響實時監(jiān)測效果,所以接收緩沖區(qū)設(shè)置不能過大,讓部分數(shù)據(jù)丟失,以保證數(shù)據(jù)處理的實時性。
3.2.4 設(shè)置MSComm控件的接收數(shù)據(jù)模式采用二進制方式,即 InputMode=comInputModeBinary,但用Input屬性讀取數(shù)據(jù)時,不能直接賦值給 Byte 類型變量,只能通過先賦值給一個 Variant 類型變量,返回一個二進制數(shù)據(jù)的數(shù)組,再轉(zhuǎn)換保存到Byte類型數(shù)變量中。
3.2.5 VB中有 Byte類型變量,但沒有字節(jié)的位處理語句。通道狀態(tài)字節(jié)的位處理要通過對該字節(jié)的值運算進行判斷,符號字節(jié)的位處理則要判斷符號字節(jié)的值是否大于127,大于127則為負數(shù);壓縮的BCD碼存入Byte類型變量,VB系統(tǒng)只按十進制數(shù)處理,這要通過一個簡單算法換算,解壓BCD碼才能還原成十進制表示數(shù)值。假如a是Byte類型變量,W是Single類型變量,將一個壓縮的BCD碼存入 a中,則算法是:
。=(a\16)*10 + a-(a\16)*16
則W=a-(a\16)*6
3.3 程序代碼
在(通用)(聲明)中定義程序所用變量:
Dim ab(4) As Byte ‘字節(jié)數(shù)據(jù)類型數(shù)組,用來存貯接收到的一組字節(jié)數(shù)據(jù)
Dim av As Variant ‘用來從接收緩沖區(qū)讀取數(shù)據(jù)
Dim i As Integer
Dim j As Integer
Dim w As Integer ‘接收數(shù)據(jù)個數(shù)計數(shù)器
Dim b1 As Single
Dim b2 As Single
Dim WW As Single ‘十進制檢測值
Dim TD(8) as Boolean ‘通道狀態(tài)數(shù)組
Dim Wmax(8) As Single ‘最大值數(shù)組
Dim Wmin(8) As Single ‘最小值數(shù)組
在窗體中添加名為Command1的[開始]按鈕和名為MSComm1的MSComm控件。
[開始]按鈕的Click事件處理程序主要是對MSComm1控制的參數(shù)初始化設(shè)置,程序中大部分參數(shù)在設(shè)計時可在MSComm1控制的屬性窗口中設(shè)置:
Private Sub Command1_Click() ‘開始按鈕
With MSComm1
.CommPort=2 ‘使用COM2
.Setting="9600,N,8,1" ‘設(shè)置通信口參數(shù)
.InBufferSize=40 ‘設(shè)置MSComm1接收緩沖區(qū)為40字節(jié)
.OutBufferSize=2 ‘設(shè)置MSComm1發(fā)送緩沖區(qū)為2字節(jié)
.InputMode = comInputModeBinary ‘設(shè)置接收數(shù)據(jù)模式為二進制形式
.InputLen = 1 ‘設(shè)置Input 一次從接收緩沖讀取字節(jié)數(shù)為1
.SThreshold = 1 ‘設(shè)置Output 一次從發(fā)送緩沖讀取字節(jié)數(shù)為1
.InBufferCount = 0 ‘清除接收緩沖區(qū)
.OutBufferCount = 0 ‘清除發(fā)送緩沖區(qū)
For i=1 to 8
Wmax(i) = -99 ‘最大值賦初值
Wmin(i) = 99 ‘最小值賦初值
Next i
w = 0 ‘數(shù)據(jù)個數(shù)計數(shù)器清零
.RThreshold = 1 ‘設(shè)置接收一個字節(jié)產(chǎn)生OnComm事件
On Error Resume Next ‘改變錯誤處理的方式。
Err.Clear
If .PortOpen = False Then ‘判斷通信口是否打開
.PortOpen = True ‘打開通信口
If Err Then ‘錯誤處理
MsgBox "串口通信無效"
Exit Sub
End If
End If
End With
End Sub
為了達到實時數(shù)據(jù)采集目的,實時數(shù)據(jù)采集處理程序采用MSComm事件驅(qū)動方式。MSComm1_OnComm 的事件處理程序只處理comEvReceive事件,首先判斷幀數(shù)據(jù)的開始字節(jié),關(guān)閉OnComm接收事件,然后接收數(shù)據(jù)字節(jié),將壓縮BCD進行還原轉(zhuǎn)換,再接收符號字節(jié),判斷數(shù)據(jù)符號,判斷數(shù)據(jù)最大最小值,最后打開OnComm接收事件,等待下一次OnComm事件產(chǎn)生:
Private Sub MSComm1_OnComm()
With MSComm1
Select Case .CommEvent ‘判斷MSComm1通訊事件
Case comEvReceive ‘收到Rthreshold個字節(jié)產(chǎn)生的接收事件
av = .Input ‘讀取一個接收字節(jié)
ab(1) = av(0) ‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
If ab(1) = 170 Then ‘判斷是否為數(shù)據(jù)開始標志,0FAH=170
.RThreshold = 0 ‘關(guān)閉OnComm事件接收
W=W+1 ‘計數(shù)器加1
av = .Input ‘讀取通道狀態(tài)字節(jié)
ab(0) = av(0) ‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)
For i = 1 To 8 ‘通道狀態(tài)數(shù)組復(fù)位
TD(i) = False
Next i
cn = 2 ‘幀長度賦初值,一個開始字,一個狀態(tài)字
If ab(0) >= 128 Then ‘判斷第八通狀態(tài)
TD(8) = True ‘第八道是真
ab(0) = ab(0) - 128 ‘第7位置零
cn = cn + 3 ‘幀長度加3個字節(jié)
End If
If ab(0) >= 64 Then ‘判斷第七通狀態(tài)
TD(7) = True ‘第七道是真
ab(0) = ab(0) - 64 ‘第6位置零
cn = cn + 3 ‘幀長度加3個字節(jié)
End If
If ab(0) >= 32 Then ‘判斷第六通狀態(tài)
TD(6) = True ‘第六道是真
ab(0) = ab(0) - 32 ‘第5位置零
cn = cn + 3 ‘幀長度加3個字節(jié)
End If
If ab(0) >= 16 Then ‘判斷第五通狀態(tài)
TD(5) = True ‘第五道是真
ab(0) = ab(0) - 16 ‘第4位置零
cn = cn + 3 ‘幀長度加3個字節(jié)
End If
If ab(0) >= 8 Then ‘判斷第四通狀態(tài)
TD(4) = True ‘第四道是真
ab(0) = ab(0) - 8 ‘第3位置零
cn = cn + 3 ‘幀長度加3個字節(jié)
End If
If ab(0) >= 4 Then ‘判斷第三通狀態(tài)
TD(3) = True ‘第三道是真
ab(0) = ab(0) - 4 ‘第2位置零
cn = cn + 3 ‘幀長度加3個字節(jié)
End If
If ab(0) >= 2 Then ‘判斷第二通狀態(tài)
TD(2) = True ‘第二道是真
ab(0) = ab(0) - 2 ‘第0位置零
cn = cn + 3 ‘幀長度加3個字節(jié)
End If
If ab(0) >= 1 Then ‘判斷第一通狀態(tài)
TD(1) = True ‘第一道是真
cn = cn + 3 ‘幀長度加3個字節(jié)
End If
For i = 1 To 8 ‘
If TD(i) = True Then
av = .Input ‘讀取第一個數(shù)據(jù)字節(jié)(BCD碼高位字節(jié))
ab(2) = av(0) ‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
av = .Input ‘讀取第二個數(shù)據(jù)字節(jié)(BCD碼低位字節(jié))
ab(3) = av(0) ‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
av = .Input ‘讀取第三個接收字節(jié)(符號位字節(jié))
ab(4) = av(0) ‘轉(zhuǎn)換保存到字節(jié)數(shù)據(jù)類型數(shù)組
b1 = ab(2) - 6 * (ab(2) 16) ‘高位字節(jié)壓縮BCD碼轉(zhuǎn)換為實數(shù)
b2 = ab(3) - 6 * (ab(3) 16) ‘低位字節(jié)壓縮BCD碼轉(zhuǎn)換為實數(shù)
WW = b2 + b1 / 100 ‘數(shù)值組合,標定小數(shù)點
If ab(4) > 127 Then WW = -WW ‘判斷數(shù)據(jù)符號位
Label1(i-1) = Format(WW,"0.00") ‘顯示毫米單位數(shù)值,2位小數(shù)
If WW>Wmax(i) And WW<51 Then ‘判斷最大值,儀表在剛開始工作時有干擾,會傳導(dǎo)一些亂碼,位移傳感器有參數(shù)偏差,最大值一般都略大于50毫米,所以取51為極限最大值,取-51為極限最小值。
Wmax(i) = WW
Label2(i-1)=Format(Wmax(i),"0.00") ‘顯示最大值
End If
If WW -51 Then ‘判斷最小值
Wmin(i) = WW
Label3(i-1)=Format(Wmin(i),"0.00") ‘顯示最小值
End If
End If
Next i
.RThreshold = cn ‘打開MSComm1事件接收
Else
.RThreshold = 1
End If
Case Else
End Select
End With
End Sub