fastSerial / UBlox GPS mit pro micro

Hallo zusammen

Ich bin am verzweifeln und hoffe auf eure Hilfe.
Ich möchte ein kleines Programm schreiben welches GPS Informationen ausliest und in einem anderen Seriellen Port ausgeben kann..
Verwndet wird ein UBlox GPS mit UBX Binärprotokoll.

Nun habe ich folgendes Problem, ich kenne mich mit Arduino noch nicht so tief aus um das Protokoll selber zu Decodieren bzw. nachzuschreiben um die Daten verwenden zu können.
Da ich den Ardupilot als Flugcontroller nutze kenne ich die da enthaltene GPS lib und wollte eigentlich auf dieser Aufbauen.
Das ganze ist extrem Simpel zu verwenden und Funktioniert auf einem Mega 2560 auch (getestet mit dem APM2.5). Nur brauch ich für meine Anwendung etwas kleines und leichtes, da der pro micro (Kompatibles Board) sowieso noch hier rumliegt wollte ich eigentlich den nehmen, dank USB in Chip wirklich ideal..
Aber ich schaff es damit nicht den Code zu Kompilieren..
Das Problem scheint an FastSerial zu liegen, der Fehler lautet "UBR0H was not declared in this scope".
Weis jemand wie ich FastSerial auf dem Pro Micro zum laufen kriege?

Eigentlich wollte ich den Code ja auf das eingebaute umschreiben, aber das ist zu viel und vor allem zu verstreut in x files.

Alernativ: Gibt es irgend eine lib die das UBX Protokoll kann?
Ich brauche mindestens:
Koordinaten
Speed
Höhe

Danke euch!

Hast du das Sparkfun Addon bereits in die IDE eingepflegt für den Micro?

Ja die hardware Daten sind alle da, das Board ist auch in der Liste etc.
Mit dem Originalen Leonardo kann ich den Code auch nicht Kompilieren, auf einem Uno geht es aber auch :frowning:

Edit:
Ich habe mir grade den neusten Dev Code geladen, da scheint wieder Arduino Serial verwendet zu werden, von der FastSerial lib find ich zumindest nichts mehr, aber es geht schon weiter, der ganze code ist scheinbar so extrem auf dem Mega 2560 aufgebaut, dass es praktisch unmöglich wird den Code auf einem micro zu verwenden bzw. müsste man wirklich alles durchforsten.

Gibt es denn wirklich sonst keine fertige UBX lib?

aargau:
Ich möchte ein kleines Programm schreiben welches GPS Informationen ausliest und in einem anderen Seriellen Port ausgeben kann..
Verwndet wird ein UBlox GPS mit UBX Binärprotokoll.

Warum konfigurierst Du Dein Modul nicht so, dass es NMEA-Sentences ausgibt und verwendest eine der üblichen Arduino-GPS-Libraries, die NMEA verarbeiten?

Relativ einfach, die Daten sind von einem GPS das schon für etwas anderes gebraucht wird, weshalb ich nun mit den Daten auskommen muss, da sonst das andere Gerät nichts mehr damit anfangen kann.

Ich habe gestern mit einer alten APM Version das ganze soweit hinbekommen, dass die Daten wirklich lesbar sind aber sobald irgend wo ein Delay oder etwas dazwischen kommt lauft der Code nicht mehr, ich glaube das Problem liegt da daran, dass er irgend wie immer nur ein Byte liest und die restlichen sonst verwirft...

Edit:
Ich habe nochmals mit dem Code vom alten Ardupilot getestet.
Das Problem liegt ziemlich sicher daran, dass Serial1.available() nur 1 byte hat und er die Daten desshalb verwirft wenn ein delay oder so dazwischen kommt...
An was ligt es? Kan der micro zu wenig Daten Puffern oder ist der COde zu langsam?
Wenn ich nämlich direkt im loop mir ausgeben lasse wie viele Bytes anstehen ist es nicht eins sondern eine grössere Zahl die durchaus sinn machen würde.

Ich mus sagen: Das GPS läuft leider mit 57600B und gibt die Daten wohl 5x pro Sekunde aus, das ist sicherlich nicht gerade ideal aber das müsste doch machbar sein?

