Aradığım karakterleri bulamıyorum ?

Başlatan tekniker_murat, 22 Kasım 2019, 00:20:51

tekniker_murat

Herkese selamun aleyküm.

Değerli ustalarım her geçen gün ömürden yiyor ve boşa geçen her gün için ayrıca bir yazık oluyor...

Bu günlerde şu gps konum sensörlerine biraz bulaşmış buldum kendimi ve araştırmalarım neticesinde NMEA 0183 adında bir protokol ile seri port üzerinden 9600 baud rate ile haberleştiğini öğrendim.

Elbette biraz da nmea protokolünü araştırdım...

Protokol gereği her gelen bilginin başında '$' karakteri var ve ardından 'G''P' karakteri geliyor bunlar standart ama bunlardan sonra gelen karakterler uydudan her saniye gönderilen verilerin özelliğini belirliyor...

UTC zamanını nerede olduğunun kordinatını vs şeklinde gidiyor...

$GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45

Şeklinde daima bir bilgi akışı söz konusu. Bir sürü kaynağı ve örneği inceledikten sonra benim işleme almam gerekli olan kısmı ya $GPGGA yada $GPRMC bu ikisi de benim işi çözecek gibi görünüyor lakin ben şöyle bir kod yazdım...


unsigned int    index;
char    gelen[1400];

void main() {
adcon1=7;
trise=0;
porte=0;
trisa=0;
porta=0;
trisb=0;
portb=0;
index=0;
gelen[1400]=0;

  UART1_Init(9600);               // Initialize UART module at 9600 bps
  Delay_ms(100);                  // Wait for UART module to stabilize

  UART1_Write_Text("Start");
  UART1_Write(10);
  UART1_Write(13);
        
        Glcd_Init();                                   // Initialize GLCD
        Glcd_Fill(0x00);                               // Clear GLCD

        while           (1){

        if (UART1_Data_Ready()==1) {
        gelen[index] = UART1_Read();
        index++;
        if      (index >=1400){
        yaz();
        }
        }} }


Bu kod ile amacım şu gelen adında 1400 elemanlı bir alan oluşturdum ve her data alışımda index'i 1 arttırdım sonra indexin 1400 e eşit yada büyük olduğu durumda aldığım dataları yazdıracağım alt programı çağırdım...

Elbette bir çok değişik program ve denemelerim oldu ama sadece takip edebildiğim dataların geldiği oldu... yani datalar yukarıdaki örnekte de verdiğim gibi sırası ile geliyor... tabi ben beceremedim tek satırda devamlı akıp giderken gördüm :D

Şimdi benim içinden çıkamadığım yer aslında mikroc dili ile alakalı...

Bu kod ile 1400 tane 8 bitlik veriyi 1400 ayrı adrese alabiliyorum ama ayıklayamıyorum...

ben istiyorum ki öyle bir program yapayım ki örneğin ilk gelen karakter hangisi $ işareti ben bi defa bu 1400 verinin içinde ilk olarak $ karakterini bulayım

$ karakterini bulduktan sonra arkasındaki karakterin G olduğunu üçüncü karakterin P olduğunu 4. karakterin G olduğunu bulayım ve gpgga yı bulduktan sonra bir dahaki $ karakterine kadar olan verileri yerini bildiğim için kümenin elemanları gibi tek tek sırası ile yazdırayım...

Elbette yazdırma yaparken uyduya bağlı mı değil mi kaç uydudan sinyal alışı var gibi verileri de if gibi komutlarla test edebileyim çünkü veriler alınmış sıraya dizilmiş olacak...

Mesela uyduya bağlandığı anda veriyi almaya başladı ve ilk 400 karakteri doldurdu şimdi ben bu ilk 400 karakterin içinde aradığım karakterleri ve indeks numaralarını tespit edemiyorum.

Sizce nasıl bir yol izlemem gerekir ?

[email]murat.yagci.1984@gmail.com[/email]

kartal0689

"GP" metni zaten standart. sonrasında gelen GGA veya RMC dataları geldikten sonra verileri okusan olur.
diğerlerini değişkene aktarmak zorunda değilsin. aşağıda örnek bir kod veriyorum.

