COM -GPS Receive Interval Problem



  • Hallo,

    Ich habe einen GPS-Empfänger der am USB Port sitzt und mittels USB-To-Serial über die COM Schnittstelle angesprochen wird.

    Also mein Code funktioniert soweit so gut, nur habe ich aktuell das Problem das mein Programm zu schnell die Daten abfrägt und mir die NMEA-0183 Daten nicht als kompletten Satz zurück gibt sondern gestückelt:

    Soll:

    $GPGGA,201154.000,4834.2335,N,00935.9391,E,0,00,,,M,,M,,*41
    

    Das kommt bei mir raus:

    $GPGGA,201155.000,4834.2335,N,00935.9391,E,0,00,,,M,,M,
    ,*40
    

    (Also 2 Zeilen, sollte jedoch eine sein)

    Meine Baudrate: 4800
    Bits: 8

    ReadIntervalTimeout: 15
    ReadTotalMultiplier: 1
    ReadTotalConstant: 1
    ReceiveIntervall: 900
    (Original zwar 1 aber da kommt ein satz in Zig zeilen runter gerasselt)

    Wie finde ich denn das Optionale Receive Interval heraus?
    Welche Zeitangabe ist das Interval? ms? sek?

    Gibts ne möglichkeit mein Abfrage Interval irgendwie zu berechnen oder den Code so zu ändern, das er auf die vollständigen Daten wartet bis zum Ende "\r\n" ?

    Meine Library die Ich nutze:

    TCommThread_Unit.cpp

    //---------------------------------------------------------------------------
    //TCommThread version 6.0 - 30/11/2005
    //Luciano Vieira Koenigkan - e-mail: lucianovk@bol.com.br
    #include <vcl.h>
    #pragma hdrstop
    
    #include "CommThread_Unit.h"
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    
    //   Important: Methods and properties of objects in VCL can only be
    //   used in a method called using Synchronize, for example:
    //
    //      Synchronize(UpdateCaption);
    //
    //   where UpdateCaption could look like:
    //
    //      void __fastcall Unit2::UpdateCaption()
    //      {
    //        Form1->Caption = "Updated in a thread";
    //      }
    //---------------------------------------------------------------------------
    
    __fastcall TCommThread::TCommThread()
            : TThread(true),ReturnMethod(NULL)
    {
            //Inicializando os atributos
            Connected=false;
            FreeOnTerminate = false;
    
    		DeviceName="COM1";
    
            MyDCB.DCBlength=sizeof(DCB);
    		MyDCB.BaudRate=4800;
            MyDCB.ByteSize=8;
            MyDCB.Parity=NOPARITY;
    		MyDCB.StopBits=ONESTOPBIT;
    
    		MyTimeouts.ReadIntervalTimeout=15;
    		MyTimeouts.ReadTotalTimeoutMultiplier=1;
    		MyTimeouts.ReadTotalTimeoutConstant=1;
            MyTimeouts.WriteTotalTimeoutMultiplier=1;
            MyTimeouts.WriteTotalTimeoutConstant=1;
    
            ReceiveQueue=32;
            TransmitQueue=9;
    
            MaxFails=100000;
    
    		ReceiveInterval=1;
    }
    //---------------------------------------------------------------------------
    __fastcall TCommThread::TCommThread(void(__closure *NewReturnMethod)(AnsiString))
            : TThread(true),ReturnMethod(NewReturnMethod)
    {
            //Inicializando os atributos
            Connected=false;
    
            DeviceName="COM1";
    
            MyDCB.DCBlength=sizeof(DCB);
            MyDCB.BaudRate=9600;
            MyDCB.ByteSize=8;
            MyDCB.Parity=NOPARITY;
            MyDCB.StopBits=ONESTOPBIT;
    
            MyTimeouts.ReadIntervalTimeout=15;
            MyTimeouts.ReadTotalTimeoutMultiplier=1;
            MyTimeouts.ReadTotalTimeoutConstant=1;
            MyTimeouts.WriteTotalTimeoutMultiplier=1;
            MyTimeouts.WriteTotalTimeoutConstant=1;
    
            ReceiveQueue=32;
            TransmitQueue=9;
    
            MaxFails=100000;
    
    		ReceiveInterval=1;
    }
    //---------------------------------------------------------------------------
    void __fastcall TCommThread::Execute()
    {
            unsigned long AvailableBytes;
            unsigned long ReadBytes;
    
            while(Terminated==false)
            {
                    Sleep(ReceiveInterval);
                    AvailableBytes=BytesAvailable();
                    if(AvailableBytes>0)
                    {
                            ReceivedData.SetLength(AvailableBytes);
                            if(ReadFile(DeviceHandle,(void*)ReceivedData.data(),AvailableBytes,&ReadBytes,NULL)==true)
                            {
                                    if(ReadBytes>0)
                                    {
                                            Synchronize(AfterReceiveData);
                                            ReceivedData="";
                                    }//if
                            }//if
                    }//if
            }
    }
    //---------------------------------------------------------------------------
    bool TCommThread::Connect(void)
    {
            Synchronize(Open);
            return(Connected);
    }
    //---------------------------------------------------------------------------
    
    bool TCommThread::Disconnect(void)
    {
            Synchronize(Close);
            return(!Connected);
    }
    //---------------------------------------------------------------------------
    bool TCommThread::GetConnected(void)
    {
            return(Connected);
    }
    //---------------------------------------------------------------------------
    void __fastcall TCommThread::AfterReceiveData()
    {
            ReturnMethod(ReceivedData);
    }
    //---------------------------------------------------------------------------
    
    bool TCommThread::TransmitChar(char c)
    {
            unsigned long CEnviados;
            CEnviados=0;
            if(Connected==true)
            {
                    if(WriteFile(DeviceHandle,&c,1,&CEnviados,NULL)!=0)
                            return(true);
                    else
                            return(false);
            }//if
            else
                    return(false);
    }
    //---------------------------------------------------------------------------
    int TCommThread::BytesAvailable(void)
    {
            if(Connected==true)
            {
                    COMSTAT TempStat;
                    DWORD TempDword;
    
                    if(ClearCommError(DeviceHandle,&TempDword,&TempStat)==true)
                    {
                            return(TempStat.cbInQue);
                    }//if
                    else
                            return(0);
            }//if
            else
                    return(0);
    }
    //---------------------------------------------------------------------------
    bool TCommThread::TransmitData(AnsiString Data)
    {
            int i;
            int Fails;
    
            i=1;
            Fails=0;
    
            while((i<=Data.Length())&&(Data.Length()>0)&&(Fails<MaxFails))
            {
                    if(TransmitChar(Data[i])==true)
                    {
                            i++;
                            Fails=0;
                    }
                    else
                    {
                            Fails++;
                    }
            }
            if(Fails<MaxFails)
                    return(true);
            else
                    return(false);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TCommThread::Close()
    {
            if(Connected==true)
            {
    
                    //back to original setings
                    SetCommState(DeviceHandle,&OriginalDCB);
                    SetCommTimeouts(DeviceHandle,&OriginalTimeouts);
    
                    if(CloseHandle(DeviceHandle)!=0)
                    {
                            Connected=false;
                    }//if
                    else
                    {
                            SetCommState(DeviceHandle,&MyDCB);
                            SetCommTimeouts(DeviceHandle,&MyTimeouts);
                    }
    
            }//if
    }
    //---------------------------------------------------------------------------
    void __fastcall TCommThread::Open()
    {
            if(Connected==false)
            {
                    //Open device
                    DeviceHandle=CreateFile(        DeviceName.c_str(),
                                                    GENERIC_READ|GENERIC_WRITE,
                                                    FILE_SHARE_DELETE,
                                                    NULL,
                                                    OPEN_EXISTING,
                                                    FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,
                                                    NULL
                                            );
    
                    if(DeviceHandle!=INVALID_HANDLE_VALUE)
                    {
                            //Make backup and set DCB of open device
                            GetCommState(DeviceHandle,&OriginalDCB);
                            SetCommState(DeviceHandle,&MyDCB);
    
                            //Make backup and set COMMTIMEOUTS of open device
                            GetCommTimeouts(DeviceHandle,&OriginalTimeouts);
                            SetCommTimeouts(DeviceHandle,&MyTimeouts);
    
    						SetupComm(DeviceHandle,1024*ReceiveQueue,1024*TransmitQueue);
                            //Resume Thread
                            if(this->Suspended)
                                    Resume();
                            Connected=true;
                    }//if
            }//if
    }
    //---------------------------------------------------------------------------
    void TCommThread::SetDeviceName(AnsiString NewDeviceName)
    {
            if(Connected==true)
            {
                    Disconnect();
                    DeviceName=NewDeviceName;
                    Connect();
            }
            else
                    DeviceName=NewDeviceName;
    }
    //---------------------------------------------------------------------------
    AnsiString TCommThread::GetDeviceName(void)
    {
            return(DeviceName);
    }
    //---------------------------------------------------------------------------
    HANDLE TCommThread::GetDeviceHandle(void)
    {
            return(DeviceHandle);
    }
    //---------------------------------------------------------------------------
    int TCommThread::GetReceiveQueue(void)
    {
            return(ReceiveQueue);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetReceiveQueue(int NewReceiveQueue)
    {
            if(Connected==true)
            {
                    Disconnect();
                    ReceiveQueue=NewReceiveQueue;
                    Connect();
            }
            else
                    ReceiveQueue=NewReceiveQueue;
    
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetReturnMethod(void(__closure *NewReturnMethod)(AnsiString))
    {
            if(Connected==true)
            {
                    Disconnect();
                    ReturnMethod=NewReturnMethod;
                    Connect();
            }
            else
                    ReturnMethod=NewReturnMethod;
    
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetTransmitQueue(void)
    {
            return(TransmitQueue);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetTransmitQueue(int NewTransmitQueue)
    {
            if(Connected==true)
            {
                    Disconnect();
                    TransmitQueue=NewTransmitQueue;
                    Connect();
            }
            else
                    TransmitQueue=NewTransmitQueue;
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetMaxFails(int NewMaxFails)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MaxFails=NewMaxFails;
                    Connect();
            }
            else
                    MaxFails=NewMaxFails;
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetMaxFails(void)
    {
            return(MaxFails);
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetBaudRate(void)
    {
            return(MyDCB.BaudRate);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetBaudRate(int NewBaudRate)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyDCB.BaudRate=NewBaudRate;
                    Connect();
            }
            else
                    MyDCB.BaudRate=NewBaudRate;
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetByteSize(void)
    {
            return(MyDCB.ByteSize);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetByteSize(int NewByteSize)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyDCB.ByteSize=NewByteSize;
                    Connect();
            }
            else
                    MyDCB.ByteSize=NewByteSize;
    
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetParity(void)
    {
            return(MyDCB.Parity);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetParity(int NewParity)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyDCB.Parity=NewParity;
                    Connect();
            }
            else
                    MyDCB.Parity=NewParity;
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetStopBits(void)
    {
            return(MyDCB.StopBits);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetStopBits(int NewStopBits)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyDCB.StopBits=NewStopBits;
                    Connect();
            }
            else
                    MyDCB.StopBits=NewStopBits;
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetReadIntervalTimeout(void)
    {
            return(MyTimeouts.ReadIntervalTimeout);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetReadIntervalTimeout(int NewReadIntervalTimeout)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyTimeouts.ReadIntervalTimeout=NewReadIntervalTimeout;
                    Connect();
            }
            else
                    MyTimeouts.ReadIntervalTimeout=NewReadIntervalTimeout;
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetReadTotalTimeoutMultiplier(void)
    {
            return(MyTimeouts.ReadTotalTimeoutMultiplier);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetReadTotalTimeoutMultiplier(int NewReadTotalTimeoutMultiplier)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyTimeouts.ReadTotalTimeoutMultiplier=NewReadTotalTimeoutMultiplier;
                    Connect();
            }
            else
                    MyTimeouts.ReadTotalTimeoutMultiplier=NewReadTotalTimeoutMultiplier;
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetReadTotalTimeoutConstant(void)
    {
            return(MyTimeouts.ReadTotalTimeoutConstant);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetReadTotalTimeoutConstant(int NewReadTotalTimeoutConstant)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyTimeouts.ReadTotalTimeoutConstant=NewReadTotalTimeoutConstant;
                    Connect();
            }
            else
                    MyTimeouts.ReadTotalTimeoutConstant=NewReadTotalTimeoutConstant;
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetWriteTotalTimeoutMultiplier(void)
    {
            return(MyTimeouts.WriteTotalTimeoutMultiplier);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetWriteTotalTimeoutMultiplier(int NewWriteTotalTimeoutMultiplier)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyTimeouts.WriteTotalTimeoutMultiplier=NewWriteTotalTimeoutMultiplier;
                    Connect();
            }
            else
                    MyTimeouts.WriteTotalTimeoutMultiplier=NewWriteTotalTimeoutMultiplier;
    }
    //---------------------------------------------------------------------------
    int TCommThread::GetWriteTotalTimeoutConstant(void)
    {
            return(MyTimeouts.WriteTotalTimeoutConstant);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetWriteTotalTimeoutConstant(int NewWriteTotalTimeoutConstant)
    {
            if(Connected==true)
            {
                    Disconnect();
                    MyTimeouts.WriteTotalTimeoutConstant=NewWriteTotalTimeoutConstant;
                    Connect();
            }
            else
                    MyTimeouts.WriteTotalTimeoutConstant=NewWriteTotalTimeoutConstant;
    }
    //---------------------------------------------------------------------------
    
    AnsiString TCommThread::GetAvailableData(void)
    {
            unsigned long AvailableBytes;
    		unsigned long ReadBytes;
    		AnsiString bla="";
    		ReceivedData="";
    		AvailableBytes=BytesAvailable();
    		if(AvailableBytes>0)
    		{
    				ReceivedData.SetLength(AvailableBytes);
    				if(ReadFile(DeviceHandle,(void*)ReceivedData.data(),AvailableBytes,&ReadBytes,NULL)==true)
    				{
    						if(ReadBytes>0)
    						{
    								bla = bla +bla;
    						}//if
    				}//if
    		}
            return(bla);
    }
    //---------------------------------------------------------------------------
    
    void TCommThread::SetReceiveInterval(int NewReceiveInterval)
    {
            ReceiveInterval=NewReceiveInterval;
    }
    //---------------------------------------------------------------------------
    
    int TCommThread::GetReceiveInterval(void)
    {
            return ReceiveInterval;
    }
    //---------------------------------------------------------------------------
    
    TStringList* TCommThread::GetAvailableDevicesNames(bool IncludeSerial, bool IncludeParallel, TStringList * AvaiableDevicesNames)
    {
            TRegistry       *Registro = new TRegistry();
            TStringList     *StringsTemp = new TStringList();
            int Indice;
            if (AvaiableDevicesNames!=NULL)
                    AvaiableDevicesNames->Clear();
            else
                    AvaiableDevicesNames = new TStringList();
    
            Registro->RootKey=HKEY_LOCAL_MACHINE;
    
            if(IncludeSerial==true)
            {
                    StringsTemp->Clear();
    
                    Registro->OpenKey("hardware\\devicemap\\serialcomm",false);
                    Registro->GetValueNames(StringsTemp);
    
                    for (Indice=0;Indice<StringsTemp->Count;Indice++)
                            AvaiableDevicesNames->Add(Registro->ReadString(StringsTemp->Strings[Indice]));
                    Registro->CloseKey();
            }
    
            if(IncludeParallel==true)
            {
                    StringsTemp->Clear();
    
                    Registro->OpenKey("hardware\\devicemap\\parallel ports",false);
                    Registro->GetValueNames(StringsTemp);
    
                    for (Indice=0;Indice<StringsTemp->Count;Indice++)
                            AvaiableDevicesNames->Add(ExtractFileName(Registro->ReadString(StringsTemp->Strings[Indice])));
                    Registro->CloseKey();
            }
            AvaiableDevicesNames->Sort();
            delete Registro;
            delete StringsTemp;
            return AvaiableDevicesNames;
    
    }
    //---------------------------------------------------------------------------
    

    TCommThread_Unit.h

    //---------------------------------------------------------------------------
    //TCommThread version 6.0 - 30/11/2005
    //Luciano Vieira Koenigkan - e-mail: lucianovk@bol.com.br
    
    #ifndef CommThread_UnitH
    #define CommThread_UnitH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Registry.hpp>
    //---------------------------------------------------------------------------
    class TCommThread : public TThread
    {
    private:
            HANDLE DeviceHandle;
            bool Connected;
            AnsiString DeviceName;
            DCB MyDCB;
            DCB OriginalDCB;
            COMMTIMEOUTS MyTimeouts;
            COMMTIMEOUTS OriginalTimeouts;
            int ReceiveQueue;
            int TransmitQueue;
            AnsiString ReceivedData;
            int MaxFails;
            bool Disconnecting;
            int ReceiveInterval;
            void __fastcall AfterReceiveData();
            bool TransmitChar(char c);
            int BytesAvailable(void);
            void __fastcall Close();
            void __fastcall Open();
    protected:
            void __fastcall Execute();
    public:
            __fastcall TCommThread(void(__closure *NewReturnMethod)(AnsiString));
            __fastcall TCommThread();
            void(__closure *ReturnMethod)(AnsiString);
            bool Connect(void);
            bool Disconnect(void);
            bool GetConnected(void);
            bool TransmitData(AnsiString Data);
            void SetDeviceName(AnsiString NewDeviceName);
            AnsiString GetDeviceName(void);
            HANDLE GetDeviceHandle(void);
            int GetReceiveQueue(void);
            void SetReceiveQueue(int NewReceiveQueue);
            int GetTransmitQueue(void);
            void SetTransmitQueue(int NewTransmitQueue);
            void SetMaxFails(int NewMaxFails);
            int GetMaxFails(void);
            int GetBaudRate(void);
            void SetBaudRate(int NewBaudRate);
            int GetByteSize(void);
            void SetByteSize(int NewByteSize);
            int GetParity(void);
            void SetParity(int NewParity);
            int GetStopBits(void);
            void SetStopBits(int NewStopBits);
            int GetReadIntervalTimeout(void);
            void SetReadIntervalTimeout(int NewReadIntervalTimeout);
            int GetReadTotalTimeoutMultiplier(void);
            void SetReadTotalTimeoutMultiplier(int NewReadTotalTimeoutMultiplier);
            int GetReadTotalTimeoutConstant(void);
            void SetReadTotalTimeoutConstant(int NewReadTotalTimeoutConstant);
            int GetWriteTotalTimeoutMultiplier(void);
            void SetWriteTotalTimeoutMultiplier(int NewWriteTotalTimeoutMultiplier);
            int GetWriteTotalTimeoutConstant(void);
            void SetWriteTotalTimeoutConstant(int NewWriteTotalTimeoutConstant);
            void SetReturnMethod(void(__closure *NewReturnMethod)(AnsiString));
            AnsiString GetAvailableData(void);
            void SetReceiveInterval(int NewReceiveInterval);
            int GetReceiveInterval(void);
            TStringList* TCommThread::GetAvailableDevicesNames(bool IncludeSerial, bool IncludeParallel, TStringList * AvaiableDeviceNames);
    };
    //---------------------------------------------------------------------------
    #endif
    


  • ReceiveInterval wird offenebar in Millisekunden verlangt.

    Du müßtest in deiner ReturnMethod die Daten solange puffern, bis ein Zeilenendzeichen ankommt. Danach gibst du den Inhalt des Puffers als Zeile weiter und löscht den Puffer. ReceiveInterval hochdrehen ist keine Lösung für dein Problem.

    Du könntest alternativ versuchen, ReadTotalTimeoutMultiplier zu erhöhen. Das setzt aber, zusammen mit ReadIntervalTimeout, voraus, dass das GPS-Gerät einen kontinuierlichen Datenstrom schickt. Darauf sollte man sich aber, angesichts des Protokolls, das Zeilenendzeichen verwendet, nicht verlassen.



  • Hallo,

    Wie du schon sagtest, das ReceiveInterval hochzudrehen ist keine Lösung, da der Datenstrom vom GPS Receiver dann ins Stocken gerät.

    Wie könnte denn so ein Buffer letzendlich aussehen?

    Könnte in denn ein Zeilenende mit <CR><LF> mit WaitCommEvent in meinem Thread Abwarten um so an eine Vollständige GPS Zeile zu kommen?

    Weil mein Start fängt generell immer mit $GPS an und Endet mit <CR><LF>...



  • Okay hab nun mein Problem gelöst.

    Meine Receive Funktion sieht nun so aus:

    void __fastcall TCommThread::Execute()
    {
            unsigned long AvailableBytes;
    		unsigned long ReadBytes;
    		bool enabled = false;
    
            while(Terminated==false)
            {
    				Sleep(1);
    				AvailableBytes=BytesAvailable();
                    if(AvailableBytes>0)
                    {
                            //ReceivedData.SetLength(AvailableBytes);
                            if(ReadFile(DeviceHandle,Buffer,AvailableBytes,&ReadBytes,NULL)==true)
                            {
                                    if(ReadBytes>0)
    								{
    									AnsiString s;
    									for(DWORD i=0; i < AvailableBytes; i++)
    									{
    										if(Buffer[i] == 0x24) // Warten auf $
    											enabled = true;
    
    										if(Buffer[i] == 0x0d) // Ende <CR>
    											enabled = false;
    
    										if(enabled == true)
    											ReceivedData=ReceivedData+Buffer[i];
    
    										if(enabled == false && ReceivedData != "")
    										{
    											Synchronize(AfterReceiveData); // Ausgeben wenn String fertig
    											ReceivedData="";
    										}
    									}
                                    }//if
                            }//if
                    }//if
            }
    }
    

    Die Ausgabe:

    $GPGLL,4834.3678,N,00935.8617,E,102434.000,V*25
    $GPGSA,A,1,,,,,,,,,,,,,,,*1E
    $GPGSV,2,1,07,32,37,063,,28,05,265,,20,63,261,,23,26,191,*7D
    $GPGSV,2,2,07,01,42,057,,07,30,203,,08,38,238,*44
    $GPRMC,10$GPGGA,102632.000,4834.3678,N,00935.8617,E,0,00,,,M,,M,,*41
    $GPGLL,4834.3678,N,00935.8617,E,102632.000,V*21
    $GPGSA,A,1,,,,,,,,,,,,,,,*1E
    $GPGSV,2,1,06,19,08,169,,14,17,040,,01,41,056,,20,64,262,*74
    $GPGSV,2,2,06,32,36,063,,07,30,202,*7A
    $GPRMC,102632.000,V,4834.3678,N,00935.8617,E,,,080408,,*12
    $GPVTG,,T,,M,,N,,K*4E
    $GPGGA,102633.000,4834.3678,N,00935.8617,E,0,00,,,M,,M,,*40
    $GPGLL,4834.3678,N,00935.8617,E,102633.000,V*20
    $GPGSA,A,1,,,,,,,,,,,,,,,*1E
    $GPGSV,2,1,06,19,08,169,,14,17,040,,01,41,056,,20,64,262,*74
    $GPGSV,2,2,06,32,36,063,,07,30,202,*7A
    $GPRMC,102633.000,V,4834.3678,N,00935.8617,E,,,080408,,*13
    $GPVTG,,T,,M,,N,,K*4E
    

Log in to reply