GPS NMEA Parser (verileri ayrıştırmak)

Başlatan kimlenbu, 22 Mayıs 2014, 12:39:04

kimlenbu

selamlar,

GPS'ten gelen ham verileri ayrıştırmam gerekiyor - enlem, boylam, saat, hız, kaç uyduya bağlı vs. Kodum aşağıdaki şekilde çalışıyor ama hazır bir "ayrıştırıcı" kütüphanesi var mıdır ?

örneğin

GPSOKU(ham_gps_verisi,"enlem") dediğimde bana ham veri içinden istediğimi ayıklayıp çıkaran ?

Kullandığım kod USART1 üzerinden gelen $GPGGA verisinin ilk 5 bilgisini gösteriyor.

extern uint8_t tmpStr100[101];
uint8_t *token;

void USART1_IRQHandler(void){

	// check if the USART1 receive interrupt flag was set
	if( USART_GetITStatus(USART1, USART_IT_RXNE) ){

		static uint8_t cnt = 0; // this counter is used to determine the string length
		static uint8_t DolarBulundu=0;
		static uint8_t SatirSonuBulundu=0;
		uint8_t verino=0;
		uint8_t satir=0;
		char t = USART1->DR; // the character from the USART1 data register is saved in t

		if (t=='$'){DolarBulundu=1;}
		else if (t=='\n'){SatirSonuBulundu=1;}
		
		if(DolarBulundu==1 && SatirSonuBulundu==0)
		{
			tmpStr100[cnt] = t;
			cnt++;
		}
		else if (SatirSonuBulundu==1)
		{ 
			cnt = 0;
			DolarBulundu=0;
			SatirSonuBulundu=0;
			token=strtok(tmpStr100,",");
			if (!strcmp(token,"$GPGGA"))
			{
				while (token!=NULL)
				{
					SSD1963_LCD_ShowString(0,satir,token,BEYAZ,BILGIRENGI,&Font16x24);
					satir+=25;
					verino+=1;
					if (verino==6){break;} //Sadece saat, enlem, boylam bilgisi yeterli oldugu icin diger verilerin gösterilmesini engelledik
					token = strtok(NULL,",");
				}
			}
		}
	}
}

Elektroemre

#1
Merhabalar hocam,

Telit JN3'den gelen GPRMC verileri ayrıştırmak için benzer bir olayı daha önce STM32 için yazmıştım. Kodlar C++ da yazıldı. (Aslında C'de çaktırma )
Virgülleri baz alarak ayrıştırma yapılıyor. Ayrıştırılan veriler struct a dolduruluyor sizde istediğiniz kısmı kullanıyorsunuz.

Header dosyası (GpsJn3.h)
#ifndef __GPSJN3_H
#define __GPSJN3_H

#include "stm32f10x.h"
#include "serial.h"



typedef struct
{
	char Time[16];
	char PosValidatiy; // A:valid, V:NotValid
	
	char Latitude[16];
	char LatitudeDir;  // N/S
	char Longitude[16];
	char LongitudeDir; // W/E
	
	char Speed[16];
	char Heading[16];
	char Date[16];
	
	char MagVar[16];
	char MagVarDir;
	
}GPRMC_t;


class GpsModule
{
private:
	
	
	char LineBuff[128];
	
	bool DataValid;

public:

	GPRMC_t GPRMC;

	GpsModule(void);
	bool DataIsValid(void);
	bool WaitForData(void);
	bool ParseGPRMC(void);
	bool FindKey(char* Str,const char* Key);
	bool CopyUntilComma(char** src,char* dst);
	bool CopySingleCh(char** src,char* dst);

	void DumpGPRMC(void);

	SerialPort GpsSerial;
	
};



#endif // __GPSJN3_H



CPP dosyası (GpsJn3.cpp)
#include "GpsJn3.h"



void GpsModule::DumpGPRMC(void)
{
	GpsSerial.PrintLn("");
	GpsSerial.Print("Time:        ");    GpsSerial.PrintLn(GPRMC.Time);
	GpsSerial.Print("PosValidaty: ");    GpsSerial.putc(GPRMC.PosValidatiy); GpsSerial.PrintLn("");
	GpsSerial.Print("Latitude:    ");    GpsSerial.PrintLn(GPRMC.Latitude);
	GpsSerial.Print("LatitudeDir: ");    GpsSerial.putc(GPRMC.LatitudeDir); GpsSerial.PrintLn("");
	GpsSerial.Print("Longitude:   ");    GpsSerial.PrintLn(GPRMC.Longitude);
	GpsSerial.Print("LongitudeDir:");    GpsSerial.putc(GPRMC.LongitudeDir); GpsSerial.PrintLn("");
	GpsSerial.Print("Speed:       ");    GpsSerial.PrintLn(GPRMC.Speed);
	GpsSerial.Print("Heading:     ");    GpsSerial.PrintLn(GPRMC.Heading);
	GpsSerial.Print("Date:        ");    GpsSerial.PrintLn(GPRMC.Date);
	GpsSerial.Print("MagVar:      ");    GpsSerial.PrintLn(GPRMC.MagVar);
	GpsSerial.Print("MagVarDir:   ");    GpsSerial.putc(GPRMC.MagVarDir); GpsSerial.PrintLn("");
}


