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

📄 nmea.cpp

📁 开源GPS源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

NMEA_STATUS NMEAGetGPGSAData( pNMEA_GSA_DATA pNmeaGSVData )
{
	TRACKING_PRNs TrackingPRNs[ 12 ];

	memset( TrackingPRNs, 0, sizeof( TrackingPRNs )  );  
	
	pNmeaGSVData->Mode    = NMEA_MODE_A; // Cliff

	if( GetNavStatus() )
	{
		pNmeaGSVData->FixMode = NMEA_FIX_MODE_3D_FIX;
	}
	else
	{
		pNmeaGSVData->FixMode = NMEA_FIX_MODE_NO_FIX;
	}

	if( gSimulate )
	{
		pNmeaGSVData->FixMode = NMEA_FIX_MODE_3D_FIX;
	}
	
	GetTrackingPRNs( &TrackingPRNs[0] );
	
	for( int i = 0; i < 11; i++ )
	{
		pNmeaGSVData->PRNs[ i ] = TrackingPRNs[ i ].PRN;
	}
	
	if( gSimulate )
	{
		pNmeaGSVData->PRNs[ 0 ] = 7;
		pNmeaGSVData->PRNs[ 1 ] = 9;
		pNmeaGSVData->PRNs[ 2 ] = 24;
		pNmeaGSVData->PRNs[ 3 ] = 4;
	}


	pNmeaGSVData->PDOP = GetPDOP(); // ( float )2.5;
	pNmeaGSVData->HDOP = GetHDOP(); // ( float )1.3;
	pNmeaGSVData->VDOP = GetVDOP(); // ( float )2.1;
	
	return NMEA_SUCCESS;
}

