我正在寻找生产级的开源Delphi NMEA解析器。
如果它可以满足关键任务要求,那就很好(我在开玩笑!我相信使用Win32系统无法实现)。
到目前为止,我已经使用基本的Windows API(NMEA 0183)通过串行端口尝试了腕式GPS(Garmin Foretrex 101)的基本接口。
我还探索了一个开源VCL组件,以处理与航空模型GPS(Garmin Gpsmap 196)进行的实验性串行通信。
谢谢。
最佳答案
我最终使用了来自开源TComPort包的TComPort和TComDataPacket。
ComPort设置:
object ComPort: TComPort
BaudRate = br4800
Port = 'COM1'
Parity.Bits = prNone
StopBits = sbTwoStopBits
DataBits = dbEight
Events = [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak, evCTS, evDSR, evError, evRLSD, evRx80Full]
FlowControl.OutCTSFlow = False
FlowControl.OutDSRFlow = False
FlowControl.ControlDTR = dtrDisable
FlowControl.ControlRTS = rtsDisable
FlowControl.XonXoffOut = False
FlowControl.XonXoffIn = False
SyncMethod = smWindowSync
OnAfterOpen = ComPortAfterOpen
OnAfterClose = ComPortAfterClose
Left = 904
Top = 192
end
ComDataPacket设置:
object ComDataPacket: TComDataPacket
ComPort = ComPort
StartString = '$'
StopString = '*'
OnPacket = ComDataPacketPacket
Left = 808
Top = 240
end
使用类型摘录
type
// NMEA 0185's messages used
TMsgGP = (
msgGP, // Unknown message
msgGPGGA, // Global Positioning System Fix Data
msgGPGLL, // Geographic position, Latitude and Longitude
msgGPGSV, // Satellites in view
msgGPRMA, // Recommended minimum specific GPS/Transit data Loran C
msgGPRMC, // Recommended minimum specific GPS/Transit data
msgGPZDA // Date and time
);
// Satellite properties
TSatellite = record
Identification: ShortInt;
Elevation: 0..90;
Azimut: Smallint;
SignLevel: Smallint;
end;
// Array of satellites referenced
TSatellites = array[1..MAX_SATS] of TSatellite;
// GPS status informations
TGPSDatas = record
Latitude: Double;
Longitude: Double;
HeightAboveSea: Double;
Speed: Double;
UTCTime: TDateTime;
Valid: Boolean;
NbrSats: Shortint;
NbrSatsUsed: Shortint;
end;
ComDataPacketPacket事件处理程序:
procedure TForm1.ComDataPacketPacket(Sender: TObject; const Str: string);
var
Resultat: TStringList;
MsgCorrect, TypeMsg: string;
i: Integer;
begin
Resultat := TStringList.Create;
try
// Split the message into different parts.
MsgCorrect := AnsiReplaceStr('$'+Str, ',,', ' , , ');
Resultat.Text := AnsiReplaceStr(LeftStr(MsgCorrect, Length(MsgCorrect) - 1), ',', #13#10);
// Get the message type
TypeMsg := AnsiMidStr(Resultat[0], 4, 3);
case IndexMsgGP(TypeMsg) of
msgGPGGA:
begin
end;
msgGPGLL:
begin
end;
msgGPGSV:
begin
// If there are satellites referenced in the frame
if Resultat.Count < 4 then
FGPSDatas.NbrSats := 0
else
FGPSDatas.NbrSats := StrToInteger(Resultat[3]);
if Resultat[2] = '1' then
begin
FSatRef := 0;
// Initiate satellites values
for i := 1 to 12 do
with FSatellites[i] do
begin
Identification := 0;
Elevation := 0;
Azimut := 0;
SignLevel := 0;
end;
end;
i := 4;
// For each referenced satellites
while (i + 4) <= (Resultat.Count) do
begin
with FSatellites[FSatRef + 1] do
begin
Identification := StrToInteger(Resultat[i]);
Elevation := StrToInteger(Resultat[i + 1]);
Azimut := StrToInteger(Resultat[i + 2]);
if Resultat[i + 3] <> '' then
SignLevel := StrToInteger(Resultat[i + 3])
else
SignLevel := 0;
end;
Inc(i, 4);
Inc(FSatRef);
end;
end;
msgGPRMA:
begin
end;
msgGPRMC:
begin
end;
msgGPZDA:
begin
end;
else
end;
finally
Resultat.Free;
end;
end;
NMEA处理在事件处理程序中进行。