Detta är som sagt den tredje delen i serien med Raspberry Pi (RPi) och GPS. I fösta delen kopplades GPS-modulen ihop med RPi:n via den inbyggda UART:en, och i andra delen användes en daemon för att läsa och koppla positionsinformation till Pythonkoden. I slutet av del två så hade jag en skräddarsydd GPS-logg som skrev data till en fil.
Jag har nu förfinat koden lite så att loggen döps automatiskt och skrivs till ett kopplat USB-minne i stället, vilket blir mer praktiskt än att behöva ta ur det lilla SD-kortet eller koppla upp nätverk och SSH hela tiden. Mitt python skript körs även automatiskt när RPi:n bootar. Allt detta är finesser som egentligen inte behövs för att lära sig något, men om det är många som vill ha en mer detaljerad redogörelse för hur detta gjordes så säg till så kanske det blir ett inlägg om detta specifikt.
I det här inlägget så kommer det dock att bli GPIO och lysdioder och knappar. Jag släpper GPS lite så att är du bara intresserad av GPIO funktionalitet med RPi, så behöver du inte stressläsa de tidigare två delarna.
Koden i bilden överst är ett exempel på hur man kan använda GPIO via Python tolken i terminalen.
>>> import RPi.GPIO as GPIO >>> GPIO.setmode(GPIO.BCM) >>> GPIO.setup(20, GPIO.OUT) >>> GPIO.output(20, 1) >>> GPIO.output(20, 0) >>> GPIO.cleanup()
Först så importeras RPi:ns GPIO bibliotek och tilldelas namnet GPIO. I den resterande koden kan jag därför ange GPIO i stället för att behöva hänvisa till hela namnet/sökvägen.
Det finns två sätt att adressera pinnar i GPIO. BCM, vilket jag föredrar här och motsvarar numreringen som används för GPIO namnen. GPIO 20 är därför inte samma sak som pin 20. Det andra alternativet är BOARD och då menar man faktiskt pin nummer. Nu är ju inte alla pinnar GPIO, så jag tycker det är bättre att adressera GPIO namn i stället, och sedan använda en bild för att ta reda på exakt pin nummer. GPIO 20 är pin nummer 37 på en RPi B+ eller RPi 2 B.
Till pin 37, eller GPIO 20 har jag anslutet en lysdiod via en resistor till jord. Jag har byggt ett kretskort med blandade lysdioder och knappar tidigare som jag använder nu. Men en LED och resistor på ca 1k ohm i serie till jord, borde fungera fint. Blir det svårt att se ljuset så kan en resistor med mindre värde väljas.
Alla GPIO pinnar kan fungera som såväl in- som utgångar. Detta styrs av kod och kommandot GPIO.setup. Här har jag preciserat just GPIO20 som ut.
Sedan sätter jag helt enkelt denna utgång som hög (1) eller låg (0), vilket bör tända och släcka dioden. Man kan använda 1/0, True/False eller GPIO.HIGH/GPIO.LOW.
För att ”nollställa” alla GPIO portar så använder man kommandot GPIO.cleaunup().
Knappar
Knappar används på GPIO ingångar, och kopplas även dessa in med en resistor. En så kallad ”pull down” eller ”pull up” resistor, beroende på om man vill att ingången skall vara normalt hög eller låg.
Ingångar konfigureras på liknande sätt som utgångar, men nu vill jag se vad som händer när jag trycker på en knapp, så därför blir det smidigare att skriva ett python program och köra det i stället.
Knappen ansluts mellan GPIO26, i mitt fall, och matningen på 3.3 volt. Här gäller det att vara noga och inte koppla in 5V vilket kan förstöra RPi:n. För att säkerställa att det verkligen är en låg nivå när knappen inte är nedtryckt så använder jag en ”pull down” resistor. Om man vill ha normalt hög ingång så byter man plats på jord och matningsspänningen. Det är också noga att man inte kopplar matningsspänning direkt till jord, vilket skulle kunna leda till att den magiska röken läcker ut ur kretsarna.
I en del fall kan man koppla in ett litet motstånd (jämfört med pull down resistorn) mellan knapp och 3.3V också, vilket skyddar ingången i viss utsträckning.
import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) import time inpin = 26 utpin = 20 GPIO.setup(utpin, GPIO.OUT) GPIO.setup(inpin, GPIO.IN) try: while True: value = GPIO.input(inpin) if value: for i in range (0,5) GPIO.output(utpin, 1) time.sleep(0.2) GPIO.output(utpin, 0) time.sleep(0.2) else: pass except: GPIO.cleanup()
Koden ovan skall om allt fungerar bara snurra runt och vänta (while loopen). Om GPIO 26 är låg, eller ”False” så kommer endast ”pass” att exekveras, det vill säga ingenting.
När knappen trycks ned så blir GPIO26 hög och ”value” blir ”True”, vilket kommer att sätta GPIO20 hög och låg, eller tända och släcka dioden, i rask takt fem gånger.
Det är ”time.sleep” som gör att det läggs in en fördröjning i angivet antal sekunder. Om det inte fanns med tid att vänta så skulle dioden tändas och släckas så snabbt att det inte skulle gå att uppfatta.
Som vanligt är det bra att ”städa” bland portarna på RPi:n när allt är klart. Eftersom det är en ”evig” loop så måste man avsluta med ctrl+c, ett så kallat ”keybboard interrupt”, vilket fångas med kombinationen try: / except:. Det går att peka ut keyboard interrupt specifikt men här har jag använt en generell variant som fångar alla tänkbara fel, utan att skilja på dem.
För att exekvera koden på RPi:n så körs kommandot:
sudo python filnamn.py
Du byter naturligtvis ut ”filnamn.py” mot ditt eget filnamn.
Sådär, då har jag metoder för att läsa in positionsinformation från GPS-modulen och sätt att känna av om användaren vill något. Jag kan även meddela saker med hjälp av lysdioder. Det är inte mycket svårare att ansluta exempelvis en summer till en utgång om man i stället vill ha en ljudsignal.
Lite krångligare blir det om man vill ha en lite display ansluten som man kan skicka information till, men inte mycket.
Jag kommer att fortsätta att bygga något med knappar, lysdioder och kanske även en liten display, för att kunna experimentera med pythonkod och GPS.
Med knappar så kan jag relativt enkelt exempelvis samla in punkter i en egen loggfil. Olika kanppar kan betyda olika objekttyper. Om man vill kan man blanda in även analoga indata och därmed få ett inmatningsvärde som ligger mellan 0 och 1, vilket kan vara användbart i vissa situationer (kanske en sensor som mäter avståndet mellan enheten och vägbanan).
Man kan sedan skapa hur många pythonprogram man vill och till och med växla mellan olika program medan man håller på och samlar in data. Jag ser framför mig ett analogt vred med definierade gränsvärden som växlar kod beroende på vad som är inställt.
Jag vet inte nu om jag återkommer till Raspberry Pi i närtid, men om du är nyfiken så borde du ha tillräckligt i dessa tre inlägg för att kunna börja. Raspberry Pi går att få tag på överallt. Knappar, dioder och motstånd likaså. En GPS-modul är inte heller så svår att få tag på, och med rätt anslutningar och kretsar så kan man till och med använda en vanlig standard GPS så länge den har ”seriell ut” med NMEA (vilket bland annat många Garmin har).
Varning
När du kopplar in saker till RPi:n så måste du säkerställa att signalerna håller sig till 3.3 V. Att koppla in högre spänningar kan förstöra RPi:n. Vill du använda en standard GPS så kan du bygga en krets som ”isolerar” RPi:n, exempelvis med optokopplare för några kronor.
Jag vill egentligen inte peka ut en källa till var du kan få tag på komponenterna men har du bråttom så kommer här en lista via Kjell & Co.
Du behöver inte allt detta, men du behöver strömförsörjning via mikro USB och ett mikro SD kort för operativsystemet. Startkit och lite anslutningskablar är dock bra att ha om man skall göra lite olika experiment. Vill du handla via postorder så kan lawicel-shop.se vara ett alternativ (bra utbud och rimliga priser).
Vill du använda exempelvis Adafruit.com så har de ett trevligt kit med det mesta man behöver. Sedan så kan man välja en GPS hatt, eller den GPS-modul som jag använt (du behöver inte båda).
Sedan finns Sparkfun och Element14 också. I Europa så har vi exempelvis Conrad som gladeligen levererar till Sverige.
Ett tips är att även kika lite bland aktuella fyndvaror. Där kan man hitta mycket till låga priser, och allt behöver inte vara det allra senaste.
Tänk på att det kan tillkomma en del om du handlar från utlandet, så har du en butik lokalt med det du behöver så kan det bli billigare i slutändan. Däremot så finns det en hel del butiker där ute som uppenbarligen inte har en aning om hur lite elektronik egentligen kostar om man letar lite.