//
// GSA - GPS DOP and active satellites
//
/* 
	GSA - GPS DOP and active satellites. This sentence provides details on the nature of the fix. 
	It includes the numbers of the satellites being used in the current solution and the DOP. DOP 
	(dilution of precision) is an indication of the effect of satellite geometry on the accuracy of the fix.
	It is a unitless number where smaller is better. For 3D fixes using 4 satellites a 1.0 would be considered to 
	be a perfect number, however for overdetermined solutions it is possible to see numbers below 1.0. 

    There are differences in the way the PRN's are presented which can effect the ability of some programs 
	to display this data. For example, in the example shown below there are 5 satellites in the solution and 
	the null fields are scattered indicating that the almanac would show satellites in the null positions that 
	are not being used as part of this solution. Other receivers might output all of the satellites used at the 
	beginning of the sentence with the null field all stacked up at the end. This difference accounts for some 
	satellite display programs not always being able to display the satellites being tracked. Some units may show 
	all satellites that have ephemeris data without regard to their use as part of the solution but this is non-standard. 

  $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39

Where:
     GSA      Satellite status
     A        Auto selection of 2D or 3D fix (M = manual) 
     3        3D fix - values include: 1 = no fix
                                       2 = 2D fix
                                       3 = 3D fix
     04,05... PRNs of satellites used for fix (space for 12) 
     2.5      PDOP (dilution of precision) 
     1.3      Horizontal dilution of precision (HDOP) 
     2.1      Vertical dilution of precision (VDOP)
     *39      the checksum data, always begins with *

*/
NMEA_STATUS NMEASendGPGSA( void )
{
	
	NMEA_GSA_DATA NmeaGSAData;
	char          pFieldBuffer[ MAX_NMEA_FIELD ];
    char          TXBufferIndex = 0;
	char          TransmitBuffer[ MAX_NMEA_BUFFER ];


	memset( TransmitBuffer,0, MAX_NMEA_BUFFER ); 
	
	
	//
	// Get the necessary data from the FW.
	//
	memset( &NmeaGSAData,0, sizeof( NMEA_GSA_DATA ) );
	NMEAGetGPGSAData( &NmeaGSAData );

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

	//
	// Field 0 Mode   
	//
	if( NmeaGSAData.Mode == NMEA_MODE_A )
	{
		strcpy( pFieldBuffer, NMEA_MODE_A_STR );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	}
	else if( NmeaGSAData.Mode == NMEA_MODE_M )
	{
		strcpy( pFieldBuffer, NMEA_MODE_M_STR );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	}
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// Field 1 FixMode
	//
	itoa( NmeaGSAData.FixMode, pFieldBuffer, 10 );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
	
	//
	// Now the satellites
	//
	for( int i = 0; i < 12; i++ )
	{
		if( NmeaGSAData.PRNs[ i ] )
		{
			
			sprintf( pFieldBuffer, "%02d", NmeaGSAData.PRNs[ i ], pFieldBuffer );
			// itoa( NmeaGSAData.PRNs[ i ], pFieldBuffer, 10 );
			NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
			NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
		}
		else
		{
			NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
		}
	}

	//
	// PDOP
	//
	ftoa( NmeaGSAData.PDOP, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// HDOP
	//
	ftoa( NmeaGSAData.HDOP, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
	NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

	//
	// VDOP
	//
	ftoa( NmeaGSAData.VDOP, pFieldBuffer );
	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;
	}
	else
	{
		return NMEA_SUCCESS;
	}
}



NMEA_STATUS NMEAGetGPGSVData( pNMEA_GSV_DATA pNmeaGSVData )
{
	
	pNmeaGSVData->NumberOfSatellites = GetNumberOfVisibleSVs();
	
	//
	// Calculate the number of sentences.
	//
	if( pNmeaGSVData->NumberOfSatellites <= 4 )
	{
		pNmeaGSVData->NumberOfSentences = 1;
	}
	else
	{
		pNmeaGSVData->NumberOfSentences = pNmeaGSVData->NumberOfSatellites/4;
	 
		if( pNmeaGSVData->NumberOfSatellites%4 )
		{
			pNmeaGSVData->NumberOfSentences += 1;
		}
	}

	pVISIBLE_SV_DATA pVisibleSVData = GetVisibleSVData();


	for(  int Satellite = 0; Satellite < pNmeaGSVData->NumberOfSatellites; Satellite++ )
	{
		pNmeaGSVData->SvViewData[ Satellite ].Valid			= 1;
		
		// pNmeaGSVData->SvViewData[ Satellite ].Azimuth		= pVisibleSVData[ Satellite ].azimuth;
	
		if( pVisibleSVData[ Satellite ].azimuth < 0 )
		{
			pNmeaGSVData->SvViewData[ Satellite ].Azimuth = 180 + ( 180 - ( ( abs( pVisibleSVData[ Satellite ].azimuth ) ) ) );
		}
		else
		{
			pNmeaGSVData->SvViewData[ Satellite ].Azimuth		= pVisibleSVData[ Satellite ].azimuth;
		}
		
		pNmeaGSVData->SvViewData[ Satellite ].Elevation     = pVisibleSVData[ Satellite ].elevation;
		pNmeaGSVData->SvViewData[ Satellite ].SatellitePRN  = pVisibleSVData[ Satellite ].PRN;
		pNmeaGSVData->SvViewData[ Satellite ].SNR			= pVisibleSVData[ Satellite ].CNo;
	}

	return NMEA_SUCCESS;	
}

/* 
	GSV - Satellites in View shows data about the satellites that the unit might be able to 
	find based on its viewing mask and almanac data. It also shows current ability to track 
	this data. Note that one GSV sentence only can provide data for up to 4 satellites and thus 
	there may need to be 3 sentences for the full information. It is reasonable for the GSV sentence 
	to contain more satellites than GGA might indicate since GSV may include satellites that are not used
	as part of the solution. It is not a requirment that the GSV sentences all appear in sequence. To avoid 
	overloading the data bandwidth some receivers may place the various sentences in totally different samples 
	since each sentence identifies which one it is. 

	The field called SNR (Signal to Noise Ratio) in the NMEA standard is often referred to as signal strength.
	SNR is an indirect but more useful value that raw signal strength. It can range from 0 to 99 and has 
	units of dB according to the NMEA standard, but the various manufacturers send different ranges of 
	numbers with different starting numbers so the values themselves cannot necessarily be used to evaluate 
	different units. The range of working values in a given gps will usually show a difference of about 25 
	to 35 between the lowest and highest values, however 0 is a special case and may be shown on satellites
	that are in view but not being tracked. 


	$GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75

	Where:
      GSV          Satellites in view
      2            Number of sentences for full data
      1            sentence 1 of 2
      08           Number of satellites in view

      01           Satellite PRN number
      40           Elevation, degrees
      083          Azimuth, degrees
      46           SNR - higher is better
           for up to 4 satellites per sentence
      *75          the checksum data, always begins with *

*/

NMEA_STATUS NMEASendGPGSV( void )
{
	
	NMEA_GSV_DATA NmeaGSVData;
	char          pFieldBuffer[ MAX_NMEA_FIELD ];
    char          TXBufferIndex = 0;
	char          TransmitBuffer[ MAX_NMEA_BUFFER ];
	TRACKING_PRNs TrackingPRNs[ 12 ];

	memset( TransmitBuffer,0, MAX_NMEA_BUFFER ); 
	memset( &NmeaGSVData, 0, sizeof( NMEA_GSV_DATA ) );
	
	//
	// Get the necessary data from the FW.
	//
	NMEAGetGPGSVData( &NmeaGSVData );
	GetTrackingPRNs( &TrackingPRNs[0] );

	int Satellite = 0;

	for( int SequenceNumber = 0; SequenceNumber < NmeaGSVData.NumberOfSentences; SequenceNumber++  )
	{
		TXBufferIndex = 0;
		
		//
		// Add the header
		//
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_START );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_GPGSV );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

		//
		// Field 0 Number of sentences for full data 
		//
		itoa( NmeaGSVData.NumberOfSentences, pFieldBuffer, 10 ); 
		NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );


		
		//
		// Field 1 SequenceNumber
		//
		itoa( SequenceNumber + 1, pFieldBuffer, 10 );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

		//
		// Field 2 Number of satellites in view 
		sprintf( pFieldBuffer, "%02d", NmeaGSVData.NumberOfSatellites );
		//itoa( NmeaGSVData.NumberOfSatellites, pFieldBuffer, 10 );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
		NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

		//
		// Now add the satellite data.
		//
	    for( int NumSatelliteThisSentence = 0; NumSatelliteThisSentence < 4; NumSatelliteThisSentence++ )
		{
			if( NmeaGSVData.SvViewData[ Satellite ].Valid	)
			{
				//
				// PRN
				//
				sprintf( pFieldBuffer, "%02d", NmeaGSVData.SvViewData[ Satellite ].SatellitePRN );
				// itoa( NmeaGSVData.SvViewData[ Satellite ].SatellitePRN, pFieldBuffer, 10 );
				NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
				NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );

				//
				// Elevation
				//
				sprintf( pFieldBuffer, "%02d", NmeaGSVData.SvViewData[ Satellite ].Elevation );
				//itoa( NmeaGSVData.SvViewData[ Satellite ].Elevation, pFieldBuffer, 10 );
				NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
				NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
				
				//
				// Azimuth Needs to be 0 - 360
				//
				
				sprintf( pFieldBuffer, "%03d", NmeaGSVData.SvViewData[ Satellite ].Azimuth );
				// itoa( NmeaGSVData.SvViewData[ Satellite ].Azimuth, pFieldBuffer, 10 );
				NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
				NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
				
				//
				// SNR
				//
				//
				// If we are not tracking then do not display
				// the SNR.
				//
				for( int i = 0; i < 11; i++ )
				{
					//
					// See if we are tracking this guy.
					//
					if( NmeaGSVData.SvViewData[ Satellite ].SatellitePRN == TrackingPRNs[ i ].PRN )
					{
						sprintf( pFieldBuffer, "%02d", NmeaGSVData.SvViewData[ Satellite ].SNR );
						NMEAAddField( TransmitBuffer, &TXBufferIndex, pFieldBuffer );
						break;

					}
								
				}

				if( NumSatelliteThisSentence < 3 )
				{
					NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
				}

			}
			else
			{
				NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
				NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
				NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
				if( NumSatelliteThisSentence < 3 )
				{
					NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );
				}
			}
			Satellite++;
			//SequenceNumber++;
		}

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

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

		memset( TransmitBuffer,0, MAX_NMEA_BUFFER ); 
		     
	}
	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.
     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
     230394       Date - 23rd of March 1994
     003.1,W      Magnetic Variation
     *6A          The checksum data, always begins with *


*/



NMEA_STATUS NMEAGetGPVTGData( pNMEA_VTG_DATA pNmeaVTGData )
{

	pNmeaVTGData->TrueHeading		= GetTrueHeading();
	pNmeaVTGData->MagHeading		= 180.32;
	pNmeaVTGData->GroundSpeedKnots	= GetGroundSpeedKnots();
	pNmeaVTGData->GroundSpeedKilos	= GroundSpeedKilos();

	return NMEA_SUCCESS;
}

/*
VTG - Velocity made good. The gps receiver may use the LC prefix instead of GP if it is emulating Loran output. 

  $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K

where:
        VTG          Track made good and ground speed
        054.7,T      True track made good

⌨️ 快捷键说明

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