Die NMEA 0183 GSV Datensätze vom GPS zerlegen

In den NMEA GSV Datensätzen werden die empfangenen Satelliten Nummern, die Richtung, die Höhe über dem Horizont und die Signalstärke ausgegeben. Hiermit lässt sich die für den Satellitenstatus so typische Draufsicht und die Signalstärkebalken anzeigen.

In jeder Zeile werden bis zu 4 Satellitendaten ausgegeben und für weitere Satelliten werden zusätzliche Zeilen angefügt. Bei einem 12-Kanal GPS Empfänger können also bis zu 3 Zeilen ausgegeben werden wenn 12 Satelliten im Empfangsbereich sind.

Hier das Programm mit den verschiedenen Funktionen.

// Hauptprogramm zum Testen der GSV NMEA Zerlegung
// Bei einem 12 Kanal Empfänger: 3 GSV Datensätze mit bis zu 4 Satelliten
//
// Matthias Busse 31.3.2015 Version 1.0

int inByte, start=0, sats;
//             12345678901234567890123456789012345678901234567890123456789012345678901234
String nmea = "NMEA Datensaetze zerlegen in die Bestandteile  Version 1.0  Matthias Busse"; // reservieren
//             $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
//             $GPGSV,3,2,11,07,06,073,,15,47,291,50,18,10,325,,24,07,255,38*71
//             $GPGSV,3,3,11,21,06,299,32,19,10,021,,44,06,248,*4D
//             $GPGSV,3,3,10,19,06,015,,33,06,248,*7A

void setup() {
  Serial.begin(4800); // 4800 Baud Dateneingang und Konsole
  Serial.println(nmea);
}

void loop() {
  if (Serial.available()) { // sind Daten im Eingangspuffer
    inByte = Serial.read(); // dann lesen
    if ((start==0) && ((inByte == '$')||(inByte == '!'))) {
      start=1; nmea=""; // bei $ oder ! starten
    }
    if(start==1) {nmea.concat((char)inByte);} // das Zeichen anhängen
    if((inByte==13) && (start==1)) { // CR > Datensatzende > NMEA ausgeben
      start=0;
//      Serial.println(nmea); // alles auf Konsole ausgeben
//      if (nmea.substring(3,10) == "GSV,3,1") { // Einen dieser 3 if auswählen ...
      if (nmea.substring(3,10) == "GSV,3,2") { // sonst wird die Ausgabe ...       
//      if (nmea.substring(3,10) == "GSV,3,3") { // überlastet.
        Serial.println(nmea); // auf Konsole ausgeben
        Serial.print(" GSV ");
        Serial.print(" Datensaetze ");
        Serial.print(getGSV_total(nmea));
        Serial.print(" SatzNr. ");
        Serial.print(getGSV_counter(nmea)); 
        Serial.print(" Alle Sats ");
        Serial.println(getGSV_sats(nmea)); 
        Serial.print(" Sats in dieser Message ");
        sats = getGSV_satsInMess(nmea);
        Serial.println(getGSV_satsInMess(nmea));
        for(int k = 0; k < sats; k++) { 
          Serial.print(" Nr ");
          Serial.print(getGSV_satNo(nmea, k));
          Serial.print(" El ");
          Serial.print(getGSV_satEl(nmea, k));
          Serial.print(" De ");
          Serial.print(getGSV_satDeg(nmea, k));
          Serial.print(" Sn ");
          Serial.println(getGSV_satSnr(nmea, k));
        }
        Serial.println();
      }
    }
  }
}

int getGSV_total(String s) {
// Aus dem GSV Datensatz die Anzahl der GSV Datensätze  
// $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
//        -
// von Matthias Busse 29.03.2015 Version 1.0  
  int k = s.indexOf( ',',1);
  return s.substring(k+1, k+2).toInt();
}

int getGSV_counter(String s) {
// Aus dem GSV Datensatz die Nummer dieses Datensatzes  
// $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
//          -
// von Matthias Busse 29.03.2015 Version 1.0  
  int k = s.indexOf( ',',1);
  k = s.indexOf( ',',k+1);
  return s.substring(k+1, k+2).toInt();;
}

