#ifndef __UBX_H__ #define __UBX_H__ class UBX_NAV_POSLLH // 0x01 0x02 { public: uint32_t iTOW; // [ms] Time-of-Week int32_t lon; // [1e-7 deg] Longitude int32_t lat; // [1e-7 deg] Latitude int32_t height; // [mm] height above elipsoid (GPS altitude) int32_t hMSL; // [mm] height above Mean Sea Level uint32_t hAcc; // [mm] horizontal accuracy uint32_t vAcc; // [mm] vertical accuracy } ; class UBX_NAV_STATUS // 0x01 0x03 { public: uint32_t iTOW; // [ms] Time-of-Week uint8_t gpsFix; // Fix type: 0:none, 1=dead reckoning, 2:2-D, 3:3-D, 4:GPS+dead reckoning, 5:time-only uint8_t flags; // xxxxTWDF => T:Time-of-Week is valid, W:Week-Number is valid, D:Diff. GPS is used, F:Fix valid uint8_t diffStat; // DD => 00:none, 01:PR+PRR corr., 10: PR+PRR+CP corr., 11: high accuracy PR+PRR+CP uint8_t res; // reserved PR=Pseudo-Range, PRR=Pseudo-Range Rate uint32_t ttff; // [ms] Time To First Fix uint32_t msss; // [ms] Since Startup } ; class UBX_NAV_DOP // 0x01 0x04 { public: uint32_t iTOW; // [ms] Time-of-Week uint16_t gDOP; // [1/100] geometrical uint16_t pDOP; // [1/100] position uint16_t tDOP; // [1/100] time uint16_t vDOP; // [1/100] vertical uint16_t hDOP; // [1/100] horizontal uint16_t nDOP; // [1/100] north-south uint16_t eDOP; // [1/100] east-west uint16_t padding; // padding for round size } ; class UBX_NAV_SOL // 0x01 0x06 { public: uint32_t iTOW; // [ms] Time-of-Week int32_t fTOW; // [ns] Time-of-Week int16_t Week; // [week] uint8_t gpsFix; // 0=none, 1=DR, 2=2D, 3=3D, 4=DR+GPS, 5=time-only uint8_t flags; int32_t ecefX; // [cm] ECEF position int32_t ecefY; // [cm] int32_t ecefZ; // [cm] uint32_t pAcc; // [cm] position accuracy int32_t ecefVX; // [cm/s] ECEF velocity int32_t ecefVY; // [cm/s] int32_t ecefVZ; // [cm/s] uint32_t sAcc; // [cm/s] speed accuracy uint16_t PDOP; // [1/100] uint8_t reserved1; // uint8_t numSV; // [satellites] uint8_t reserved2[4]; // } ; class UBX_NAV_VELNED // 0x01 0x12 { public: uint32_t iTOW; // [ms] Time-of-Week int32_t velN; // [cm/s] velocity North int32_t velE; // [cm/s] velocity East int32_t velD; // [cm/s] velocity Down uint32_t Speed; // [cm/s] velocity uint32_t gSpeed; // [cm/s] ground speed (horizontal velocity) int32_t heading; // [1e-5 deg] ground heading uint32_t sAcc; // [cm/s] speed accuracy uint32_t cAcc; // [1e-5 deg] heading accuracy } ; class UBX_NAV_TIMEGPS // 0x01 0x020 { public: uint32_t iTOW; // [ms] Time-of-Week int32_t fTOW; // [ns] reminder of Time-of-Week uint16_t week; uint8_t leapS; uint8_t valid; // bits: 0:ToW, 1:week, 2:leapS uint32_t tAcc; // [ns] public: static const uint32_t SecsPerWeek = 7*24*60*60; uint8_t Valid(void) const { return (valid&0x03)==0x03; } uint32_t UnixTime() const { return (iTOW+10)/1000 + week*SecsPerWeek + 315964785; } // http://www.andrews.edu/~tzs/timeconv/timedisplay.php } ; class UBX_NAV_TIMEUTC // 0x01 0x21 { public: uint32_t iTOW; // [ms] Time-of-Week uint32_t tAcc; // [ns] accurary estimate int32_t nano; // [ns] uint16_t year; // 1999..2099 uint8_t month; // 1..12 uint8_t day; // 1..31 uint8_t hour; uint8_t min; uint8_t sec; uint8_t valid; // bits: 0:ToW, 1:WN, 2:UTC } ; class UBX_RXM_PMREQ // 0x02 0x41 { public: uint32_t duration; // [ms] uint32_t flags; // bit #1 = enter backup mode } ; class UBX_CFG_CFG { public: uint32_t clearMask; uint32_t saveMask; uint32_t loadMask; uint8_t deviceMask; } ; class UBX_CFG_PRT // 0x06 0x00 { public: uint8_t portID; // 0 = I2C, 1 = UART1, 2 = UART2, 3 = USB, 4 = SPI uint8_t reserved1; uint16_t txReady; // 0 = disable this feature int32_t mode; // 00 10x x 11 x 1 xxxx => 0x08D0 uint32_t baudRate; // [bps] int16_t inProtoMask; // bit 0:UBX, bit 1:NMEA int16_t outProtoMask; // bit 0:UBX, bit 1:NMEA uint16_t flags; // bit 1:extendedTxTimeout uint16_t reserved2; } ; class UBX_CFG_MSG // 0x06 0x01 { public: uint8_t msgClass; // 0xF0:00=GGA, 0xF0:02=GSA, 0xF0:04=RMC, 0xF0:41=TXT uint8_t msgID; uint8_t rate; // message send rate } ; /* class UBX_CFG_MSG // 0x06 0x01 { public: uint8_t msgClass; // 0xF0:00=GGA, 0xF0:02=GSA, 0xF0:04=RMC, 0xF0:41=TXT uint8_t msgID; uint8_t rate[6]; // message send rate } ; */ class UBX_CFG_RATE // 0x06 0x08 { public: uint16_t measRate; // [ms] measurement rate uint16_t navRate; // [cycles] = 1 uint16_t timeRef; // 0=UTC, 1=GPS } ; class UBX_CFG_NAV5 // 0x06 0x24 { public: uint16_t mask; // bit #0 = apply dynamic mode settings, #1 = apply min. elev. settings, #2 = apply fix mode settings uint8_t dynModel; // 6 = airborne 1g, 7 = 2g, 8 = 4g uint8_t fixMode; // 1=2D only, 2=3D only, 3=auto 2/3D int32_t fixAlt; // [0.01m] uint32_t fixAltVar; // [0.001m] int8_t minElev; // [deg] minimum satelite elevation uint8_t drLimit; // [sec] Dead Reconning time limit uint16_t pDop; uint16_t tDop; uint16_t pAcc; // [m] uint16_t tAcc; // [m] uint8_t staticHoldThres; // [cm/s] uint8_t dgpsTimeout; // [s] uint8_t cnoThreshNumSVs; // uint8_t cnoThresh; // [dBHz] uint8_t reserved2[2]; uint32_t reserved3; uint32_t reserved4; } ; // UBX Class packet numbers const uint8_t UBX_NAV = 0x01; // navigation const uint8_t UBX_ACK = 0x05; // acknoledgement of configuration const uint8_t UBX_CFG = 0x06; // configuration class UBX_RxMsg // receiver for the UBX sentences { public: // most information in the UBX packets is already aligned to 32-bit boundary // thus it makes sense to have the packet so aligned when receiving it. static const uint8_t MaxWords=32; // 10; // maximum number of 32-bit words (excl. head and tail) static const uint8_t MaxBytes=4*MaxWords; // max. number of bytes static const uint8_t SyncL=0xB5; // UBX sync bytes static const uint8_t SyncH=0x62; union { uint32_t Word[MaxWords]; // here we store the UBX packet (excl. head and tail) uint8_t Byte[MaxBytes]; } ; uint8_t Class; // Class (01=NAV) uint8_t ID; // ID uint8_t Bytes; // number of bytes in the packet (excl. head and tail) private: uint8_t Padding; // just to make the structure size be a multiple of 4-bytes uint8_t State; // bits: 0:loading, 1:complete, 2:locked, uint8_t Idx; // loading index uint8_t CheckA; // UBX check sum (two bytes) uint8_t CheckB; void CheckInit(void) { CheckA=0; CheckB=0; } // initialize the checksum void CheckPass(uint8_t Byte) { CheckA+=Byte; CheckB+=CheckA; } // pass a byte through the checksum public: void RecalcCheck(void) { CheckInit(); CheckPass(Class); CheckPass(ID); CheckPass(Bytes); CheckPass(0x00); for(uint8_t Idx=0; IdxMaxBytes) { Clear(); return; } break; case 5: // MSB of packet length (expect zero) CheckPass(RxByte); if(RxByte!=0) { Clear(); return; } break; default: // past the header, now load the packet content uint8_t ByteIdx=Idx-6; if(ByteIdx