Forum: Mikrocontroller und Digitale Elektronik GPS Datensatz einlesen


von Franki (Gast)


Lesenswert?

Guten Morgen,

ich auf einem Embedded-PC die serielle Schnittstelle jetzt zum Laufen 
gebracht. Eine Methode ist die CheckForFrame. Damit kann ich prüfen wann 
das Ende mit dem Zeichen 'z' erreicht wurde. Die ReceiveCallBackFunc 
Methode beinhaltet das ganze Frame.
1
int COMchild::CheckForFrame(char* buf, int len)
2
{
3
        if (len == 100)
4
  {
5
    if(buf[99]=='z')
6
    {
7
        return 1;
8
    }
9
  }
10
  return 0;
11
}
12
13
void COMchild::ReceiveCallBackFunc(void* _pthis)
14
{
15
  int i;
16
  COM *pthis= (COM*)_pthis;
17
  char value[100];
18
  
19
  for (i=0; i<RX_BUFFER_SIZE;i++)
20
    {
21
      value[i] = pthis->rxbuffer[i];
22
    }
23
}

Jetzt hab ich eine GPS Maus angeschlossen.
Ich möchte nun die einzelnen Datensätze einlesen. Wie kann ich dies 
realisieren? Das Problem ist, ja, das die einzelnen Datensätze 
unterschiedlich lang sind.

von Franki (Gast)


Lesenswert?

Ich hoffe ich hab mich verständlich ausgedrückt!

von Karl H. (kbuchegg)


Lesenswert?

Nicht wirklich

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Beide Funktionen gefallen mir nicht.

In COMchild::ReceiveCallBackFunc sehe ich Probleme bei RX_BUFFER_SIZE > 
100, dem Abschliessen mit Nullbyte, dem Verlust von value beim Verlassen 
der Funktion sowie dem Brute-Force-Kopieren ungeachtet der tatsächlichen 
Eingabelänge im rxbuffer. Abgesehen davon, dass Platz für pthis 
verschwendet wird.

In COMchild::CheckForFrame gefällt mir die erste Prüfung auf 
Vollgeschriebenen buf über len==100 nicht. Das wäre auch der erste 
Punkt, der weg müsste, wenn die Zeilen unterschiedlich lang sind.

Um genauere Vorschläge zu machen, bräuchte man mehr Infos zum 
Programmcode. Rel. einfach wäre es wenn z.B. in rxbuffer immer komplette 
Zeilen (bis Zeilenende \n) stehen und dann COMchild::ReceiveCallBackFunc 
aufgerufen würde. Ich würde dann die Funktion aufblasen:
1
int COMchild::ReceiveCallBackFunc(void* _pthis, char* dest_line, size_t max_dest_len)
2
{
3
  // Anzahl Zeichen im Zeileneingangspuffer+Nullbyte > max_dest_len
4
  // oder dest_line == NULL oder _pthis == NULL
5
  // return 0;
6
7
  // Zeichen im Zeileneingangspuffer+Nullbyte nach dest_line kopieren
8
  // return Anzahl Zeichen im Zeileneingangspuffer+Nullbyte;
9
}

Mit den Daten daraus kannst du dann schon die Zeile prüfen
1
int COMchild::CheckForFrame(char* buf, size_t len)
2
{
3
   // Aufruf:
4
   // an buf wird dest_line übergeben
5
   // an len wird Anzahl Zeichen im Zeileneingangspuffer+Nullbyte übergeben
6
7
   // wenn len == 0 oder buf == NULL
8
   // return UNGUELTIG
9
10
   // Erweiterung:
11
   // wenn Anfang gleich $GRABC
12
   return IST_ABC_FRAME;
13
14
   // Erweiterung:
15
   // wenn Anfang gleich $GRXYZ
16
   return IST_XYZ_FRAME;
17
18
   // Erweiterung:
19
   // Nix erkannt...
20
   return IST_UNBEKANNTER_FRAME;
21
}

Mit den FRAME_TYPEN könnte man dann eine Framezerschnippelfunktion 
triggern, die die interessanten Daten aus den unterschiedlichen Frames 
herausholt (Länge, Breite, Anzahl der Sats, Zeit...)

von Karl H. (kbuchegg)


Lesenswert?

Franki wrote:
> Ich hoffe ich hab mich verständlich ausgedrückt!

Nicht wirklich

Welche spezielle Bedeutung spielt das 'z'?

> Ich möchte nun die einzelnen Datensätze einlesen. Wie kann ich
> dies realisieren? Das Problem ist, ja, das die einzelnen
> Datensätze unterschiedlich lang sind.

Ist das ein NMEA Protokoll?

Die Datensätze fangen mit '$' an und laufen bis zu einem CR/LF
Sobald ein '$' auftaucht, alle weiteren Zeichen bis zum
CR/LF in einem Buffer sammeln, das CR/LF bleibt aussen vor,
noch ein '\0' dahinter und du hast einen ganz normalen C-String,
den du mit den C Stringfunktionen (strcpy, strcat, strtok, etc)
weiterverarbeiten kannst.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.