GPS Logger Mini

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche
New gLogger logo.svg

Von Martin Matysiak

Einleitung

Nachdem ich mit meinem GPS Logger nun schon seit zwei Jahren erfolgreich diverse Strecken und Touren aufzeichne, wurde es Zeit für eine Neuauflage des Gerätes. Vor allem die Größe war auf Radfahrten eher hinderlich, hinzu kam die störanfällige Kabelverbindung des GPS-Moduls, die den alltäglichen Belastungen nicht immer stand hielt. Ein weiterer Aspekt beim Entwurf der zweiten Version, der mir wichtig war, ist eine leichte Nachbaumöglichkeit des Loggers. Aus diesem Grund verwende ich nur Bauteile, die bei den bekannten Distributoren erhältlich sind. Die Platine ist exakt auf das Gehäuse abgestimmt, sodass eine stabile Konstruktion gewährleistet ist.

Nachfolgend eine Auflistung der wichtigsten Änderungen im Vergleich zum Vorgänger:

  • Deutlich kleiner (Außenmaße: 5cm x 5cm x 2cm)
  • Integrierte Ladeschaltung
  • Keine Schalter/Tasten - einlegen der SD-Karte schaltet das Gerät ein, herausnehmen schaltet es aus
  • Aus Platzgründen verzicht auf ein FAT-Dateisystem auf der SD-Karte - Stattdessen Einsatz des selbstentwickelten "NoFS" (No FileSystem)
  • Kein Schutz vor Tiefentladung. In der Regel sind LiIon Akkus durch eine interne Schaltung vor Tiefentladung geschützt. Sollte dies nicht der Fall sein bitte den Akku regelmäßig laden
  • Geschätzte Akkulaufzeit: 10 bis 15 Stunden
  • Doppelseitiges Layout, GPS-Modul befindet sich direkt auf der Platine (höhere Stabilität)

Eine Beispielroute, die mit dem gLogger Mini aufgezeichnet wurde, kann auf Google Maps betrachtet werden. Einige Kurven sind dort sehr geschnitten, das liegt an der maximal möglichen Anzahl an Koordinaten bei Google Maps, weswegen der Pfad dementsprechend vereinfacht werden musste.

Platine

Oberseite der Platine
Unterseite der Platine

Die Platine ist von den Maßen her nach den Vorgaben des Gehäuses gestaltet. Mit Hilfe der zwei Bohrungen lässt es sich somit passgenau montieren. Ich habe ein doppelseitiges Layout erstellt, bei dem fast ausschließlich SMD-Bauteile zum Einsatz kommen, um möglichst viel Platz zu sparen. Das GPS-Modul ist fest auf der Platine angebracht, lediglich der Akku wird über ein kurzes Kabel zur Platine herangeführt. Alle Bauteile passen ohne große Probleme in das Gehäuse, näheres dazu in den folgenden Abschnitten.

Der Schaltplan sowie das Layout wurde mit Eagle erstellt, der Projektordner kann im "Downloads"-Bereich abgerufen werden. Ober- und Unterseite der Platine sind auf den beiden Fotos dargestellt, nachfolgend noch der Schaltplan des gLogger Mini:

GLoggerMini schaltplan.png

Aus Platzgründen wurde auf viele Extras des vorherigen GPS Loggers verzichtet, so wird die Akkumulatorspannung nicht mehr kontrolliert und die unverbundenen Pins sind auch nicht mehr zu Steckern herausgeführt. Auch auf einen klassischen ISP-Programmierstecker habe ich verzichtet. Auf der Unterseite der Platine sind allerdings alle 6 notwendigen Kontakte als große Lötpads freigelegt, an denen man Kabel zu einem passenden Stecker anlöten kann (siehe Bauanleitung). Da der Mikrocontroller in der Regel nur einmalig oder nur sehr selten umprogrammiert werden muss, halte ich diesen Mehraufwand für vertretbar.

Zusammenbau

