⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nmea.cpp

📁 开源GPS源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        034.4,M      Magnetic track made good
        005.5,N      Ground speed, knots
        010.2,K      Ground speed, Kilometers per hour

Note that, as of the 2.3 release of NMEA, there is a new field in the VTG sentence at the end just prior to the checksum. For more information on this field see here. 

Receivers that don't have a magnetic deviation (variation) table built in will null out the Magnetic track made good. 

 

	$GPVTG
Track Made Good and Ground Speed. 

eg1. $GPVTG,360.0,T,348.7,M,000.0,N,000.0,K*43
eg2. $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*41

           054.7,T      True course made good over ground, degrees
           034.4,M      Magnetic course made good over ground, degrees
           005.5,N      Ground speed, N=Knots
           010.2,K      Ground speed, K=Kilometers per hour

eg3. for NMEA 0183 version 3.00 active the Mode indicator field
     is added at the end
     $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K,A*53
           A            Mode indicator (A=Autonomous, D=Differential,
                        E=Estimated, N=Data not valid)



*/

NMEA_STATUS NMEASendGPVTG( void )
{
	
	NMEA_VTG_DATA NmeaVTGData;
	char          pFieldBuffer[ MAX_NMEA_FIELD ];
    char          TXBufferIndex = 0;
	char          TransmitBuffer[ MAX_NMEA_BUFFER ];


	memset( TransmitBuffer,0, MAX_NMEA_BUFFER ); 
	memset( &NmeaVTGData, 0, sizeof( NMEA_VTG_DATA ) );
	
	//
	// Get the necessary data from the FW.
	//
	NMEAGetGPVTGData( &NmeaVTGData );

	TXBufferIndex = 0;

	//
	// Add the header
	//
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_START );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_GPVTG );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// True heading
	//
	ftoa( NmeaVTGData.TrueHeading, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_TRUE_HEADING );
    NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Mag heading
	//
	ftoa( NmeaVTGData.MagHeading, pFieldBuffer );
//	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_MAG_HEADING );
    NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );


	//
	// Ground speed knots
	//
	ftoa( NmeaVTGData.GroundSpeedKnots, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_KNOTS );
    NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Ground speed kilos
	//
	ftoa( NmeaVTGData.GroundSpeedKilos, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_KILOS );
//    NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
		
	//
	// Check Sum 
	//
	NMEAAddCheckSum( TransmitBuffer, &TXBufferIndex );

	//
	// CR/LF
	//
	NMEAAddCRLF( TransmitBuffer, &TXBufferIndex );

	//
	// Now send the sentence.
	//
	if( !ComPortWrite( ( unsigned char *)&TransmitBuffer[0], TXBufferIndex ) )
	{
		return NMEA_FAILED;
	}
  
	return NMEA_SUCCESS;
}

NMEA_STATUS NMEAGetGPRMCData( pNMEA_RMC_DATA pNmeaRMCData )
{
	DMY Dmy;
	unsigned long DateOfFix;
	//
	// Need to convert from degrees to degrees and minutes format.
	//
	pNmeaRMCData->TimeOfFixUTC  = GetTimeOfFixUTC();

	pNmeaRMCData->Status = NMEA_ACTIVE; // Cliff TODO
	
	pNmeaRMCData->Lat			= ConvertLatLonFromDegreestoDegreesMinutes( GetLatitudeAbs() );

	pNmeaRMCData->NorthSouth    = GetNorthSouth();

	pNmeaRMCData->Long			= ConvertLatLonFromDegreestoDegreesMinutes( GetLongitudeAbs() );
	pNmeaRMCData->EastWest      = GetEastWest();
	

	pNmeaRMCData->GroundSpeedKnots =  GetGroundSpeedKnots();
	pNmeaRMCData->TrueHeading      =  GetTrueHeading(); 
	GetDayMonthYear( &Dmy );

	DateOfFix = ( ( unsigned long )Dmy.Day * 10000 ) + ( ( unsigned long )Dmy.Month * 100 ) + ( ( unsigned long )Dmy.Year - 2000 );
	pNmeaRMCData->DateOfFix        =  DateOfFix;

	return NMEA_SUCCESS;
}

