寻找可靠的 Delphi NMEA 解析器

5
我正在寻找一个生产级别的开源 Delphi NMEA 解析器。如果它能满足关键任务要求就更好了(开个玩笑!我相信在 Win32 系统上达不到这个要求)。
到目前为止,我已经使用基本的 Windows API(NMEA 0183)通过串口与手腕 GPS(Garmin Foretrex 101)进行了基本接口测试。
我还尝试过使用开源 VCL 组件处理航空模型 GPS(Garmin Gpsmap 196)的实验性串行通信。
谢谢。

3
不是开源软件,但仍然不错的是ZylSoft的NMEA GPS组件。 - LU RD
@ LU RD:谢谢,ZylSolf 写了很多优秀的组件。 - menjaraz
如果你认为某事不可达成,那为什么还要询问呢?显然,你想要的是可以实现的,没有理由不能实现。 - Security Hound
@Ramhound:我从SO的这篇帖子中学到,在串行通信过程中数据可能会被损坏。例如,在DIY喷洒导航系统中使用基于Win32的解决方案是无意义的。尽管如此,应用程序层面肯定还有改进的空间,但目前我不知道从哪里开始。 - menjaraz
1个回答

4

我最终使用了来自开源TComPort包的TComPortTComDataPacket


串口设置:

  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处理在事件处理程序中进行。

1
这是分享我的发现(在Delphi 2010中测试过)。谢谢。 - menjaraz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接