In diesem Abschnitt möchte ich eine Schritt für Schritt Anleitung zum Zusammenbau des "gLogger Mini" anbieten, sodass jeder einen Nachbau schafft. Im Abschnitt "Benötigte Bauteile" befinden sich nicht nur die Bauteile für die Platine, sondern auch alle anderen Bauteile, die für den Zusammenbau notwendig sind. Der dort aufgeführte Gesamtpreis entspricht somit ziemlich genau dem, was für einen Nachbau ausgegeben werden muss (zzgl. Versandkosten und MwSt. bei Farnell). Das Einzige, was dort nicht aufgelistet ist, sind zwei Schrauben zum fixieren der Platine im Gehäuse. Diese sollten sich allerdings im Haushalt oder im nächsten Baumarkt kostengünstig auftreiben lassen. Näheres dazu in der Anleitung.

Benötigte Bauteile

Bauteil Beschreibung Wert Bauform Distributor Preis
C1 Keramik-Kondensator 1µF 0805 Alle 0,07€
C2 Keramik-Kondensator 1µF 0805 Alle 0,07€
C3 Keramik-Kondensator 10nF 0805 Alle 0,05€
C4 Keramik-Kondensator 100nF 0805 Alle 0,05€
C5 Keramik-Kondensator 100nF 0805 Alle 0,05€
C6 Keramik-Kondensator 22pF 0805 Alle 0,05€
C7 Keramik-Kondensator 22pF 0805 Alle 0,05€
C8 Keramik-Kondensator 100nF 0805 Alle 0,05€
IC1 Low-Drop Spannungsregler 3.3V LP2985 SOT23-5L F 0,56€
IC2 Laderegler MAX1555 SOT23-5L F 2,41€
IC3 Mikrocontroller ATMega88 TQFP32 F 3,56€
IC4 MicroSD-Kartenslot Hirose DM3B SMD F 2,23€
IC5 GPS-Modul ST22 - P 20€
LED1 SMD Leuchtdiode ROT 1206 Alle 0,08€
LED2 SMD Leuchtdiode GRÜN 1206 Alle 0,08€
Q1 Quarz 7,3728MHz HC49/S Alle 0,18€
R1 Widerstand 470Ω 0805 Alle 0,10€
R2 Widerstand 10kΩ 0805 Alle 0,10€
R3 Widerstand 10kΩ 0805 Alle 0,10€
R4 Widerstand 470Ω 0805 Alle 0,10€
X1 USB Buchse Mini-B 5 pol. SMD R 0,24€
- Akku 600mAh iPod Mini R 5,30€
- Gehäuse Hammond 1551R 5x5x2cm³ C, F 1,67€
- Platine Ich! 10€
Gesamtpreis 47,15€

Als Farnell-Alternative sei hbe-shop.de genannt, bei dem auch von Privat bestellt werden kann. Der Shop nutzt die Farnell-Bestellnummern.

Anleitung

Da fast ausschließlich SMD-Bauteile verwendet werden, sollten generelle Lötkenntnisse vorhanden sein. Diese Anleitung ist lediglich meine Vorgehensweise beim zusammenbau des Geräts. Es besteht kein Zwang, die selbe Reihenfolge einzuhalten. Mit dieser Anleitung möchte ich lediglich auf ein paar Feinheiten bei der Montage hinweisen.

Schritt 1: Fangen wir mit der Oberseite der Platine an. Diese ist relativ unkritisch, alle SMD Bauteile können schon aufgelötet werden. Lediglich mit den beiden größten Bauteilen sollte man noch warten. Dies wäre zum einen der Quarz, der nach dem Verlöten mit zwei "Löthügeln" auf der Unterseite das Befestigen des Mikrocontrollers stören könnte. Zum anderen handelt es sich um das GPS-Modul. Man kann es eigentlich auch jetzt schon auflöten, wenn man allerdings nachher noch selber am Programm für den Mikrocontroller arbeiten möchte, sind freie UART-Leitungen zwecks Debugging sehr hilfreich. Aus diesem Grund habe ich mir das Modul für den Schluss aufgespart.

Tipp: Bei Bauteilen mit vielen Pins (z. B. die USB-Buchse) kann man ruhig viel Lötzinn verwenden, auch wenn Lötbrücken entstehen. Das überschüssige Zinn kann man dann mit einer Entlötlitze entfernen, anschließend hat man sehr gut aussehende Lötstellen. Das verfahren erläutere ich allerdings gleich noch einmal mit Bildern beim Mikrocontroller.

