I'm looking for opensource Delphi NMEA parser of production grade.
It will be fine if it can meet critical mission requirement (I'm joking! I believe it's not attainable using a Win32 system).
So far, I have played around with basic interfacing of a wrist GPS (Garmin Foretrex 101) through serial port using basic windows API (NMEA 0183).
I have also explored an opensource VCL component to handle experimental serial communication with an aviation model GPS (Garmin Gpsmap 196).
Thanks.
I end up using TComPort and TComDataPacket from the open source TComPort package.
ComPort setting:
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 settings:
object ComDataPacket: TComDataPacket
ComPort = ComPort
StartString = '$'
StopString = '*'
OnPacket = ComDataPacketPacket
Left = 808
Top = 240
end
Excerpt of type used
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 Event handler:
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 processing took place in the event handler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With