int getGSV_sats(String s) {
// Aus dem GSV Datensatz die Anzahl der Satelliten in allen GSV Datensätzen 
// $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
//            --
// von Matthias Busse 29.03.2015 Version 1.0  
  int k = s.indexOf( ',',1);
  k = s.indexOf( ',',k+1);
  k = s.indexOf( ',',k+1);
  int k2 = s.indexOf( ',',k+1);
  return s.substring(k+1, k2).toInt();;
}

int getGSV_satsInMess(String s) {
// Aus dem GSV Datensatz Anzahl der Satelliten in diesem GSV Datensatz 
// $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
// Komma Anzahl: 19=4 15=3 11=2 7=1;
//
// von Matthias Busse 29.03.2015 Version 1.0  
int k=1, l=-1;
  while(k>0) {
    k = s.indexOf( ',',k+1);
    l++;
  }
  return (l-3.0)/4.0;
}

int getGSV_satNo(String s, int no) {
// Aus dem GSV Datensatz die SatNummer an der Stelle no holen  
// $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
//               --           --         --         --
// von Matthias Busse 29.03.2015 Version 1.0   
int k1=0, k2=0, l, m;
  for(m=0;m<=no;m++) { // Stelle
    for(l=0;l<4;l++) { 
      k1 = s.indexOf( ',',k1+1);
    }
  }
  k2 = s.indexOf( ',',k1+1);
  return s.substring(k1+1, k2+1).toInt();
}

int getGSV_satEl(String s, int no) {
// Aus dem GSV Datensatz die SatElevation an der Stelle no holen  
// $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
//                  --           --         --         --
// von Matthias Busse 29.03.2015 Version 1.0   
int k1=0, k2=0, l, m;
  k1 = s.indexOf( ',',1);
  for(m=0;m<=no;m++) { // Stelle
    for(l=0;l<4;l++) { 
      k1 = s.indexOf( ',',k1+1);
    }
  }
  k2 = s.indexOf( ',',k1+1);
  return s.substring(k1+1, k2+1).toInt();
}

int getGSV_satDeg(String s, int no) {
// Aus dem GSV Datensatz die SatDegrees an der Stelle no holen  
// $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
//                     ---          ---        ---        ---
// von Matthias Busse 29.03.2015 Version 1.0   
int k1=0, k2=0, l, m;
  k1 = s.indexOf( ',',1);
  k1 = s.indexOf( ',',k1+1);
  for(m=0;m<=no;m++) { // Stelle
    for(l=0;l<4;l++) { 
      k1 = s.indexOf( ',',k1+1);
    }
  }
  k2 = s.indexOf( ',',k1+1);
  return s.substring(k1+1, k2+1).toInt();
}

int getGSV_satSnr(String s, int no) {
// Aus dem GSV Datensatz die SatSignalNoiseRation an der Stelle no holen  
// $GPGSV,3,1,11,13,84,232,52,30,35,073,,05,28,203,,28,60,103,40*74
//                         --           -          -          --
// von Matthias Busse 29.03.2015 Version 1.0   
int k1=0, k2=0, l, m;
  s.replace("*", ",");
  k1 = s.indexOf( ',',1);
  k1 = s.indexOf( ',',k1+1);
  k1 = s.indexOf( ',',k1+1);
  for(m=0;m<=no;m++) { // m. Satellit
    for(l=0;l<4;l++) { // l. Daten
      k1 = s.indexOf( ',',k1+1);
    }
  }
  k2 = s.indexOf( ',',k1+1);
  return s.substring(k1+1, k2+1).toInt();
}

Links: GGA & RMC Daten zerlegen.

Hardware: Arduino Uno Rev 3
Software: Arduino 1.5.8

von Matthias Busse

3 Gedanken zu „Die NMEA 0183 GSV Datensätze vom GPS zerlegen

    1. admin Beitragsautor

      Beim kopieren hat sich ein Fehler eingeschlichen, den ich jetzt korrigiert habe.
      In Zeile 43 ist das WordPress Plugin Crayton kreativ geworden und hat den Text geändert.
      Ich habe das Programm mit der aktuellen Arduino Umgebung 1.5.8 übersetzt.
      Matthias

      Antworten
  1. Günther

    Was passiert, wenn die Datensätze nicht vollständig / beschädigt ankommen? Ich suche nach einer Lösung für die Prüfung, ohne die Checksumme nachrechnen zu müssen.

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.