ich fuege einem Buffer immer etwas hinzu.
char* Buffer;
if (booler.gpsstart == 1 && StringLen < 5) {
*Buffer++ = c;
StringLen++;
setData(c);
}
jetzt wuerde ich gerne abfragen ob die ersten 5 zeichen des Buffers
GPGGA heiszen.
so z.B.
if (Buffer == "GPGGA") {
}
Es geht mir dabei darum, folgende GPS Daten die ich per UART bekomme,
in einzelne Teile zu zerlegen, um es in getrennte Variablen zu packen.
(Navilock NL501-TTL)
$GPGGA,053740.000,2503.6319,N,12136.0099,E,1,08,1.1,63.8,M,15.2,M,,0000*
64
Simon schrieb:
> ich fuege einem Buffer immer etwas hinzu.>> char* Buffer;
Ich hoffe mal, dass das nicht alles ist :-)
> jetzt wuerde ich gerne abfragen ob die ersten 5 zeichen des Buffers> GPGGA heiszen.>> so z.B.> if (Buffer == "GPGGA") {>> }
[C]
if( strncmp( Buffer, "GPGGA", 5 ) == 0 )
[/C
> Es geht mir dabei darum, folgende GPS Daten die ich per UART bekomme,> in einzelne Teile zu zerlegen, um es in getrennte Variablen zu packen.> (Navilock NL501-TTL)>> $GPGGA,053740.000,2503.6319,N,12136.0099,E,1,08,1.1,63.8,M,15.2,M,,0000* 64
per strtok am , aufbrechen und umkopieren.
Simon schrieb:
> ich fuege einem Buffer immer etwas hinzu.>> char* Buffer;>> if (booler.gpsstart == 1 && StringLen < 5) {> *Buffer++ = c;> StringLen++;> setData(c);> }>>> jetzt wuerde ich gerne abfragen ob die ersten 5 zeichen des Buffers> GPGGA heiszen.>> so z.B.> if (Buffer == "GPGGA")
Nein. Schau dir strncmp aus der libc an!
Ausserdem veränderst du Buffer, d.h er zeigt nach Abspeichern des
Strings dahiner !
>mmh das funzt so nicht,
Das funktioniert schon, aber das immer was ungleich 0 rauskommt,
bedeutet, das da eben nicht "GPGGA" am Anfang des Buffers steht. Du
musst also rausfinden, warum das so ist. Der Vergleich ist in Ordnung.
Gib doch mal den String aus, dann weisst Du was drinsteht.
>Du musst in "Buffer" ja auch einen Zeiger auf den Anfang des Strings>übergeben.
Buffer ist schon der String. Man kann "darin" nicht einen Zeiger
übergeben.
Das erste Argument von strncmp ist der Zeiger auf einen String. Soweit
ist das korrekt.
>>Du musst in "Buffer" ja auch einen Zeiger auf den Anfang des Strings>>übergeben.>Buffer ist schon der String. Man kann "darin" nicht einen Zeiger>übergeben.>Das erste Argument von strncmp ist der Zeiger auf einen String. Soweit>ist das korrekt.
Blödfug/Haarespalterei. "Buffer" ist eine Variable und darin ist ein
Zeiger, der irgendwo hinzeigt. Buffer ist KEIN string, nur die Daten auf
die er zeigt können als string interpretiert werden.
Abgesehen davon, das in der folgenden Zeile für meinen Geschmack ein
paar Klammern fehlen, wird auch der Zeiger in Buffer erhöht.
1
*Buffer++=c;
Deswegen sieht das strcmp nur noch das Ende des Strings und kann
folglich auch nicht richtig funktionieren. Deswegen entweder sowas wie
"Buffer - StringLen" als Zeiger übergeben, oder (meinen Präferenz), sich
den Anfang in einer eigenen Variable merken und nicht immer verändern,
z.B. so:
Ach komm jetzt. "strtok" in google eintippen und dann lesen sollte schon
noch drin sein, oder? Wenn es konkrete Probleme gibt, und der Quelltext
dafür vorliegt, werden sie hier sicher gerne geholfen...
ja, genau das ist ja mein Problem, die AVR-libc dokumentation
beschreibt die funktion nur kurz.
http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html#g6ace85338eafe22a0ff52c00eb9779b8
char * strtok_r ( char * string,
const char * delim,
char ** last
)
meinevar = strtok(Buffer, ",", ??)
ein weiteres problem was ich habe, der ganze string den ich vom GPS
empfaenger bekomme, geht garnicht in den buffer.
waere schoen ich koennte das mit einmal in buffer einlesen
>ja, genau das ist ja mein Problem, die AVR-libc dokumentation
beschreibt die funktion nur kurz.
Das ist durchaus nicht alles. In den Zeilen darunter steht noch mehr.
Ausserdem bist Du ja nicht gezwungen ausschliesslich dort zu schauen.
Parses the string s into tokens.
strtok parses the string s into tokens. The first call to strtok should
have s as its first argument. Subsequent calls should have the first
argument set to NULL. If a token ends with a delimiter, this delimiting
character is overwritten with a '\0' and a pointer to the next character
is saved for the next call to strtok. The delimiter string delim may be
different for each call.
Ausserdem bist Du ja nicht gezwungen ausschliesslich dort zu schauen.
>ein weiteres problem was ich habe, der ganze string den ich vom GPS>empfaenger bekomme, geht garnicht in den buffer.
Mach doch den Buffer einfach länger.
Wenn ich den groesser mache mit [100] vergroessert sich natuerlich
wieder der speicher den ich belge.
das is doch auch kacke,
ich muesste doch nur das start signal abwarten ($GPGGA).
danach alles was kommt in nen kleinen buffer bis ein "," auftritt.
>das is doch auch kacke,
Das mag ja sein, aber mit dieser Beschreibung
>ich muesste doch nur das start signal abwarten ($GPGGA).>danach alles was kommt in nen kleinen buffer bis ein "," auftritt.
hast Du ja schon festgelegt wie es auch mit kleinem Buffer geht.
Mach es doch einfach so.
Mach´s doch so:
Erst mal alles ignorieren. Wenn ein $ kommt, globale Variable setzen,
dass du jetzt im Datensatz bist. Wenn du im Datensatz bist, 5 Zeichen in
einen 6 Byte großen Buffer einsortieren. Wenn du das 5. Zeichen
eingesammelt hast, vergleichen, ob GPGGA ist. Wenn ja, 2. globale
Variable setzen, dass du im korrekten Datensatz bist. Dann halt alles
einsammeln, entweder von Komma zu Komma gleich beim Empfangen sortieren
(Datensatzabschnitte mitzählen) oder alles bis zum Zeilenumbruch in
einen großen Buffer. Dann auswerten und nach der Auswertung die globalen
Variablen zurücksetzen.
Mit strtok bekommst du bei den meisten GPS Empfängern ein Problem.
Manchmal steht in den Teilabschnitten nix, also gleich das nächste
Komma. Dann funktioniert die Geschichte mit dem Token nicht richtig.
Jedenfalls hat´s auf der Implementierung des MSPGCC nicht hingehauen.
Warum springt der beim vergleichen mit == "." niemals in
das untere else feld?
obwohl das LCD display ein . zeigt?
er findet nie einen . darin, werder wenn ich es
so: '.'
noch so "."
noch 0x2E
schreibe
Simon schrieb:
> Warum springt der beim vergleichen mit == "." niemals in> das untere else feld?
Was mich viel mehr verblüfft ist, dass dir dein Compiler dabei keine
Warnung ausgegeben hat.
In C gilt
Alles zwischen doppelten Gänsefüschen (also ") ist ein String
Alles zwischen einfachen Gänsefüschen (also ') ist ein Character
Du willst Character vergleichen, also
> if ( c == "." ) {
if ( c == '.' ) {
Der Witz daran ist ja das selbst das nicht funktioniert
1
if((GPSc==2)&&(StringLen<8)){
2
3
if(c=='.'){
4
GPSc=3;
5
StringLen=0;
6
lcd_puts("P3");
7
}else
8
{
9
tim[StringLen]=c;
10
StringLen++;
11
setData(c);
12
}
13
}
er muesste ja sobald er ein '.' erkennt, auf dem LCD ein P3 ausgeben.
tut er aber nicht.
er gibt einen punkt aus und macht weiter bis StringLen <8 erreicht hat.
und da er GPSc = 3 ausgibt, duerfte er niemals mehr keins der beiden
anspringen.
unsigned int ist größer als char. Ich weiß nicht genau, was der Compiler
aus if (c == '.') macht bzw. was du überhaupt in die Variable c
reinliest. Kannst dir ja mal den erzeugten Assembler anschauen. Ich
meine ganz ganz dunkel was im Kopf zu haben, dass er das vll falsch
"verbreitert". Deshalb sollte man auch, wenn man mit 32 bit Werten
hantiert, immer so: var &= 0x00000012 und nicht so: var &= 0x12
verknüpfen.
Matthias
Sind das die UART Routinen vom Fleury Peter?
Wenn ja, dann haben die im HighByte Kennungen enthalten und damit ist
der komplette unsigned int nicht mehr '.', selbst wenn im Low-byte ein
'.' kodiert ist. Du musst aber c auf unsigned int lassen, sonst kriegst
du nie die UART_NO_DATA Benachrichtigung.
1
if((c&0xFF)=='.')
2
...
Aber der ganze Ansatz, den du da treibst ist IMHO eher auf der schwachen
Seite angesiedelt. Würd ich nicht so machen. Ich würde erst mal
abwarten, bis ein $ daherkommt. Ist es da, dann beginnt das Sammeln von
Zeichen. Und zwar solange, bis ein ',' oder ein \n daherkommt. Jedesmal
wenn ein ',' daherkommt ist wieder ein Bestandteil der Zeile komplett
da. Je nachdem, das wievielte das war, wird es entsprechend ausgewertet.
Deine ganze Steuerung mit GPSc ist mir viel zu kompliziert.