GPS GPRMC kodlarını parçalayıp okuma

Başlatan mcn, 21 Eylül 2011, 14:45:52

mcn

GPS modüller bir uygulama yapmaya çalışıyorum.Ancak C bilgimin kısıtlı olmasından dolayı bir türlü başaramadım.Biraz uğraştım ancak sadece gelen GPRMC kodunun tamamını parçalayamadan direk 2x16 lcd ye basabiliyorum.Tabi ki bu hiçbi işe yaramıyor.

İsteğim gelen dataları parça parça ayırıp(enlem,boylam,hız,saat vb.) lcd ye yazdırıp kullanabilmek.

Bunun için CCS C forumda kod library de bununla ilgili bir kod buldum,ancak bir türlü kullanamadım bu kodu.Bu kodla enlem boylam ve hız bilgisini 2x16 lcd ye nasıl yazdırabilirim?

/////////////////////////////////////////////////////////////////////////////// 
#include <string.h> 
#include <stdlib.h> 
/////////////////////////////////////////////////////////////////////////////// 
typedef struct _DateTimeInfo 
{ 
   int8 Day; 
   int8 Month; 
   int8 Year; 
   int8 Hour; 
   int8 Minute; 
   int8 Second; 
} DateTimeInfo; 
//////////////////////////////////////// 
typedef struct _GPRMCInfo 
{ 
   char Valid; 
   DateTimeInfo DT; 
   float Latitude; 
   char N_S; 
   float Longitude; 
   char E_W; 
   float Speed; 
} GPRMCInfo; 
/////////////////////////////////////////////////////////////////////////////// 
//copy string (pos n to pos m) from s2 to s1 
char* StrnmCpy(char *s1, char *s2, size_t n, size_t m) 
{ 
   int8 i; 
   char *s; 
    
   for (s=s1, i=n, s2+=n; i<=m; i++) 
      *s++ = *s2++; 
   *s = '\0'; 
    
   return s1; 
} 
/////////////////////////////////////////////////////////////////////////////// 
// find c in s starting from pos st 
int8 StrFnd(char *s, char c, size_t st) 
{ 
   int8 l; 
    
   for (l=st, s+=st ; *s != '\0' ; l++, s++) 
      if (*s == c) 
         return l; 
   return -1; 
} 
/////////////////////////////////////////////////////////////////////////////// 
void GPRMC_decode(char *GPRMCStr, GPRMCInfo *RMCInfo) 
{ 
   int8 p1, p2; 
   char TempStr[16]; 
    
   p1 = StrFnd(GPRMCStr, ',', 0);      //find first comma 
   if (p1 == 6) 
   { 
      //check for valid packet: 
      if ( (StrFnd(GPRMCStr, 'A', p1+1) == 18) && (GPRMCStr[0]=='$')) //valid? 
      { 
         RMCInfo->Valid = 'A'; 
          
         //Get time 
         p1 = StrFnd(GPRMCStr, ',', 0);      //find first comma 
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma 
         RMCInfo->DT.Hour = atoi(StrnmCpy(TempStr, GPRMCStr, p1+1, p1+2));   //hour 
         RMCInfo->DT.Minute = atoi(StrnmCpy(TempStr, GPRMCStr, p1+3, p1+4)); //min 
         RMCInfo->DT.Second = atoi(StrnmCpy(TempStr, GPRMCStr, p1+5, p1+6)); //sec 
          
         //Get latitude & direction 
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma 
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma 
         RMCInfo->Latitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1)); 
         RMCInfo->N_S = GPRMCStr[p2+1]; 
          
         //Get longitude & direction 
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma 
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma 
         RMCInfo->Longitude = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1)); 
         RMCInfo->E_W = GPRMCStr[p2+1]; 
          
         //Get speed 
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma 
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma 
         RMCInfo->Speed = atof(StrnmCpy(TempStr, GPRMCStr, p1+1, p2-1)); 
          
         //Get date 
         p1 = StrFnd(GPRMCStr, ',', p2+1);   //find next comma 
         p2 = StrFnd(GPRMCStr, ',', p1+1);   //find next comma 
         RMCInfo->DT.Day = atoi(StrnmCpy(TempStr, GPRMCStr, p1+1, p1+2));  //dd 
         RMCInfo->DT.Month = atoi(StrnmCpy(TempStr, GPRMCStr, p1+3, p1+4));//mm 
         RMCInfo->DT.year = atoi(StrnmCpy(TempStr, GPRMCStr, p1+5, p1+6)); //yy 
      } 
      else                                //not valid 
      { 
         RMCInfo->Valid = 'V'; 
      } 
   } 
} 
///////////////////////////////////////////////////////////////////////////////


Longitude,Latitude,speed gibi değerleri bir yapı içerisinde tanımlamış,o yüzden şu şekilde kullanmaya çalıştığımda doğal olarak
Longitude adında bir değişken olmadığını söylüyor.

lcd_gotoxy(1,1);
printf(lcd_putc,"%f",Longitude);


Ne yapmam gerek?CCS le GPS uygulaması yapacak arkadaşlara yardımcı olmuş olur bu konu.

Şimdiden teşekkürler.
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer


mcn

Denedim ustam,bu defada bilinmeyen olarak "RMCInfo" yu gösteriyor.
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer

GPRMC_decode fonksiyonunun içinde mi deniyorsunuz dışında mı?

