Har du inte läst gårdagens inlägg, så gör det inte så mycket. Där beskriver jag hur jag kopplar samman en GPS med en Raspberry Pi (RPi) till en seriell port via de inbyggda UART kretsarna.
Vill du göra motsvarande eller läsa om hur det gick till så skall du börja med det inlägget, men vill du bara veta hur du får in seriell GPS i Python (linux), då räcker det att hänga med här.
Jag kommer att använda mig av en ”daemon” med programmet GPSd.
sudo apt-get install gpsd gpsd-clients
Den port jag använder på RPi:n heter /dev/ttyAMA0, men om du har din GPS ansluten på en annan port så skall det gå bra det också.
I förra inlägget så testade jag att data kom in med terminalprogrammet screen, men om du installerar programmen ovan så kan du använda cgps i stället.
gpsd /dev/ttyAMA0 9600 cgps
Texten 9600 anger baud rate och kan i många fall uteslutas.
Du kan lägga till ”-s” efter cgps för att inte visa det seriella flödet från gpsd. Du kan även använda tangenten ”s” medan programmet körs för att slå på och av detta flöde.
Då jag ansluter till RPi:n via ssh så kan jag inte använda en del av de andra klientprogrammen, men om du har din GPS ansluten direkt till din dator så kan du prova med programmet xgps i stället för cgps.
Ett annat program som ingår bland gpsd-klienterna är en gpx-logg.
gpxlogger -d -f filnamn.gpx
Jag har inte haft hundraprocentig framgång med detta, men det fungerar oftast. Tillägget ”-d” kör programmet som deamon och sparar alla data till det filnamn som anges med ”-f”.
Använder du som jag ssh och vill ladda hem gpx-filen till den lokala datorn så kan följande kommando vara användbart.
ssh pi@server-ip 'cat filnamn.gpx' > filnamn.gpx
Kommandot kan inte köras inifrån ssh sessionen utan från den plats i filsystemet dit du vill spara loggfilen. (Avsluta ssh med ’exit’)
Python
Jag får börja med att säga att mina Python kunskaper är lite begränsade, så jag har ännu inte helt greppat vad all kod jag använder gör i detalj. Jag tycker att detta är ok, och en del i mina ambitioner att lära mig mer om Python och då framför allt ”interrupt” och ”objektorientering”. Koden jag använder kommer från flera källor på Internet, så det är fullt möjligt att du känner igen kodbitar från andra källor, men det fungerar i alla fall.
#! /usr/bin/python # -*- coding: latin1 -*- import os from gps import * # läser in pythonbiblioteket för gps import time import threading gpsd = None # Global variabel os.system('clear') # rensa terminalfönster class GpsPoller(threading.Thread): # Klass för att starta "lyssningen" på GPS porten def __init__(self): threading.Thread.__init__(self) global gpsd gpsd = gps(mode=WATCH_ENABLE) self.current_value = None self.running = True def run(self): global gpsd while gpsp.running: gpsd.next() if __name__ == '__main__': # Huvudprogrammet gpsp = GpsPoller() try: gpsp.start() while True: # Själva programloopen som körs tills... os.system('clear') print 'latitud ' , gpsd.fix.latitude print 'longitud ' , gpsd.fix.longitude print 'höjd ' , gpsd.fix.altitude print 'mode ' , gpsd.fix.mode print 'tid ' , gpsd.fix.time for i in gpsd.satellites: print i time.sleep(3) except (KeyboardInterrupt, SystemExit): # ... du trycker ctrl + c print "\nDödar tråden..." gpsp.running = False gpsp.join() print "Klart.\nAvslutar." # Nu är allt slut!
Koden består av tre delar. Inledningsvis så importeras nödvändiga bibliotek samt deklaration av globala variabler. Därefter finns en class som är den funktion som hela tiden läser av GPSd och samlar in informationen. Detta görs i en egen ”tråd” oberoende av resten av koden (det är detta jag vill lära mig mera om). Själva huvudloopen körs i en egen del av koden där det inleds med att den tidigare skapade classen startas (GpsPoller() och gpsp.start()) och sedan så körs själva while loopen så länge inga fel uppstår. Om det uppstår fel, eller om exempelvis användaren trycker ner ctrl+c så hoppar programmet till en felhantering som stänger ned trådar som körs på ett förnuftigt sätt.
När jag kör programmet med sudo python gpspy.py så får jag följande resultat i terminalen (bild ovan).
Att tänka på när man döper sina filer är att man inte kan ge dem ett namn som man också vill importera. Jag kan exempelvis inte döpa filen till ”gps.py” eftersom jag vill importera biblioteket ”gps”, men ”gpspy.py” går bra att kalla den.
I Python kan jag nu när som helst anropa gpsd och hämta information om exempelvis uppskattat fel i positionen, och använda detta för att ”göra något”.
Göra något…
I morgon så kommer jag att knyta ihop GPS data med GPIO porten på RPi:n, men så länge så skulle en skräddarsydd loggfil kunna vara något?
Först så skall filen skapas. Detta görs med två rader efter ”Try:” i koden.
log = open(”gps_logg.txt”, ”w”) log.write(”latitud, longitud, utc_tid, hojd, fart, epx, epy, epv, ept, sats”)
Därefter så skriver man data som motsvarar de kolumnrubriker som skapades ovan, varje gång loopen körs.
log.write(”%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n” % (gpsd.fix.latitude, gpsd.fix.longitude, gpsd.utc, gpsd.fix.altitude, gpsd.fix.speed, gpsd.fix.epx, gpsd.fix.epy, gpsd.fix.epv, gpsd.fix.ept, gpsd.satellites))
Koden ovan läggs in inne i ”while” loopen.
Sedan skall filen stängas när allt är klart, genom att nedanstående skrivs in i slutet av koden.
log.close()
Det var det hela. Nu skall det förhoppningsvis finnas en loggfil med data från GPS-mottagaren på den sökväg du använt.
Det går naturligtvis att utveckla koden hur mycket som helst, vilket jag också kommer att göra med min Raspberry Pi. Bland annat så kommer jag att skapa en ny loggfil varje dag, vilket kontrolleras när RPi:n startar. Koden kommer att köras automatiskt vid boot, och loggarna kommer att lagras på ett USB-minne i stället för på sd-kortet.
Vad kommer du att göra med din?
Om du kopierar och klistrar in koden här ovan så tänk på att WordPress inte använder samma teckenkod som normal ASCII för vissa tecken (brukar vara exempelvis citationstecken).
I morgon blir det lite som sagt dioder och knappar via GPIO.
För att kopiera filer mellan maskiner, så är det enklare/bättre att använda scp(1) istället för ssh(1) och cat(1) som du gör. Det fungerar men kan ersättas med
scp pi@server:~/filnamn.gpx filnamn.gpx
Då kopierar man från en fil/katalog till en fil/katalog. fil/katalog kan vara på den lokala eller servern. Fugerar så länge som servrarna som man använder har ssh-inloggning.
ex: scp pi@server1:~/filen.txt anders@server2:/home/anders/kaka.txt
Där kopierar jag från användaren pi på server1 till användaren anders på server2 och filen heter ~/filen.txt (dvs i pi:s hemmakatalog) på server1 och kopieras till /home/anders/kaka.txt på server2
Se manualsidan för ssh(1) och scp(1).