Tipp: Wenn man nur SMD-1206-Bauteile auf Lager haben sollte, bekommt man diese auch ganz gut auf die 0805er Pads. Ein Beispiel dafür findet sich in der Abbildung (die 22pF Kondensatoren in der Nähe des Quarzes).

Platine nach Schritt Eins

Schritt 2: Nun sind SD-Slot und Mikrocontroller dran. Da beide sehr geringe Pinabstände besitzen, ist das Verfahren zum Verlöten bei beiden Teilen sehr ähnlich. Ich verwende die Methode mit einer Entlötlitze, welche im nachfolgenden Bild dargestellt ist. Das Verfahren ist relativ simpel:

a) Bevor das Bauteil platziert wird, zunächst die Pads mit etwas Lötpaste bedecken, sodass der Lötvorgang später vereinfacht wird (optional). Anschließend wird das Bauteil ausgerichtet und an zwei Pads (am besten gegenüberliegend) fixiert

b) Eine Kante wird großzügig mit Zinn bedeckt und verlötet

c) Mit einer Entlötlitze wird so lange überschüssiges Zinn wieder entfernt, bis keine Zinnbrücken mehr vorhanden sind

d) Wiederholung von Schritt b und c bei den verbleibenden Kanten

Das Ergebnis ist eine sehr gut aussehende Lötstelle mit optimalem Kontakt.

Glm tqfp.jpg

Schritt 3: Die kritischsten Bauteile befinden sich nun auf der Platine. Was noch fehlt, sind einige Kondesatoren, ein Widerstand sowie (falls vorhin weggelassen) der Quarz und das GPS-Modul. Nach dem erfolgreichen Löten sollte die Platine wie beim nebenstehenden Bild aussehen.

Fast fertige Platine

Schritt 4: Nun muss noch der Akkumulator mit der Platine verbunden werden. Ausgeliefert wird er mit einem Stecker - eigentlich war eine passende Buchse geplant, leider haben wenige Millimeter für diesen Plan gefehlt. Aus diesem Grund muss der Stecker behutsam entfernt werden (die Kabel nicht davor abschneiden, sonst sind sie zu kurz!). Schaut man auf die Unterseite der Platine (die Seite mit µC und SD-Slot), so sollten die Kabel von links an die Vias herangeführt werden, damit alles gut in das Gehäuse passt. Hierbei muss man ein wenig probieren, bis es passt.

Schritt 5: Bevor der Mikrocontroller programmiert wird, sollte man zunächst den Akkumulator vollständig aufladen (wer weiß, in welchem Zustand er ankommt..). Hierfür einfach das Gerät per USB entweder an den Computer oder an ein Netzteil mit USB-Buchsen-Ausgang stecken. Wenn alles geklappt hat, leuchtet jetzt die rote LED, die anzeigt, dass der Akku geladen wird. Zeit für eine kleine Pause :-)

Schritt 6: In der Zwischenzeit kann man sich natürlich auch den Programmieradapter basteln. Ich habe hierfür einen 2x3-Pin Stecker auf eine Lochraster Platine gebracht und anschließend an jeden Pin ein Stück Draht angelötet, welcher nachher mit den entsprechenden Pads auf der Platine verbunden werden muss. Das nebenstehende Foto zeigt meine Konstruktion. Es gilt folgende Pinbelegung:

Avr-isp-pinout.png

ISP-Programmieradapter

Schritt 7: Sobald der Akku geladen und der Programmieradapter verbunden ist, wird es Zeit, das Gerät zu programmieren. Damit das Gerät Strom bekommt, muss während dieses Vorgangs eine MicroSD-Karte eingelegt sein. Neben dem Programm müssen auch die Fuses richtig eingestellt werden. Ich verwende hierfür das Programm "avrdude" mit folgenden Parametern[1]:

-U lfuse:w:0xdc:m -U hfuse:w:0xdf:m

Ist das Gerät richtig programmiert, dürfe die grüne LED nach einem Initialisierungsvorgang mit einer Frequenz von 1Hz aufblitzen (wenn man nichts an den eingehenden NMEA-Kommandos verändert hat). Sollte dies der Fall sein, kann man nun den Programmieradapter wieder entfernen und die Platine im Gehäuse verschrauben.