GpsModule::GpsModule()
{
	GPRMC.Time[0] = '\0';
	GPRMC.PosValidatiy = 'V'; // A:valid, V:NotValid
	
	GPRMC.Latitude[0] = '\0';
	//GPRMC.LatitudeDir;  // N/S
	GPRMC.Longitude[0] = '\0';
	//GPRMC.LongitudeDir; // W/E
	
	GPRMC.Speed[0] = '\0';
	GPRMC.Heading[0] = '\0';
	GPRMC.Date[0] = '\0';
	
	GPRMC.MagVar[0] = '\0';
	//GPRMC.MagVarDir;
	
	GpsSerial.init(USART2,9600);
	DataValid = false;
	
}

bool GpsModule::DataIsValid(void)
{
	return DataValid;
}

bool GpsModule::WaitForData(void)
{
	GpsSerial.gets(LineBuff,sizeof LineBuff);
	//GpsSerial.PrintLn(LineBuff);
	DataValid = ParseGPRMC();
	return DataValid;
}

bool GpsModule::FindKey(char* Str,const char* Key)
{	
	while(*Key != '\0')
	{		
		if(*Str != *Key)
			return false;	
		
		Str++; Key++;
	}

	return true;
}


bool GpsModule::CopyUntilComma(char** src,char* dst)
{
	int i;
	char* src_temp = *src;
	

	if(*src_temp == ',' || *src_temp == '\0')
	{
		*dst = '\0';
		return true;
	}
	
	for(i = 0; ; i++)
	{		
		dst[i] = *src_temp++;
		
		if(*src_temp == ',' )
		{
			src_temp++;
			dst[i+1] = '\0';
			break;
		}
		else if(*src_temp == '\0')
		{
			return false;
		}
	}
	
	*src = src_temp;
	return true;
	
}

bool GpsModule::CopySingleCh(char** src,char* dst)
{	
	char* src_temp = *src;
	
	if(*src_temp == ',')
	{
		*dst = ' ';
		src_temp++;
	}
	else if(*src_temp == '\0')
	{
		*dst = ' ';
		return false;
	}
	else
	{
		*dst = *src_temp;
		src_temp+=2;
	}
	
	*src = src_temp;
	
	return true;
	
}

bool GpsModule::ParseGPRMC(void)
{
	
	char* LineTemp = LineBuff;
	
	if(!FindKey(LineTemp,"$GPRMC"))
		return false;
	
	LineTemp+=7;
	
	if ( !CopyUntilComma(&LineTemp,GPRMC.Time) ) return false;
	
	if ( !CopySingleCh(&LineTemp,&GPRMC.PosValidatiy) ) return false;
	
	if ( !CopyUntilComma(&LineTemp,GPRMC.Latitude) ) return false;
	if ( !CopySingleCh(&LineTemp,&GPRMC.LatitudeDir) ) return false;
	
	if ( !CopyUntilComma(&LineTemp,GPRMC.Longitude) ) return false;
	if ( !CopySingleCh(&LineTemp,&GPRMC.LongitudeDir) ) return false;
	
	if ( !CopyUntilComma(&LineTemp,GPRMC.Speed) ) return false;
	if ( !CopyUntilComma(&LineTemp,GPRMC.Heading) ) return false;
	if ( !CopyUntilComma(&LineTemp,GPRMC.Date) ) return false;
	
	if ( !CopyUntilComma(&LineTemp,GPRMC.MagVar) ) return false;
	if ( !CopySingleCh(&LineTemp,&GPRMC.MagVarDir) ) return false;
	
	DumpGPRMC();
	
	return true;
}

kimlenbu

sanırım fonksiyon tanımlamalarını C++ tipinden C'ye çevirirsem işimi görür bu :) teşekkürler.

rukiye

selamlar,
gps ten gelen veriyi ayrıstırmam gerekiyor örneğin GPRMC while döngüsüne yazmam  gerek nasıl yapabilirim ?
acil lütfen