GPS auf SD Bestimmte Daten auslesen und speichern



  • Hallo,
    ich habe vor, GPS-Daten zu speichern, die immer wie folgt reinkommen:

    GPGSA,A,3,02,04,05,14,30,,,,,,,,03.6,02.9,02.10AGPGSA,A,3,02,04,05,14,30,,,,,,,,03.6,02.9,02.1*0A GPGSV,2,1,05,02,33,070,43,04,14,035,40,05,66,093,46,14,26,240,3572
    GPGSV,2,2,05,30,85,057,47,,,,,,,,,,,,43GPGSV,2,2,05,30,85,057,47,,,,,,,,,,,,*43 GPRMC,163411,A,5150.3752,N,00639.0283,E,000.0,000.0,170807,,,A
    7E
    $GPGGA,163412,5150.3752,N,00639.0286,E,1,05,02.9,00009.1,M,046.9,M,,*4E

    Und das pro Sekunde....
    So nun ist da aber noch jede Menge Müll drin, denn ich brauche nur die
    Daten auf SD zu speichern, die mit
    $GPGGA beginnen. Dazu habe ich in C ein kleines Programm geschrieben, welches leider nicht ganz so funktioniert, wie ich es gerne hätte...
    Leider sollte ich auf Mikrocontrollern nicht mit Strings und floats hantieren, da diese sehr rechenintensiv sind!

    DAHER DARF NICHT MIT STRING ODER FLOAT GEARBEITET WERDEN 😞

    aber hier erstmal das programm:

    #include "iostream.h"
    #include "stdio.h"
    #include "stdlib.h"
    //#include ".h"
    
    int main(void)
    {
    	unsigned int	BUFFER_SIZE=82;
    	char			buffer[82], usefulbuffer[82];
    	char			*boese, *useful;
    	unsigned int count, bufcount;
    
    	count			=	0;
    	bufcount		=	0;
    
    	boese	=	buffer;			// Zeiger intitialisieren (d.h. auf eine gültige adresse im RAM setzen)!!!
    	useful	=	usefulbuffer;	// Zeiger intitialisieren (d.h. auf eine gültige adresse im RAM setzen)!!!
    	for(count=0;count < BUFFER_SIZE;count++)
    	{
    		boese[count]=0;
    	}
    	count=0;
    	for(count=0;count < BUFFER_SIZE;count++)
    	{
    		useful[count]=0;
    	}
    	count=0;
    
    	*boese =	"$GPGSA,A,3,02,04,05,14,30,,,,,,,,03.6,02.9,02.1*0A$GPGSV,2,1,05,02,33,070,43,04,14,035,40,05,66,093,46,14,26,240,35*72$GPGSV,2,2,05,30,85,057,47,,,,,,,,,,,,*43$GPRMC,163411,A,5150.3752,N,00639.0283,E,000.0,000.0,170807,,,A*7E$GPGGA,163412,5150.3752,N,00639.0286,E,1,05,02.9,00009.1,M,046.9,M,,*4E";
    
    	for(count=0;count <=409;count++)
    	{
    		if(buffer[count] == '$')
    			if(buffer[count+1] == 'G')
    				if(buffer[count+2] == 'P')
    					if(buffer[count+3] == 'G')
    						if(buffer[count+4] == 'G')
    							if(buffer[count+5] == 'A')
    							{
    								for(bufcount=0;bufcount<=81;bufcount++)
    								{
    									count += bufcount;
    									usefulbuffer[bufcount]=buffer[count];
    								}
    							}	
    	}
    	printf("%c\n", buffer);
    }
    

    Ich hoffe jemand von euch weiß rat, sitze nun leider schon seit fast 3 Tagen an diesem Problem !

    Vielen Dank für Hinweise in die richtige Richtung!!!!!!



  • Probiers mal damit.
    Frickel-Schnellschuss aus der Hüfte:

    [quote="Studiologe"]

    #include "iostream.h"
    #include "stdio.h"
    #include "stdlib.h"
    //#include ".h"
    
    int main(void)
    {
    	unsigned int	BUFFER_SIZE=82;
    	char			buffer[82], usefulbuffer[82];
    	char			*boese, *useful;
    	unsigned int count, bufcount;
    
    	count			=	0;
    	bufcount		=	0;
    
    	boese	=	buffer;			// Zeiger intitialisieren (d.h. auf eine gültige adresse im RAM setzen)!!!
    	useful	=	usefulbuffer;	// Zeiger intitialisieren (d.h. auf eine gültige adresse im RAM setzen)!!!
    	for(count=0;count < BUFFER_SIZE;count++)
    	{
    		boese[count]=0;
    	}
    	count=0;
    	for(count=0;count < BUFFER_SIZE;count++)
    	{
    		useful[count]=0;
    	}
    	count=0;
    
    	*boese =	"$GPGSA,A,3,02,04,05,14,30,,,,,,,,03.6,02.9,02.1*0A$GPGSV,2,1,05,02,33,070,43,04,14,035,40,05,66,093,46,14,26,240,35*72$GPGSV,2,2,05,30,85,057,47,,,,,,,,,,,,*43$GPRMC,163411,A,5150.3752,N,00639.0283,E,000.0,000.0,170807,,,A*7E$GPGGA,163412,5150.3752,N,00639.0286,E,1,05,02.9,00009.1,M,046.9,M,,*4E";
    
    	for(count=0;count <=409;count++)
    	{
    		if(buffer[count] == '$')
    			if(buffer[count+1] == 'G')
    				if(buffer[count+2] == 'P')
    					if(buffer[count+3] == 'G')
    						if(buffer[count+4] == 'G')
    							if(buffer[count+5] == 'A')
    							{
    								for(bufcount=0;bufcount<=81;bufcount++)
    								{
    																	usefulbuffer[bufcount]=buffer[count+bufcount];
    								}
    	count += bufcount;
    
    							}	
    	}
    	printf("%c\n", buffer);
    }
    


  • Hi Minimee und danke für die rasche Antwort,
    leider jedoch kommt bei der Ausgabe so das gleiche raus



  • Studiologe schrieb:

    Leider sollte ich auf Mikrocontrollern nicht mit Strings und floats hantieren, da diese sehr rechenintensiv sind!

    Bist du sicher, dass du hier nicht C++-Strings meinst? Die Funktionen aus der string.h (in C) operieren auf null-terminierten Arrays und sind unproblematisch.
    Nimm das Programm hier als Ausgangspunkt. Es sucht alle GPGGA-Datensätze aus dem Eingabepuffer und schreibt sie hintereinander in den Ausgabepuffer. Wenn die Datensätze in etwa die Länge deines Beispiels haben, sollte das zeitlich kein Problem sein. Wie schnell kannst du auf die SD-Karte schreiben?

    #include <stdio.h>
    #include <string.h>
    
    #define N 512
    
    char inv[] = "$GPGSA,A,3,02,04,05,14,30,,,,,,,,03.6,02.9,02.1*0A"
                 "$GPGSV,2,1,05,02,33,070,43,04,14,035,40,05,66,093,46,14,26,240,35*72"
                 "$GPGGA,163412,5150.3752,N,00639.0286,E,1,05,02.9,00009.1,M,046.9,M,,*4E"
                 "$GPGSV,2,2,05,30,85,057,47,,,,,,,,,,,,*43"
                 "$GPRMC,163411,A,5150.3752,N,00639.0283,E,000.0,000.0,170807,,,A*7E"
                 "$GPGGA,163412,5150.3752,N,00639.0286,E,1,05,02.9,00009.1,M,046.9,M,,*4E";
    
    char outv[N];
    
    int main(void)
    {
      char *p = strtok(inv, "$");
    
      while (p) {
        if (strncmp(p, "GPGGA", 4) == 0) {
          strcat(outv, "$");
          strcat(outv, p);
        }
    
        p = strtok(NULL, "$");  
      }
    
      puts(outv);
    
      return 0;
    }
    


  • die daten kommen doch bestimmt einzeln über die serielle reingetrudelt, oder?
    dann bastel dir doch eine einfachr state-machine, die auf einzelne zeichen reagiert. bei '$GPGSA' wird der 'state' eins weitergschaltet, stimmt ein zeichen nicht, dann springt er wieder auf den ausgangszustand. sind alle zeichen da, dann wird alles folgende gespeichert oder verarbeitet bis zum zeilenende (CR oder LF oder beides) und danach geht's wieder von vorn los. noch einen time-out einbauen (2 sekunden kein input, dann state-machine resetten) und gut is'.
    so ungefähr könnt's gehen.
    🙂


Anmelden zum Antworten