|
|
GPS Mini Navigatorvon Matthias Larisch
[Bearbeiten] EinleitungSeit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS-Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen! Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS-Bluetooth-Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS-Empfänger, ein Bluetooth-Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind. Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält. Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth-GPS zu integrieren. Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt. [Bearbeiten] Hardware[Bearbeiten] GPS/Bluetooth-ModulMein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium-Ionen-Akku mit 1100 mAh ist ein Standard-Modell, der EL-EN5. Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht: Links das GPS-Modul, oben gehen die UART-RX/TX-Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS-Signalindikator. Ganz unten ist die 5V-Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3V-Low-Drop-Regler, welcher im Standby nur rund 20µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3V-Regler. Um eine Schaltung auf diese Platine aufzubauen, können die UART-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth-Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit. Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3V-Layer, welche durchtrennt werden kann. Außerdem wird das Modul jedoch noch anderweitig mit 3,3V versorgt, um Almanach & Ephemeriden-Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt. Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS-Modul macht nach längeren Standby-Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby-Versorgung zurückzuführen sind. Dies wird weiter untersucht. Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist. [Bearbeiten] µC-PlatineDas Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 UARTs zu verwenden. Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD-Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z. B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten). Durch 2 P-Kanal-MOSFETs kann die SD-Karte und das GPS-Modul vom Strom getrennt werden. Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD-Miniaturhub-Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal-Logic-Level-FETs gibts mit dem IRF7314 gleich als Doppelpack im SO8-Gehäuse, 20V, ~5A bei nur 0,06Ω RdsOn @ 3,3V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen. Das GPS-Modul wird mit dem Hardware-UART des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-UART ausreichen muss. [Bearbeiten] Verbindung beider PlatinenDie Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS-Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z. B. 0,2mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei. Die Mikro-SD-Karte findet auf der anderen Seite der Platine ihren Platz. Der 100nF-Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die UART-Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-FET versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3V-Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth-Modul ein und aus. Die Stromaufnahme der einzelnen Module beträgt im Übrigen:
[Bearbeiten] SoftwareDie Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet. Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen. Download des kompletten Quelltexts: GPS Mini Navigator Version beta 0.3 Behobene Fehler:
Bekannte Fehler:
Behobene Fehler:
Bekannte Fehler:
GPS Mini Navigator Version beta 0.1 [Bearbeiten] AufbauDas Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden. Zum Einsatz kommen folgende Komponenten:
Außerdem existieren noch folgende Sourcefiles bzw. Module:
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP-Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software-UART mit. Das Bluetooth-Modul eignet sich somit auch für Firmware-Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden. Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen. [Bearbeiten] SD-Karte und DateisystemUlrich Radigs MMC/SD-Library eignet sich für kleine bis mittelgroße Mikrocontroller-Projekte aufgrund ihrer Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID- und CSD-Register. Ich habe dabei die Block-Lese-Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI-Bus bis zum Abschluss des Lesevorgangs blockiert sind. Dafür ergeben sich dann folgende Funktionen:
Initialisiert den Lesevorgang ab Sektor addr.
Liest (count) Bytes in den übergebenen Puffer.
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann. Das Dateisystem ist möglichst einfach gestrickt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen & Schreiben in neue Dateien, das Öffnen & Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben. Der Aufbau aller Sektoren ist wie folgt: Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS-Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation) Byte 1 - 507: Nutzdaten Byte 508 - 511: Adresse des nächsten Sektors. Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (->filesystem_simple.h) sein. Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei. Achtung: Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD-Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD-Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben. [Bearbeiten] GPS-ZugriffDas GPS-Modul wird nach dem Einschalten mit
in den Sirf-Modus initialisiert und je nach Parameter der USART-RX-Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht. Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2% Abweichung. Der Ablauf:
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden. Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse. [Bearbeiten] LED- und TastenhandlingÜber einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX-Pin vom Software-UART auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software-UART aktiviert. [Bearbeiten] Software-UART-HandlingIn der Hauptschleife wird überprüft, ob das Software-UART aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch-Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem: SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED. SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low-Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD-Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer-Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software-UART mit durchlaufenden Daten ausreicht. SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist. SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation. [Bearbeiten] MenüDie Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten. Grundsätzlich sieht die Struktur wie folgt aus: Es gibt Obermenüs (0-4) und Untermenüs (variable Anzahl). Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück. Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt. Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü. Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 4 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-). Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus. Das Menü ist zur Zeit wie folgt gegliedert
* Für 1 und 2 gilt: Erneuter Aufruf springt zum nachfolgenden Wegpunkt.
[Bearbeiten] PC-InteraktionFür den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht. [GPS Babel] eignet sich wunderbar, um ausgelesene Daten in ein Google-Earth-kompatibles Format umzuwandeln, um sich z. B. die GPS-Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden. |