mcn

#4
dışında deniyorum ,void main() fonksiyonunun içinde.

////////////////

İçinde denediğimde hata vermedi.

Bu defada GPRMC_decode fonksiyonunu çağıramıyorum.

void main() içinde bir while(true) döngüsünün içinde GPRMC_decode(); yazıyorum ancak hata veriyor.Geri dönüş değeri olarak ne tanımlamam gerek GPRMC_decode(?,?); nin içine onu anlayamadım?
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer

C için yazıldığı için structure pointer olarak tanımlanmış, CCS'de doğrudan & operatörü kullanılabiliyor. Bu haliyle olsun derseniz biraz bekleyin, örnek hazırlayım.

mcn

Beklemedeyim hocam,bi şekilde olsun da.Şimdiden teşekkürler.
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer


mcn

gelen veri şu şekilde:

Alıntı Yap$GPRMC,142351.000,A,4046.4733,N,02950.1894,E,0.00,0.00,190911,,,A*60
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer

mcn.zip
Alıntı Yap$GPRMC,142351.000,A,4046.4733,N,02950.1894,E,0.00,0.00,190911,,,A*60
karşılığı bu şekilde çıkıyor, kontrol edersiniz:
Alıntı Yap$GPRMC,142351.000,A,4046.4733,N,02950.1894,E,0.00,0.00,190911,,,A*60
Valid: A
Day: 19
Month: 9
Year: 11
Hour: 14
Minute: 23
Second: 51
Latitude: 4046.4732
N_S: N
Longitude: 2950.1898
E_W: E
Speed:    0.0000

Proje Codeblocks için, siz dosyaları kullandığınız ide'ye göre kopyalarsınız.

mcn

Kodu şu şekilde kendime göre düzenledim.

#include "16F887.h"

#fuses INTRC_IO,NOWDT,PUT,NOMCLR,PROTECT,CPD,BROWNOUT,NOIESO,NOFCMEN,NOLVP,NODEBUG,NOWRT,BORV21

#use delay(clock=4000000)

#use RS232(Baud=9600,XMIT=PIN_C6,RCV=PIN_C7,ERRORS)

#include "stdlibm.h"
#include "gprmc.c"

GPRMCInfo *GpsData;

char GpsPtr[70];

void main()
{
   while(1){
   GpsData = (GPRMCInfo *)malloc(sizeof(GpsData));

  // strcpy(GpsPtr,"$GPRMC,142351.000,A,4046.4733,N,02950.1894,E,0.00,0.00,190911,,,A*60");
   //printf("%s",GpsPtr);

   GPRMC_decode(GpsPtr,GpsData);

   printf("\n\rValid: %c",GpsData->Valid);
   printf("\n\rDay: %d",GpsData->DT.Day);
   printf("\n\rMonth: %d",GpsData->DT.Month);
   printf("\n\rYear: %d",GpsData->DT.Year);
   printf("\n\rHour: %d",GpsData->DT.Hour);
   printf("\n\rMinute: %d",GpsData->DT.Minute);
   printf("\n\rSecond: %d",GpsData->DT.Second);
   printf("\n\rLatitude: %9.4f",GpsData->Latitude);
   printf("\n\rN_S: %c",GpsData->N_S);
   printf("\n\rLongitude: %9.4f",GpsData->Longitude);
   printf("\n\rE_W: %c",GpsData->E_W);
   printf("\n\rSpeed: %9.4f",GpsData->Speed);
   }
   
}




Değerler sürekli sıfır geliyor?

Alıntı YapValid:
Day: 0
Month: 17
Year: 16
Hour: 1
Minute: 0
Second: 0
Latitude: 0.0000
N_S:
Longitude: 0.0000
E_W: E
Speed:    0.0000
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer

GpsPtr'ye (yani dışarıdan almanız gereken gps verisine) bir şey atamamışsınız. Ortada parçalanacak veri yok.

mcn

  GpsPtr=getch();


şeklinde bir atama yaptım,gene sıfır değerlerini almamın yanında pic kitleniyor.Seri porttan sürekli bilgi geldiği için buffer dolup tıkanıyor sanırım.Bunu nasıl çözebilirim?
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

-Hasan-

Merhabalar;

mcn arkadaşım GPS modülünü ne kadara, nereden aldınız?

Alıntı Yap$GPRMC,142351.000,A,4046.4733,N,02950.1894,E,0.00,0.00,190911,,,A*60

Bilgiyi parçalamadığınız zaman bu şekilde veri geliyor değil mi?

JKramer

Alıntı yapılan: mcn - 21 Eylül 2011, 18:01:38
  GpsPtr=getch();


getch() ile bir byte alırsınız; GpsPtr, 70 byte'lık bir dizi. Bence gps işine bir virgül koyun, öncelikle seri haberleşme konusunu halledin. Klavyeden gönderdiğiniz verileri kesme kullanarak bir diziye atıp işleyin mesela. Circular buffer konusunu inceleyin, CCS'in forumunda güzel örnekler var. Gps konusunda bilgim yok ama sürekli veri geliyorsa, bunları bir buffer'da saklayıp işinize yarayan kısımları  işlemeniz gerekecek. Mesela paketin başlangıcı $ işaretiyse buffer'da bunu arar, bulduktan sonra o noktadan paketin boyutu kadarlık kısmı GpsPtr'ye atarsınız.