aargau:
... wenn ein delay oder so dazwischen kommt...
Ich mus sagen: Das GPS läuft leider mit 57600B und gibt die Daten wohl 5x pro Sekunde aus, das ist sicherlich nicht gerade ideal aber das müsste doch machbar sein?

57600 Baud sind 5760 Zeichen pro Sekunde.
Der serielle Eingangspuffer kann bei HardwareSerial (keine Ahnung wie es bei Deiner Serial-Library ist) max. 63 Zeichen aufnehmen, das entspricht 63/5760s = 0,0109375s

D.h. ein "delay(11)" oder mehr wäre dann bereits zu viel, wenn das Modul gerade sendet, während auf dem Arduino das delay das Programm blockiert.

Okay, das bringt mich jetzt schon wieder etwas weiter.
Ich brauch eigentlich ja kein Delay, der Code soll die GPS Daten und ein paar Analoge 2-3x in der Sekunde via SoftwareSerial senden, das ganze wird natürlich per millis() gelöst und nicht mit delay aber ich habe etwas Angst, dass der ganze Code dann zu Problemen führt.
Der Puffer beinhaltet lustigerweise ja eben immer nur 1Zeichen/Byte? und ist nicht voll.
Ich habe nun um das Problem zu eruieren mal folgenden Code geschrieben:

if(Serial1.available()>2)
{
for(int i=0;i<Serial1.available();i++)
{
// print the sh*t
if(Serial1.read() == 0xB5)
{
Serial.print(i) ;
Serial.println("Syncchar!") ;
i++ ;
Serial.println(Serial1.read(),HEX) ;
}
}
Serial.println() ;
}
delay(1000) ;

Das ergibt jeweils 63 Zeichen die im Puffer liegen und er kann die beiden Sync Chars 0xB5 und 0x62 auch nacheinander ausgeben, das sieht also schon mal ganz gut aus.
Aber eben in der Klasse vom alten Ardupilot wird immer nur ein Zeichen aus dem Puffer gelesen, irgend was muss dies also überschreiben.
Ich werde nun mal versuchen den Code direkt zu verwenden ohne die Klasse, ev. hilft das ja schon etwas weiter.
Ich bin dem Ziel zumindest ein stückchen näher gekommen :wink:

Was ich noch gefunden habe: Google Code Archive - Long-term storage for Google Code Project Hosting. Dieser Code verwendet das selbe GPS wie ich und klappt scheinbar auf einem pro mini ohne wenn und aber + das ganze OSD zeugs zusätzlich. Leider kann ich den COde da aber dank fastSerial auch wieder nicht auf meinem micro Kompilieren, so dass ich den irgend wie auch nicht als anhaltspunkt nehmen konnte, zumal ich darin nicht mal den Ort gefunden habe wo die Daten in die UBLOX Klasse abgefüllt werden....

aargau:
// print the sh*t

Einsicht ja bekanntlich ist der erste Weg zur Besserung.

Versuch's mal mit:

void loop(){
  if(Serial1.available())
  {
    char c=Serial1.read();
    if(c == 0xB5) Serial.println();
    Serial.print(c,HEX); 
    Serial.print(" ");
  }
}

Dein Code zum Lesen von Zeichen ist ja das reinste "Tohuwabohu mit Delay".
Du möchtest doch die Daten ausgeben und nicht nur die Sync-Chars, oder?

Hi jurs

Der Code oben war nur mal als test ob er eben die Daten auch in den Puffer liest oder nur nacheinander ausliest wie bei der Klasse die ich verwende, das war eben Positiv, es muss also irgend was geben, dass den Puffer Löscht oder bereits viel zu früh ausliest.
Ich kann mich wie gesagt nicht extrem gut aus mit dem ganzen, ich bin eigentlich ein php'ler.

Ich habe nun mal die Klasse genommen und als normale Funktionen direkt im Sketch eingebaut um wirklch nur das zu haben was zum encoden gebraucht wird. Objektiv würde ich sagen der Code läuft schonmal viel schneller, gemessen habe ich es aber nicht.

