#ifndef __NMEA_H__ #define __NMEA_H__ #include uint8_t NMEA_Check(uint8_t *NMEA, uint8_t Len); uint8_t NMEA_AppendCheck(uint8_t *NMEA, uint8_t Len); inline uint8_t NMEA_AppendCheck(char *NMEA, uint8_t Len) { return NMEA_AppendCheck((uint8_t*)NMEA, Len); } uint8_t NMEA_AppendCheckCRNL(uint8_t *NMEA, uint8_t Len); inline uint8_t NMEA_AppendCheckCRNL(char *NMEA, uint8_t Len) { return NMEA_AppendCheckCRNL((uint8_t*)NMEA, Len); } class NMEA_RxMsg // receiver for the NMEA sentences { public: static const uint8_t MaxLen=120; // maximum length static const uint8_t MaxParms=24; // maximum number of parameters (commas) uint8_t Data[MaxLen]; // the message itself uint8_t Len; // number of bytes uint8_t Parms; // number of commas uint8_t Parm[MaxParms]; // offset to each comma uint8_t State; // bits: 0:loading, 1:complete, 2:locked, uint8_t Check; // check sum: should be a XOR of all bytes between '$' and '*' public: void Clear(void) // Clear the frame: discard all data, ready for next message { State=0; Len=0; Parms=0; } void Send(void (*SendByte)(char) ) const { for(uint8_t Idx=0; Idx=Parms) return 0; return Data+Parm[Field]; } uint8_t ParmLen(uint8_t Field) const { if(Field>=Parms) return 0; if(Field==(Parms-1)) return Len-hasCheck()*3-Parm[Field]; return Parm[Field+1]-Parm[Field]-1; } uint8_t isGP(void) const // GPS sentence ? { if(Data[1]!='G') return 0; return Data[2]=='P'; } uint8_t isGL(void) const // GLONASS sentence ? { if(Data[1]!='G') return 0; return Data[2]=='L'; } uint8_t isGA(void) const // GALILEO sentence ? { if(Data[1]!='G') return 0; return Data[2]=='A'; } uint8_t isGN(void) const { if(Data[1]!='G') return 0; return Data[2]=='N'; } uint8_t isBD(void) const // for Beidou GSA and GSV { if(Data[1]!='B') return 0; return Data[2]=='D'; } uint8_t isGx(void) const // GPS or GLONASS sentence ? { return Data[1]=='G'; } uint8_t isGPRMC(void) const // GPS recomended minimum data { if(!isGP()) return 0; if(Data[3]!='R') return 0; if(Data[4]!='M') return 0; return Data[5]=='C'; } uint8_t isGNRMC(void) const // GPS recomended minimum data { if(!isGN()) return 0; if(Data[3]!='R') return 0; if(Data[4]!='M') return 0; return Data[5]=='C'; } uint8_t isGxRMC(void) const // GPS recomended minimum data { if(!isGx()) return 0; if(Data[3]!='R') return 0; if(Data[4]!='M') return 0; return Data[5]=='C'; } uint8_t isGPGGA(void) const // GPS 3-D fix data { if(!isGP()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='G') return 0; return Data[5]=='A'; } uint8_t isGNGGA(void) const // GPS 3-D fix data { if(!isGN()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='G') return 0; return Data[5]=='A'; } uint8_t isGxGGA(void) const // { if(!isGx()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='G') return 0; return Data[5]=='A'; } uint8_t isGxVTG(void) const // velocity relative to the ground { if(!isGx()) return 0; if(Data[3]!='V') return 0; if(Data[4]!='T') return 0; return Data[5]=='G'; } uint8_t isGxZDA(void) const // UTC time+date, time zone { if(!isGx()) return 0; if(Data[3]!='Z') return 0; if(Data[4]!='D') return 0; return Data[5]=='A'; } uint8_t isGPGSA(void) const // GPS satellite data { if(!isGP()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='S') return 0; return Data[5]=='A'; } uint8_t isGNGSA(void) const // { if(!isGN()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='S') return 0; return Data[5]=='A'; } uint8_t isGxGSA(void) const // GP=GPS, GA=Galileo, GL=Glonass, GB=BaiDou, GN=any of the systems combined { if(!isGx()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='S') return 0; return Data[5]=='A'; } uint8_t isGxGSV(void) const // Satellite data { if(!isGx() && !isBD()) return 0; // we include as well $BDGSV if(Data[3]!='G') return 0; if(Data[4]!='S') return 0; return Data[5]=='V'; } uint8_t isGPGSV(void) const // GPS satellite data { if(!isGP()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='S') return 0; return Data[5]=='V'; } uint8_t isGLGSV(void) const // GLONASS satellite data { if(!isGL()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='S') return 0; return Data[5]=='V'; } uint8_t isGAGSV(void) const // GALILEO satellite data { if(!isGA()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='S') return 0; return Data[5]=='V'; } uint8_t isBDGSV(void) const // BEIDOU satellite data { if(!isBD()) return 0; if(Data[3]!='G') return 0; if(Data[4]!='S') return 0; return Data[5]=='V'; } uint8_t isGPTXT(void) const // GPS test message { if(!isGP()) return 0; if(Data[3]!='T') return 0; if(Data[4]!='X') return 0; return Data[5]=='T'; } uint8_t isP(void) const // Private thus specific to the euqipment { return Data[1]=='P'; } uint8_t isPOGN(void) const // OGN dedicated NMEA sentence { if(Data[1]!='P') return 0; if(Data[2]!='O') return 0; if(Data[3]!='G') return 0; return Data[4]=='N'; } uint8_t isPOGNB(void) // barometric report from the OGN tracker { if(!isPOGN()) return 0; return Data[5]=='B'; } uint8_t isPOGNT(void) // other aircraft position (tracking) report from OGN trackers { if(!isPOGN()) return 0; return Data[5]=='T'; } uint8_t isPOGNS(void) // tracker parameters setup { if(!isPOGN()) return 0; return Data[5]=='S'; } uint8_t isPGRMZ(void) // barometric pressure report { if(!isP()) return 0; if(Data[2]!='G') return 0; if(Data[3]!='R') return 0; if(Data[4]!='M') return 0; return Data[5]=='Z'; } uint8_t isPOGNL(void) // log file list request { if(!isPOGN()) return 0; return Data[5]=='L'; } } ; #endif // of __NMEA_H__