Schritt 8: Leider liefert das Gehäuse nur Schrauben mit, um den Deckel zu befestigen, nicht aber für die inneren zwei Gewinde zur Befestigung der Platine. Diese muss man entweder zu Hause oder im nächsten Baumarkt suchen. Bei meinem Prototypen habe ich 2x12-Holzschrauben verwendet. Diese waren minimal zu lang! Ich würde also 2x10 oder 2x8 Schrauben empfehlen. Wichtig ist, dass sowohl die äußeren als auch die inneren Schrauben nicht zu fest angeschraubt werden dürfen. Ansonsten herrscht ein zu großer Druck auf den Kartenslot und die Karte verklemmt sich beim Einlegen oder Herausnehmen. Nach dem Anschrauben also immer prüfen, ob die Karte noch gut passt. Auf einer Seite des Gehäuses muss man etwas vom Plastik wegschneiden, damit Zugang zum USB-Port und zum Speicherkarten-Slot gegeben ist.

Software

AVR

Geöffneter gLogger Mini während des Ladevorgangs

Die Software für den Mikrocontroller besteht aus mehreren einzelnen Modulen, die in der Hauptdatei zusammengesetzt und abgefragt werden. Der generelle Ablauf des Programms sieht wie folgt aus:

  • NMEA-String vom GPS-Modul holen
  • Wenn GPS Fix, dann NMEA-String auf SD-Karte schreiben
  • Einmal als optisches Feedback die LED aufblitzen lassen
  • Schlafen legen, auf den nächsten Datenempfang per UART warten

Es ist zu beachten, dass die LED bei jedem eingehenden NMEA-Kommando blinkt, und nicht etwa bei jedem Schreibvorgang. Sollte die SD-Karte also trotz mehrfachen Blinkens leer sein, so hatte das Modul höchstwahrscheinlich keinen GPS-Fix. Während der Initialisierung der Module leuchtet die grüne LED dauerhaft. Wenn sie anschließend mit einer relativ hohen Frequenz blinkt (um genau zu sein 5Hz), so konnte entweder die SD-Karte oder das GPS-Modul nicht initialisiert werden. Die rote LED ist nicht mit dem Mikrocontroller verbunden und dient nur zum Anzeigen des Ladevorgangs (leuchtet sie bei eingestecktem USB-Kabel, so wird der Akku momentan geladen. Sobald die LED erlischt, ist der Ladevorgang beendet und der Akku aufgeladen).

Standardmäßig werden nur $GPGGA-Meldungen aufgezeichnet. In der Datei modules/gps.c lässt sich dies in der Funktion gps_init() allerdings leicht verändern. Man muss lediglich die Werte der Variable commands (Z. 31) ändern:

  unsigned char commands[8] = {
    0x01, //GGA 1Hz
    0x00, //Keine GSA
    0x00, //Keine GSV
    0x00, //Keine GLL
    0x00, //Keine RMC
    0x00, //Keine VTG
    0x00, //Keine ZDA
    0x00}; //In SRAM&FLASH

Der Wert gibt an, in welchem Zeitintervall (in Sekunden) das Kommando vom GPS-Modul ausgegeben werden soll. Der Wert 0 deaktiviert die jeweilige Meldung.

Sollten andere Kommandos gewünscht sein, so ist es ratsam bzw. notwendig, die Prüfung nach einer validen Positionsmeldung abzuschalten. Hierfür muss man folgende Codezeilen in der Hauptschleife (gLogger.c, Z. 95-97)

    if(gps_getNmeaSentence(nmeaBuf, 128)) {
      nofs_writeString(nmeaBuf);
    }

auf folgende abändern:

    gps_getNmeaSentence(nmeaBuf, 128);
    nofs_writeString(nmeaBuf);

und schon wird jegliches eingehende NMEA-Kommando auf die Speicherkarte geschrieben. Es gibt noch einige andere Konfigurationsoptionen für das ST22 GPS-Modul. Diese sind in der Application Note AN0003 des Skytraq Venus6 Chipsatzes[2] aufgelistet.