Was mir nicht ganz klar ist, wird der Puffer einfach immer wieder überschrieben wenn er nicht ausgelesen wird oder was passiert da genau? Das ganze läuft nun nämlich bis zu einem delay von 10ms wirklich ohne Probleme, aber irgend wie macht mir das ganze schon etwas Sorgen, das würde ja heissen wenn mein restlicher Code dann mehr als 10ms braucht läuft nichts mehr.
Ideal wäre halt wenn man die Daten nur jedes x-te mal verarbeiten würde, für mein vorhaben brauche ich die Daten nicht mit 5hz oder mehr wie sie wohl geliefert werden.

aargau:
Was mir nicht ganz klar ist, wird der Puffer einfach immer wieder überschrieben wenn er nicht ausgelesen wird oder was passiert da genau?

Bei einer normalen FIFO-Puffer Implementierung mit 64 Byte Pufferspeicher passiert das:
63 Zeichen werden in den Puffer eingelesen und jeweils der Schreibzeiger um eins weitergezählt
Wenn das 64. Zeichen eingelesen wird, wird der Schreibzeiger nicht mehr weitergezählt, weil der Schreibzeiger sonst identisch wäre mit dem Lesezeiger für das nächste zu lesende Zeichen. D.h. die 63 gelesenen Zeichen, die den Puffer gefüllt haben, bleiben erhalten, weitere Zeichen gehen verloren.

Und wie es nun weiter geht, hängt davon ab, wie ausgelesen wird. Z.B.

  • es treffen 70 Zeichen ein, 63 Zeichen davon landen im Eingangspuffer, 7 Zeichen gehen verloren
  • jetzt würden z.B. 10 Zeichen ausgelesen, damit wird im Puffer wieder Platz für 10 Zeichen frei
  • nun kommen wieder 20 Zeichen, diese füllen die 10 freien Zeichen und 10 gehen wieder verloren

Der Zustand wäre dann:
10 Zeichen wurden ausgelesen, 53 noch im Puffer, 7 Zeichen verloren, 10 im Puffer, 10 verloren
Das wird sehr schnell sehr unübersichtlich.

Wenn Du langsamer ausliest als die Zeichen eintreffen, z.B. weil "delay" verwendet wird, dann wird' im allgemeinen nur noch ein großes Tohuwabohu und Du bekommst selbst Datensätze, die weniger als 63 Zeichen lang sind, nicht mehr in jedem Fall vollständig zusammen.

Danke für die Ausführliche Beschreibung.
d.H. ich muss zwingend delays vermeiden (sowieso mein wunsch), die GPS Daten so oft wie möglich auslesen, da sonst wohl Daten verloren gehen und die Checksum nicht mehr stimmen wird = er beginnt von vorne und kann eben nie etwas ausgeben.
Den Restlichen Code mit millis "delayen" um ihn nur x Mal auszuführen.

Der Code scheint mir dennoch extrem schnell ausgeführt zu werden, so dass man nebenbei noch mehr als genug machen kann.
Für ein paar Simple analoge Werte lesen und interpretieren (ca 2x/sek) reicht das wohl noch 1000fach

Ich habe gerade mal getestet:

GPS: Time:82251000 Fix:1 Lat:475429285 Lon:79579777 Alt:330.01 Speed:0.11 Course:0.29SATS:6
GPS: Time:82251250 Fix:1 Lat:475429278 Lon:79579793 Alt:330.02 Speed:0.13 Course:0.29SATS:6
GPS: Time:82251500 Fix:1 Lat:475429268 Lon:79579809 Alt:329.99 Speed:0.14 Course:0.29SATS:6
GPS: Time:82251750 Fix:1 Lat:475429267 Lon:79579803 Alt:329.96 Speed:0.11 Course:0.29SATS:5
Runtime MAX:196
Runtime LAST:24
Runtime MIN:12

  • Die GPS Daten werden 4x pro Sekunde ausgegeben
  • Die Verarbeitung des ganzes loop's braucht Minimal etwa 12uS, Maximal um 200uS)

Das sollte reichen denke ich mal.