/* 
RMC - NMEA has its own version of essential gps pvt (position, velocity, time) data. It is called RMC, The Recommended Minimum, which will look similar to: 

$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

Where:
     RMC          Recommended Minimum sentence C
     123519       Fix taken at 12:35:19 UTC
     A            Status A=active or V=Void. Not sure what is means??? TODO
     4807.038,N   Latitude 48 deg 07.038' N
     01131.000,E  Longitude 11 deg 31.000' E
     022.4        Speed over the ground in knots
     084.4        Track angle in degrees True
     
	 TODO Why do they have a different DMY format from the one that is in ZDA?? 
	 
	 230394       Date - 23rd of March 1994
     003.1,W      Magnetic Variation
     *6A          The checksum data, always begins with *

Note that, as of the 2.3 release of NMEA, there is a new field in the RMC sentence at the end just prior to the checksum. For more information on this field see here. 

*/

NMEA_STATUS NMEASendGPRMC( void )
{
	
	NMEA_RMC_DATA NmeaRMCData;
	char          pFieldBuffer[ MAX_NMEA_FIELD ];
    char          TXBufferIndex = 0;
	char          TransmitBuffer[ MAX_NMEA_BUFFER ];


	memset( TransmitBuffer,0, MAX_NMEA_BUFFER ); 
	memset( &NmeaRMCData, 0, sizeof( NMEA_RMC_DATA ) );
	
	//
	// Get the necessary data from the FW.
	//
	NMEAGetGPRMCData( &NmeaRMCData );

	TXBufferIndex = 0;

	//
	// Add the header
	//
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_START );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_GPRMC );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );


	//
	// Field 0 Time   
	//
	// The time field must be 6 digits long. If the hour is less than 10 you 
	// must pad it with an extra zero.
	//
    sprintf( pFieldBuffer, "%06ld.00", ( long )NmeaRMCData.TimeOfFixUTC );
//	ftod( NmeaRMCData.TimeOfFixUTC, pFieldBuffer  );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Active or Void
	//
	if( NmeaRMCData.Status == NMEA_ACTIVE )
	{
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_ACTIVE_STR );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	}
	else
	{
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_VOID_STR );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	}
	
	//
	// Field 1 Latitude
	//
    ftod4( NmeaRMCData.Lat, pFieldBuffer ); // 4 decimal places
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Field 2 North/South 
	//
	if( NmeaRMCData.NorthSouth == NMEA_SOUTH )
	{
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_SOUTH );
	}
	else
	{
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_NORTH );
	}

	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Field 3 Longitude
	//
	ftod4( NmeaRMCData.Long, pFieldBuffer ); // 4 decimal places
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );


	//
	// Field 4 East/West
	//
	if( NmeaRMCData.EastWest == NMEA_WEST )
	{
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_WEST );
	}
	else
	{
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_EAST );
	}

	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );



	//
	// Speed over the ground in knots.
	//
	ftodPrecision1( NmeaRMCData.GroundSpeedKnots, pFieldBuffer );
	//ftod( NmeaRMCData.GroundSpeedKnots, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	
	//
	// True heading
	//
	ftodPrecision1( NmeaRMCData.TrueHeading, pFieldBuffer );
	//ftod( NmeaRMCData.TrueHeading, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	
	//
	// Date
	//
	itoa( NmeaRMCData.DateOfFix, pFieldBuffer, 10  );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// MagVar
	//
  	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	
	
	//
	// Check Sum 
	//
	NMEAAddCheckSum( TransmitBuffer, &TXBufferIndex );

	//
	// CR/LF
	//
	NMEAAddCRLF( TransmitBuffer, &TXBufferIndex );

	//
	// Now send the sentence.
	//
	if( !ComPortWrite( ( unsigned char *)&TransmitBuffer[0], TXBufferIndex ) )
	{
		return NMEA_FAILED;
	}
  
	return NMEA_SUCCESS;
}