Die Befehlsbebliothek für das NoFS ist sehr begrenzt - von Außen handelt es sich um eine Art WOM[3], ohne jegliche Lesefunktion. Da ich zum derzeitigen Zeitpunkt keine Verwendung für selbige Methode hatte, wurde erst einmal auf sie verzichtet. In zukünftigen Versionen wird eine Methode zum Lesen allerdings höchstwahrscheinlich noch folgen. Beim Schreiben von Zeichenketten (Funktion nofs_writeString) werden diese zunächst in einen Buffer zwischengelagert, der die Größe eines Datensektors auf der Speicherkarte besitzt. Um die Schreibzugriffe auf die Speicherkarte gering zu halten und trotzdem keinen großen Datenverlust zu riskieren, wird der Buffer nur dann auf die Karte geschrieben, wenn selbiger voll ist, oder es sich um den n-ten Funktionsaufruf handelt. Die Anzahl n kann in der Datei modules/nofs.h variiert werden (Konstante NOFS_WRITE_BUFFER_AFTER_NTH_COMMAND).

Die aktuelle Version der Software ist 1.4. Aktualisierungen werden hier aufgeführt. Der jeweils aktuelle Quellcode + Makefile kann auf GitHub (siehe Downloads) abgerufen werden.

In Version 1.1 wurde ein Fehler behoben, durch den vorher das Schreiben immer nur bei Sektor 1 angefangen hat. Dadurch würden bereits existente Pfade allerdings überschrieben werden. Vielen Dank an Ralf Fischer für die Erkennung und gleichzeitige Lösung des Problems!

In Version 1.2 wurde ein Fehler behoben, der allerdings nur sehr sporadisch aufgetreten ist. In seltenen Fällen kam es dazu, dass das Abschlusssymbol (0x03) nicht geschrieben wurde, sodass der Logger beim nächsten Start in einer Endlosschleife hing (da das Zeichen nicht gefunden werden kann). Dies kann nun nicht mehr passieren.

In Version 1.3 wurden zwei Fehler behoben. Zum einen war das GPS-Modul entgegen des Kommentars auf 2 Hertz Aktualisierungsrate gestellt, zum anderen hat die UART Bibliothek regelmäßig versucht, über die Arraygrenzen des Eingabebuffers zu schreiben. Per Glück oder Zufall hatte dies davor keine schwerwiegenden Konsequenzen, ist aber jetzt behoben.

In Version 1.4 wurde die Befehlsbibliothek für das GPS-Modul stark überarbeitet. Man kann nun die gewünschten NMEA-Kommandos über einen Parameter beim Befehl gps_init() konfigurieren. Insgesamt werden nun alle möglichen NMEA-Kommandos unterstützt. Die Kommandos werden auf Korrektheit (d.H. richtiger Anfang und richtige Prüfsumme) geprüft. Außerdem wird bei den Kommandos, bei denen es möglich ist, auch ermittelt, ob ein GPS-Fix vorliegt. Weiterhin wurde der gesamte Code in dieser Version aufgeräumt und dokumentiert (auf Englisch).

PC

Da beim Beschreiben der Karte auf ein Dateisystem verzichtet wurde, ist das Auslesen der Karte am PC nicht komplett ohne Zusatzsoftware möglich. Hierfür kann man das Tool "RawRead" verwenden, welches das Erstellen, Auslesen und Leeren von NoFS-Medien stark vereinfacht. Das Tool ist mittlerweile in Version 2.0 und nun als Python-Skript realisiert, sodass es auf allen Plattformen (Windows, Mac, Linux) problemlos eingesetzt werden kann. Zum Ausführen des Skripts benötigt man Python, für Windows werde ich noch eine vorkompilierte *.exe-Datei erstellen, sodass diese Voraussetzung entfällt. Weiterhin muss das Tool auf allen Plattformen mit Administrationsrechnen ausgeführt werden, da direkt auf das Laufwerk geschrieben wird.

Gesteuert wird das das Programm ausschließlich über Kommandozeilenparameter. Für eine Übersicht an verfügbaren Befehlen kann man das Programm mit "python rawread.py --help" ausführen.

RawRead besitzt einen Mechanismus, der automatisch das richtige Laufwerk auswählt, sodass man den Pfad nicht manuell spezifizieren muss. Auch, wenn man eine neue Karte erstmalig mit einem NoFS beschreiben möchte (Parameter "-c"), wird über ein bestimmtes Verfahren sichergestellt, dass ausschließlich auf die Speicherkarte (und nicht etwa auf die Systemfestplatte) geschrieben wird.

Das NoFS besitzt eine recht lineare Struktur und ist nach folgendem Schema aufgebaut:

<Header><Daten><0x03>

Der Header besteht aus der Zeichenfolge k621.de (einfallslos, ich weiß). Danach folgen fortlaufend die Daten (wobei diese kein 0x03 enthalten dürfen). Abschlusscharakter ist ein 0x03 (== ETX, End of Text). Nachfolgende Daten werden ignoriert. Um eine Karte zu leeren genügt es, in den Ersten Sektor ein k621.de<0x03> zu schreiben. Der gLogger Mini sucht immer das erste Auftreten eines 0x03 und beginnt an dessen Stelle den Schreibvorgang. Das Dateisystem (wobei es eigentlich gar keines ist) besitzt durchaus seine Schwächen, ist jedoch für die Zwecke des GPS-Loggings komplett ausreichend und mit Mikrocontrollern deutlich leichter zu Handhaben als das FAT-Dateisystem.

Das Ergebnis des Auslesevorgangs ist eine Datei, die die aufgezeichneten NMEA-Kommandos beinhaltet. Diese kann man nun beispielsweise mit meiner NMEA-Toolbox zu Google-Maps Daten konvertieren. Das "RawRead" Tool inklusive Quellcode befindet sich im Downloads-Bereich.

Mac

Hier mal der Weg, den ich für den Einsatz am Mac nutze, denn der Martin hat ja mit seinem RawRead.exe den Windows-Pfad beschritten.

Um die Daten von der Karte zu lutschen, nutze ich /bin/dd, also ein Bordmittel am Mac. Die übliche Warnung, if und of nicht zu vertauschen, und das richtige Device zu nehmen, erwähne ich hiermit nur der Vollständigkeit halber. Evtl. Fahrlässigkeit kann fantastische Folgen haben.

$ dd if=/dev/disk1 of=~/Desktop/dump.bin

Das File ist bei mir 2 GB groß -- je nach Karte halt. Das dauert ne Weile. Man kann ein Gefühl dafür entwickeln (oder es berechnen), wie lang der letzte Track war und wie viele Blöcke dazu von der Karte geholt werden müssen und dafür das Kommando mit count=xyz verkürzen. Die Angabe des Device /dev/disk1 variiert natürlich je nach Bestückung mit Geräten am USB. Das richtige zu finden klappt mit dmesg oder klicki-bunti mit dem System-Profiler (Snow Leo) oder Systeminformationen (Lion). Das File dump.bin kann man dann dem Java-Programm NMEA-Toolbox zum Konvertieren vorwerfen. Java-Programme laufen auf dem Mac unter Snow Leo sofort und auch unter Lion direkt nach Installation der JRE ohne Mucken. So weit, so gut. Nun der zweite Teil:

Das Präparieren der Karte für den nächsten Aufzeichnungslauf (vgl. Karte leeren im Abschnitt für PC) mache ich mit einem nachinstallierten Progrämmchen namens hexedit. Das kann genau das, was es im Namen trägt. Und es kann es auch auf Devices, nicht nur auf Files. Installiert habe ich es aus dem Debian-Package-Fundus, der für Mac-Nutzer über eins der Projekte MacPorts oder Fink Einzug findet. Das ist am Anfang etwas mühsam, lohnt sich aber insgesamt, speziell wenn man z.B. eine Toolchain für AVR oder ARM oder ähnliches installieren möchte. Mühsam ist es auch deshalb, weil es wird das Developer-Package (Xcode) von Apple als Voraussetzung verlangt. Ist z.B. MacPorts installiert, kann mit

# port install hexedit

das Paket installiert werden. Wenn der hexedit läuft, macht man schnell noch das Device beschreibbar mit

# chmod 666 /dev/disk1

und dann läßt sich mit

# hexedit /dev/disk1

der Editor starten und die ersten Bytes der SD-Karte mit den 8 Bytes k621.de<0x03> beschreiben. Danach ist die Karte bereit für den neuen Einsatz.


Downloads

Forendiskussionen

Einzelnachweise

  1. Änderungen im Vergleich zu den Standardfuses: CKDIV8 abgeschaltet, Clock Source = Ext. Crystal Osc., 3-8Mhz, 258/14CK + 65ms Startup Time
  2. AN0003 (*.PDF)
  3. Write-Only-Memory