Procedure Uart1_GpsDataReceiveInterrupt(); iv IVT_ADDR_U1RXINTERRUPT;
 begin
 


    if (Temp1 =0) then
      begin
          Receive := UART1_Read();
          if (Receive = '$') then
            begin
                 Temp1 := 1;
                 Temp2 := 2;
            end;
      end;

    if (Temp2 = 2) then
      begin
          UART1_Read_Text(DataType, ',', 6);
          Temp2 := 3;
          Temp3 := 3;
          Temp1 := 0;

      end;
      
    if ((DataType[2] = 'G')and(DataType[3] = 'G')and(DataType[4] = 'A')) then //GPGGA
      begin

           if (Temp3 = 3) then
             begin

                  UART1_Read_Text(NMEA, '*', 100);
                  Temp3 := 4;
                  Temp2 := 2;
                  Temp1 := 0;
                  
                  //PcWriteAllow      := 1;
                  GPSnotReadCounter := 0;
                  
                  
                  // ___+0_____ ___+10____ ___+20____ ___+30____ ___+40____ ___+50____
                  // 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0
                  // 080514.000 ,3959.4287 ,N,03245.4 168,E,2,7, 1.08,932.8 ,M,38.7,M, ,
                  
                  UTC_Time_Second       := StrToWord(NMEA[4]+NMEA[5]);
                  UTC_Time_Text         := (NMEA[0]+NMEA[1]+':'+NMEA[2]+NMEA[3]+':'+NMEA[4]+NMEA[5]);
                  NMEA_LatitudeText     := NMEA[11]+NMEA[12]+NMEA[13]+NMEA[14]+NMEA[15]+NMEA[16]+NMEA[17]+NMEA[18]+NMEA[19]+NMEA[20]+NMEA[21];
                  NMEA_LongitudeText    := NMEA[23]+NMEA[24]+NMEA[25]+NMEA[26]+NMEA[27]+NMEA[28]+NMEA[29]+NMEA[30]+NMEA[31]+NMEA[32]+NMEA[33]+NMEA[34];

                  


             end;
      end;

     IFS0.U1RXIF    := 0;

 end;
//******************************************************************************

brandice5

Oncelikle string i virgul (,) ile split edersen geri kalan isler daha kolay olur. C de split icin "strtok" fonksiyonunu kullanabilirsin.

tekniker_murat

@brandice5 hocam bu konuyu biraz açabilir misin ben bu strtok fonksiyonunu bayağı araştırdım ama bir türlü çözemedim...

@kartal0689 hocam aşağıda yazdığınız bir uart kesmesi örneği mi ben şoförlük yapmaya başladıktan sonra bir çok şeyi kaçırmış öğrenememişim biraz yardımcı olur musunuz şu işin mantığı nedir nasıl bir yol yordam izlemem gerekir ?
[email]murat.yagci.1984@gmail.com[/email]

engerex

Öncelikle bu verileri bilgisayarda çözümlemeye çalışın. Daha hızlı hareket edersiniz. Sonra istediğiniz ortama uyarlayabilirsiniz.

kartal0689

Alıntı yapılan: tekniker_murat - 22 Kasım 2019, 20:44:41@brandice5 hocam bu konuyu biraz açabilir misin ben bu strtok fonksiyonunu bayağı araştırdım ama bir türlü çözemedim...

@kartal0689 hocam aşağıda yazdığınız bir uart kesmesi örneği mi ben şoförlük yapmaya başladıktan sonra bir çok şeyi kaçırmış öğrenememişim biraz yardımcı olur musunuz şu işin mantığı nedir nasıl bir yol yordam izlemem gerekir ?

evet bu işlem UART kesmesi içinde gerçekleşmektedir.
bu kodu direkt kullanarak (tabi mikroc' ye çevirip) NMEA[] string içinden ilgili karakterleri alabilirsiniz.
örneğin NMEA[0] ve NMEA[1], UTC zamanının saatini (22:54:25 ise 22' yi alır)alır. bunu strword ile string' den
sabit sayıya çevirerek kullanabilirisiniz.