NMEA_STATUS NMEAGetGPZDAData( pNMEA_ZDA_DATA pNmeaZDAData )
{
	DMY Dmy;

	pNmeaZDAData->HrMinSecUTC		= GetHrMinSecUTC();
	GetDayMonthYear( &Dmy );

	pNmeaZDAData->Day				= Dmy.Day;
	pNmeaZDAData->Month				= Dmy.Month;
	pNmeaZDAData->Year				= Dmy.Year;
	pNmeaZDAData->LocalTimeZoneHr	= 8;    // TODO
	pNmeaZDAData->LocalTimeZoneMin	= 19;	

	return NMEA_SUCCESS;
}


/* 
	ZDA - Data and Time 

	$GPZDA,hhmmss.ss,dd,mm,yyyy,xx,yy*CC
	$GPZDA,201530.00,04,07,2002,00,00*6E

	where:
	hhmmss    HrMinSec(UTC)
		dd,mm,yyy Day,Month,Year
		xx        local zone hours -13..13
		yy        local zone minutes 0..59
		*CC       checksum

  */

NMEA_STATUS NMEASendGPZDA( void )
{
	
	NMEA_ZDA_DATA NmeaZDAData;
	char          pFieldBuffer[ MAX_NMEA_FIELD ];
    char          TXBufferIndex = 0;
	char          TransmitBuffer[ MAX_NMEA_BUFFER ];


	memset( TransmitBuffer,0, MAX_NMEA_BUFFER ); 
	memset( &NmeaZDAData, 0, sizeof( NMEA_ZDA_DATA ) );
	
	//
	// Get the necessary data from the FW.
	//
	NMEAGetGPZDAData( &NmeaZDAData );

	TXBufferIndex = 0;

	//
	// Add the header
	//
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_START );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_GPZDA );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Time   
	//
	// The time field must be 6 digits long. If the hour is less than 10 you 
	// must pad it with an extra zero.
	//
	sprintf( pFieldBuffer, "%06ld.00", ( long )NmeaZDAData.HrMinSecUTC );
//	ftod( NmeaZDAData.HrMinSecUTC, pFieldBuffer  );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Day  
	//
	sprintf( pFieldBuffer, "%02d", NmeaZDAData.Day );
	//itoa( NmeaZDAData.Day, pFieldBuffer, 10  );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Month   
	//
	sprintf( pFieldBuffer, "%02d", NmeaZDAData.Month );
	//itoa( NmeaZDAData.Month, pFieldBuffer, 10 );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Year 
	//
	itoa( NmeaZDAData.Year, pFieldBuffer, 10  );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );


	//
	// Local time offset hour from UTC 
	//
	sprintf( pFieldBuffer, "%02d", NmeaZDAData.LocalTimeZoneHr );
	//itoa( NmeaZDAData.LocalTimeZoneHr, pFieldBuffer, 10  );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );


	//
	// Local time offset minute from UTC  
	//
	sprintf( pFieldBuffer, "%02d", NmeaZDAData.LocalTimeZoneMin );
	//itoa( NmeaZDAData.LocalTimeZoneMin, pFieldBuffer, 10  );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	// NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Check Sum 
	//
	NMEAAddCheckSum( TransmitBuffer, &TXBufferIndex );

	//
	// CR/LF
	//
	NMEAAddCRLF( TransmitBuffer, &TXBufferIndex );

	//
	// Now send the sentence.
	//
	if( !ComPortWrite( ( unsigned char *)&TransmitBuffer[0], TXBufferIndex ) )
	{
		return NMEA_FAILED;
	}
  
	return NMEA_SUCCESS;
}

void ftoaPrecision0( float value, char* strFloat ) 
{
	sprintf( strFloat, "%d", value); 
} 


void ftoa( float value, char* strFloat ) 
{
	sprintf( strFloat, "%.2f", value); 
} 

void ftod( double value, char* strDouble )
{
	sprintf( strDouble, "%.2f", value );
}

void ftodPrecision1( double value, char* strDouble )
{
	sprintf( strDouble, "%.1f", value );
}

void ftod4( double value, char* strDouble )
{
	sprintf( strDouble, "%.4f", value );  // added two more decimal places
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -