用VB 實現GPS 信息處理
0 引 言
目前,GPS 已在許多行業和領域得到廣泛應用,但就如何將GPS 有關信息讀入計算機以便進一步處理和應用,仍是大家普遍關心的問題。雖然目前GPS 接收儀的種類、功能各有差異,而且使用的通訊協議也比較多,但許多GPS 生產商都遵循NMEA0183 協議,并且這些GPS 都提供串行通訊接口。筆者試圖從分析GPS 通訊NMEA0183 協議入手,以計算機實時讀取、顯示、存儲、回放GPS信息為例,探討用VB 實現GPS 信息處理的一些方法。
1 GPS 通訊的NMEA 協議
GPS 的通訊協議比較多,其中NMEA (National Ma2rine Electronics Association) , 0183 協議為GPS 接收機和其他航海電子產品的導航數據輸出格式,是目前普遍使用且為大多數生產商遵循的協議之一,以下為其基本通訊參數及報文格式。
1. 1 GPS 串行通訊參數
波特率= 4800 ;無奇偶校驗;數據位= 8 ;停止位= 1
1. 2 NMEA 0183 報文格式
NMEA 0183 協議報文的語句串(ASCII 字符) 格式全部信息可如下表示[1] :
$AAXXX,ddd. . . ddd , 3 hh < CR > < LF >
具體內容為:
$ 串頭,表示串開始
AA 識別符
XXX 語句名
ddd ⋯ddd 數據字段,字母或數字
, 逗號
3 星號,串尾
hh $與3 之間所有字符代碼的校驗和
< CR > 回車控制符
< LF > 換行控制符
1. 3 報文示例說明
在具體的GPS 應用中,不需要用到NMEA 的全部信息,而是根據具體的工作,從中選取所需的信息,忽略其他信息。在文獻[ 1 ]中,給出了用NMEA0813 的$GPGGA語句的數據格式及示例,文中以GPS 推薦的最短數據$GPRMC 語句為例,具體討論協議串中各數據段內容。
1. 3. 1 當GPS 接收儀和衛星的通訊正常時接收到的數據中就包含如下格式的RMC 語句:
$GPRMC,055142,A,3603.3291,N,10346.3723,E,0.0,230.4,250503,1.3,
W,A *3 02
其中數據分別為:
$GPRMC 串頭,其中RMC 為定位語句
055142 表示UTC 24 小時制的標準時間,格式為“時時/分分/秒秒”。根據任務還需要將其轉換為北京時間格式
A 或V 表示信號接收狀態,其中A表示數據“OK,V表示一個警告
3603.3291 表示緯度值,格式為“ddmm.mmmm”
N 或S 標明南北半球,N為北半球(北緯)、S為南半球(南緯)
10346.3723 表示經度值,格式為“dddmm.mmmm”
E 或W 標明東西半球,E為東半球(東經)、W為西半球(西經)
0.0 表示速度, (這里速度為0)
230.4 方位角,范圍為000.0 到359.9度
250503 為UTC 的日期,格式為“日日/月月/年年”
1. 3 地磁變化(磁偏角) ,從000.0 到180.0度
W 地磁變化方向,為E或W
1. 3. 2當沒有和衛星取得聯系時
RMC 語句的顯示格式如下:
$GPRMC, ,V, , , , , , ,270503 ,1.3,W,N *2B
2 VB編程實現
在應用VB 實現對GPS 數據接收和處理時,主要通過串行通訊方式,應用MSComm 控件完成。由于文中涉及內容較多,故只給出編程思想和核心程序段。
2. 1 MSComm 控件應用
2. 1. 1 端口設置
由于GPS串行通訊參數是固定的“波特率=4800 ;無奇偶校驗;數據位=8;停止位=1”,所以在編程時直接設置串口通訊參數就行了。其主要程序段如下[2] :
’NMEA 協議設置
MSComm1.Settings= “4800,N,8,1”
2. 1. 2 數據采集
OnComm 事件被用于捕獲communications 事件及錯誤。因此可在MSComm 控件的OnComm 事件中加入處理函數,以便在文本框區實時顯示、數據采集。
Private Static Sub MSComm1 - OnComm()
’事件信息
Dim Buffer As Variant
Buffer = MSComm1.Input
ShowData txtTerm ,(StrConv(Buffer,vbUnicode))
’在文本框txtTerm 內顯示接收到的GPS 信息
’ShowData 過程實現, 見2.2.4
End Sub
2. 2 GPS 信息顯示的實現
GPS 信息的顯示實際包括兩個方面,一是經過提取處理,顯示需要的信息;二是在文本框內顯示或記錄全部信息(各種語句都顯示) 。在程序實現上,為方便讀取GPS信息, 并提高程序的復用性, 事先設計了兩個類模塊CparseUtils-wjh.cls,GPRMC-wjh.cls和一個標準模塊modTransFun.bas ;同時也設計了一個在文本框區顯示、采集數據的過程showdata。以下為主要功能或實現過程。
2. 2. 1 CparseUtils-wjh 類
該類主要用于求得語句串中數據段的數目和內容,包含兩個函數:
Function Count Parts ( sString As String , Optional sDelim As
String) As Byte ’用于返回協議語句中用“,”分割的段數
Function Parse (ByVal sString As String , iReq As Integer , Op2
tional sDelim As String) As String ’用于分割數據段內容
2. 2. 2 GPRMC-wjh 類
該類實現對接收到的語句進行判斷,并確定各段字符的具體內容。除變量和其他屬性定義外,最核心的一個方法,就是字串判斷,下面列出其程序段:
Public Property Let Sentence (ByVal RMC - Sentence As String)
Dim Utils As New CparseUtils-wjh
’檢查正確的協議語句串頭,以保證為$GPRMC 串
If Utils.Parse (RMC- Sentence , 1) =“$GPRMC”Then
’變量定義部分從略
mvarSentence = RMC - Sentence
’分析NMEA 并檢查效果,如果不滿足控制條件,返回并使變量值為空
sUTC = Utils.Parse (mvarSentence , 2) ’UTC 時間
If IsNumeric (sUTC) Then
mvarUTC = sUTC
End If
sLatitude = Utils.Parse (mvarSentence , 4) ’緯度
If IsNumeric (sLatitude) Then
mvarLatitude = sLatitude
End If
sLatHemis = Utils.Parse (mvarSentence , 5) ’南、北緯
If sLatHemis =“S”Or sLatHemis =“N”Then
mvarLatHemis = sLatHemis
End If
sLongitude = Utils. Parse (mvarSentence , 6) ’經度
If IsNumeric (sLongitude) Then
mvarLongitude = sLongitude
End If
sLonHemis = Utils. Parse (mvarSentence , 7) ’東、西經
If sLonHemis = “E”Or sLonHemis = ”W”Then
mvarLonHemis = sLonHemis
End If
sSpeed = Utils. Parse (mvarSentence , 8) ’速度
If IsNumeric (sSpeed) Then
mvarSpeed = sSpeed
End If
sUTDate = Utils. Parse (mvarSentence , 10) ’日期
If IsNumeric (sUTDate) Then
mvarUTDate = sUTDate
End If
’⋯⋯其他判斷類似,此處從略
End If
Set Utils = Nothing
End Property
2. 2. 3 modTransFun 功能模塊
該模塊給出了坐標格式轉換函數及GPS 信息顯示函數,它們分別為:
Public Function DM2DD(DegreeMinutes As String) As Double
’坐標格式轉換函數,轉換NMEA 協議的“度分”坐標格式為十進制“度度”格式
’實現方法讀者可自己完成
下面主要介紹用于GPS 數據顯示、回放時要用到的playNMEA 過程的實現方法:
Public Sub playNMEA(sArray As Variant )
’直接顯示GPS 數據流,或回放已存在的NMEA 文件
Dim rmc As GPRMC-wjh
Dim Utils As New CparseUtils - wjh
Dim Sentence As Integer
For Sentence = 0 To sCnt - 1
If Utils. Parse (sArray(Sentence) , 1) =“$GPRMC”Then
Set rmc = New GPRMC - wjh
DoEvents
With rmc
. Sentence = sArray(Sentence)
If Not Val ( . Longitude) = 0 Then
’lblX、lblY、lblSpeed、lblUTC、lblDate 分別為用于顯示X、Y
坐標,
’速度,日期,時間的標簽(Label) 控件
’這里只示例了$GPRMC 中幾個主要信息的提取,其他信
息可如法炮制
lblX. Caption = “X: ” & Format (DM2DD ( . Longitude ) ,“000. 0000”) &“”& . LonHemis
lblY. Caption =“Y: ”& Format (DM2DD( . Latitude) ,“ 00.0000”) &“”& . LatHemis
lblSpeed. Caption =“速度: ”& . Speed &“ Km/ h”
lblDate. Caption =“日期: ”& . UTDate
lblUTC. Caption =“時間: ”& . UTC ’這個時間為UTC時間
’根據任務可轉換成北京時間
Else
MsgBox“接收衛星數太少,不能定位!”
’⋯⋯
’賦給lblX、lblY、lblSpeed、lblUTC、lblDate 空串
Exit Sub
End If
End With
End If
Next Sentence
End Sub
2. 2. 4 ShowData 過程
該過程具體實現GPS 信息在文本框區顯示、采集的功能,它通過添加數據到txt Term 控件的Text 屬性,過濾控制字符,如空格、回車、換行, 并且寫數據到一個打開的記錄文件??崭穹麖乃淖髠葎h除,在Text 屬性, 或
者從傳遞字符串中;換行符將被修改為回車; txt Term 控件的Text 屬性的尺寸也被監視,使它不能超過MAX2TERMSIZE 的要求。其實現過程如下:
Private Static Sub ShowData ( Term As Control , Data As String)
On Error GoTo Handler
Const MAXTERMSIZE = 16000
Dim TermSize As Long , i
’以下為顯示GPS 信息時用的變量
Dim InString As String
Dim Utils As New CParseUtils
Dim tempStr As String
Dim n As Integer
Dim cnt As Integer
’確定現存的文本不會太大
TermSize = Len ( Term. Text )
If TermSize > MAXTERMSIZE Then
Term. Text = Mid $( Term. Text , 4097)
TermSize = Len ( Term. Text )
End If
’指到txt Term 的數據的結尾處
Term. SelStart = TermSize
’過濾/ 處理空格符
Do
i = InStr (Data , Chr $(8) )
If i Then
If i = 1 Then
Term. SelStart = TermSize - 1
Term. SelLength = 1
Data = Mid $(Data , i + 1)
Else
Data = Left $(Data , i - 2) & Mid $(Data , i +1)
End If
End If
Loop While i
’除去換行符
Do
i = InStr (Data , Chr $(10) )
If i Then
Data = Left $(Data , i - 1) & Mid $(Data , i + 1)
End If
Loop While i
’確定所有的回車都包含換行符
i = 1
Do
i = InStr (i , Data , Chr $(13) )
If i Then
Data = Left $(Data , i) & Chr $(10) & Mid $(Da2ta , i + 1)
i = i + 1
End If
Loop While i
’添加過濾的數據到SelText 屬性
Term. SelText = Data
’如果需要記錄數據到文件
If hLogFile Then
i = 2
Do
Err = 0
Put hLogFile , , Data
Dim data0 As String
If Err Then
i = MsgBox( Error $, 21)
If i = 2 Then
mnuCloseLog - Click
End If
End If
Loop While i < > 2
End If
Term. SelStart = Len ( Term. Text ) ’定位信息顯示部分開始
InString = Data
cnt = Utils. Count Parts ( InString , Chr (10) )
For n = 0 To cnt - 1
tempStr = Utils. Parse ( InString , n , Chr (10) )
ReDim Preserve sArray(n)
sArray(n) = tempStr
Next n
Set Utils = Nothing
sCnt = cnt
Call playNMEA(sArray) ’顯示部分結束
Exit Sub
Handler :
MsgBox Error $
Resume Next
End Sub
2. 3 實時記錄和保存GPS 數據
程序運行時,如執行“打開記錄文件”,則打開要記錄的文件和端口,在GPS 信息區實時顯示接收到的GPS 報文[ 2 ] ,并錄入到記錄文件中;若執行“關閉記錄文件”,則關閉記錄文件(但文本框中仍然顯示GPS 信息) 。
Private Sub mnuOpenLog - Click()
’執行“打開記錄文件”
Dim replace
On Error Resume Next
With OpenLog ’CommonDialog 控件
. Flags = cdlOFNHideReadOnly Or cdlOFNExplorer
. CancelError = True ’從用戶處獲得記錄
文件名稱
. DialogTitle = “打開記錄文件”
. Filter = “文件格式1 ( 3 . LOG) | 3 . log| 文件格式2 ( 3 . txt) | 3 . txt| 文件格式3 ( 3 . 3 ) | 3 . 3 ”
End With
Do
OpenLog. FileName = “”
OpenLog. ShowOpen
If Err = cdlCancel Then Exit Sub
Temp = OpenLog. FileName
’如果文件已經存在, 詢問用戶是否希望覆蓋此文件或在此文件基礎上添加內容
Ret = Len (Dir $( Temp) )
If Err Then
MsgBox Error $, 48
Exit Sub
End If
If Ret Then
replace = MsgBox(“代替存在的- ”+ Temp +“嗎?”, 35)
Else
replace = 0
End If
Loop While replace = 2
’用戶單擊“確定”按鈕, 則刪除此文件
If replace = 6 Then
Kill Temp
If Err Then
MsgBox Error $, 48
Exit Sub
End If
End If
’打開記錄文件
hLogFile = FreeFile
Open Temp For Binary Aclearcase/" target="_blank" >ccess Write As hLogFile
If Err Then
MsgBox Error $, 48
Close hLogFile
hLogFile = 0
Exit Sub
Else
’到文件結尾處來添加新數據
Seek hLogFile , LOF(hLogFile) + 1
End If
End Sub
Private Sub mnuCloseLog - Click()
’執行“關閉記錄文件”
Close hLogFile
hLogFile = 0
End Sub
2. 4 回放GPS 數據
GPS 數據的回放,是將存有GPS 信息的文件打開,并重新讀取、顯示其信息的過程。它包括一個打開過程[ 2 ]和一個播放過程。具體實現代碼如下(要用到前面給出的模塊中的方法) :
Private Sub mnuOpenBFile - Click()
’讀取存有GPS 信息的回放文件
Dim sFile As String
Dim Sentence
On Error GoTo errorhandle
With OpenBFile
’從用戶處獲得回放文件名稱
. DialogTitle = “打開回放文件”
. Filter = “文件格式1 ( 3 . LOG) | 3 . log| 文件格式2 ( 3 . txt) | 3 . txt| 文件格式3 ( 3 . 3 ) | 3 . 3 ”
. ShowOpen
If Len( . FileName) = 0 Then
Exit Sub
End If
sFile = . FileName
End With
Open sFile For Input As # 1
sCnt = 0
Do While Not EOF (1)
Line Input # 1 , Sentence
ReDim Preserve sArray(sCnt)
sArray(sCnt) = Sentence
sCnt = sCnt + 1
Loop
Close # 1
Exit Sub
errorhandle :
Close # 1
MsgBox“打開文件錯誤!”
End Sub
Private Sub mnuPlayBFile - Click()
’播放GPS 記錄文件
Call playNMEA(sArray)
End Sub
3 結 論
通過對GPS 通訊NMEA 協議的分析,以RMC 語句的“$GPRMC”串為例,給出了開發GPS 數據處理的方法。該方法具有簡單、高效、實用的特點。需要說明的是,用RMC 語句不能讀取高程數據,如果要在應用中讀取高程數據, 可應用文中的方法, 再編寫一個讀GGA 語句(“$GPGGA”串) 的類,其中第9 個數據段就是高程信息。
原文轉自:http://www.anti-gravitydesign.com