wiringPi.




Tillbaka till Raspberry Pi.
Inledning.
Installation.
Pinnumrering.
C-program.
- PWM.
- Interupt.
API, Funktioner.
Referenser.



Inledning.


Den här sidan ska försöka beskriva hur programpaketet wiringPi fungerar. Jag har börjat förstå att det behövs en beskrivning på svenska hur man ska använda wiringPi. Mycket av informationen är hämtad från Gordon Hendersons hemsida och sedan översatts fritt till svenska.
Inledningsvis är det lämpligt att installera följande program/programpaket:
Geany - ett grafiskt utvecklingsverktyg.
wiringPi - programpaketet för att kunna skriva program i C.



Installation.


Här finns wiringPi, programmet för att arbeta med hårdvaran och GPIO-interfacet i C:
http://wiringpi.com/download-and-install/.

sudo apt-get install git-core
git clone git://git.drogon.net/wiringPi
git pull origin
cd wiringPi
./build


Installationsproblem.
I händelse av problem med att installera wiringPi enligt ovan prova följande:
sudo apt-get install wiringPi
Själv råkade jag ut för just detta den 20/8 2016.

Ett annat sätt är att hämta wiringPi är på följande adress:
https://github.com/WiringPi/WiringPi



Pinnumrering.





Ansluta en knapp till Raspberry Pi.                                                                     R1 = 270 ohm



10K pull-up-motståndet drar ingången till 3V3 och gör det mer tillförlitligt än det svaga (>50K) interna pull-up.
1K seriemotståndet skyddar GPIO från en möjlig kortslutning ttill GND när knappen pressas ner, GPIO är satt till high.


Alternativt kan man använda det inre pull-up-motståndet:

För att avläsa rätt värde på knappen behöver vi sätta det interna pull-up-motståndet i Raspberry Pi annars kommer input att flyta och ge ett osäkert värde (0 eller 1).
Exempel på kommando:
pinMode (1, INPUT) ;
pullUpDnControl (1, PUD_UP) ;
leds [1] = 0 ;




Till början.



C-program.





PWM (“Analog”) Output
För PWM-pin, kan du använda pwmWrite([pin], [0-1023]) för att sätta den till ett värde mellan 0 och 1024. Som ett exampel…
pwmWrite(18, 723);





Till början.



API, funktioner.


Här finns API, funktioner i wiringPi beskrivna på engelska.

Setup Funktioner
wiringPiSetup(void) ;
- Denna funktion initierar wiringPi och förutsätter att anropande program använder wiringPi pinnumrering. Detta är en förenklad numrering som tillåter mappning    från virtuella pinnummren 0 till 16 till de verkliga underliggande Broadcom GPIO pinnummer. Jämför sidan med pinnummer med en tabell som jämför wiringPis    pinnummer med Broadcom GPIO pinnummer med fysiska platsen på Raspberry Pis kontakt(P1).
   Denna funktion kräver root privileger.
wiringPiSetupGpio(void) ;
- Denna funktion är identisk med ovanstående men tillåts anropande program att använda Broadcom GPIO pinnummer direkt utan ommappning.
   Precis som ovanstående funktion måste denna funktion anropas med root privileger.
wiringPiSetupSys(void) ;
- Denna funktion initierar wiringPi men använder /sys/class/gpio interface snarare än att anropa hårdvaran direkt. Den kan anropas som icke rootanvändare och tillåta    GPIO pinnar att exporteras innan man använder gpioprogram. Pinnumren i denna funktion refererar till Broadcom GPIO nummer.
   Notera: I denna funktion kan man endast använda pinnar som har exporterade via /sys/class/gpio interface. Man måste exportera dessa pinnar innan man anropar sitt    program. Man kan göra detta i ett separat shell-skript, eller genom att använda C's system() funktion innifrån sitt program.
   Notera även att en del funktioner (se nedan) inte fungerar utan rootprivileger.

Generella funktioner
void pinMode (int pin, int mode) ;
- Sätter pinnen till mode antingen INPUT, OUTPUT, eller PWM_OUTPUT.
   Notera att endast wiringPi pin 1 (Raspberry Pi 12) stödjer PWM output. Pinnumret är det numner som erhålls från ovanstående tabell.
   Denna funktion har ingen effekt i Sys mode.
void digitalWrite (int pin, int value) ;
- Skriver värdet HIGH eller LOW (1 or 0) till angiven pinne som tidigare måste ha blivit satts till OUTPUT.
void digitalWriteByte (int value) ;
- Skriver en 8-bit byte till de 8 GPIO pinnarna. Det är det snabbaste sättet att sätta alla 8 bits på en gång till ett värde, även om det fortfarande tar två skrivningar till    GPIO hårdvaran.
void pwmWrite (int pin, int value) ;
- Skriver värdet i PWM register för angiven pinne. Värdet måste ligga inom 0 och 1024.

   (Återigen, notera att endast pinne 1 (Raspberry Pi nr 12) stödjer PWM)

   Denna funktion har ingen effekt i Sys mode. (se ovan)
int digitalRead (int pin) ;
- Denna funktion returnerar värdet på angiven pinne. Detta är HIGH eller LOW (1 or 0) beroende på logisk nivå på pinnen.
void pullUpDnControl (int pin, int pud) ;
- Sätter pull-up eller pull-down resistor mode för angiven pinne, vilken ska vara satt som input. Till skilnad från Arduino, BCM2835 har både pull-up och down interna    resistors. Parametern pud ska vara; PUD_OFF, (ej pull up/down), PUD_DOWN (pull till jord) eller PUD_UP (pull till 3.3v).
   Denna funktion har ingenno effekt i Sys mode. Om man behöver activatera en pull-up/pull-down, kan man göra det med gpio program i ett skript innan man startar    sitt program.

PWM kontroll
PWM kan inte användas när man kör i Sys mode.
pwmSetMode (int mode) ;
- PWMgeneratorn kan köras i 2 moder – “balanserad” and “mark:space”. mark:space mod är den vanliga, men grundmode i Pi är “balanced”. Man kan växla mode    genom att sätta parameter PWM_MODE_BAL eller PWM_MODE_MS.
pwmSetRange (unsigned int range) ;
- Denna funktion sätter storleksregistret i PWMgeneratorn. Grundvärde är 1024.
pwmSetClock (int divisor) ;
- Denna funktion sätter divisorn för PWMklockan.
   För att förstå mer om PWMsystemet, behöver man läsa Broadcom ARM handbok om kringutrustning.

Tidsfunktioner
unsigned int millis (void) ;
- Denna funktion returnerar ett tal representerande antal millisekunder sedan programmet anropat en av wiringPiSetup funktionerna. Funktionen returnerar ett 32-bitars    heltal som omfattar maximalt 49 dagar.
void delay (unsigned int howLong) ;
- Funktionen orsakar att programexekveringen att avstanna för åtminstone howLong millisekunder. Pågrund av multi-tasking i Linux kan den bli längre.
   Notera att den maximala fördröjningen är en unsigned 32-bitars heltal på motsvarande omkring 49 dagar.
void delayMicroseconds (unsigned int howLong) ;
- Funktionen får programexekveringen att stanna i åtminstone howLong mikrosekunder. På grund av multi-tasking i Linux kan den bli längre.
   Notera att den maximala fördröjningen är ett anges med ett unsigned 32-bitars heltals mikrosekunder eller omkring 71 minuter.

Programprioritet
int piHiPri (int priority) ;
- Detta försöker att ändra ditt program till en högre prioritet och gör det möjligt till realtidskörning. Prioritetsvärdet kan ligga mellan 0 (grundinställning) och 99    (maximum). Detta gör inte ditt program snabbare men ger det en större del av tiden än andra program vid exekvering. Prioritetsparametern arbetar relativt till andra –    så man kan ge ett program prioritet 1 och andra prioritet 2 och det får samma effekt som att sätta ett program till 10 och ett annat till 90 (så länge inget annat    program körs med större prioritet).
   Returvärdet är 0 för lyckat resultat och -1 om ett fel uppstått. Om ett fel inträffat, programmet ska då testa mot en global felvariabel på vanligt sätt.
   Notera: Endast program som körs med rootprivilegier kan ändra sin prioritet. Om programmet körs utan rootprivilegier kommer ingenting att ske.

Avbrott (interupt)
Med en nyare kernel patchad med GPIO avbrottshanteringskod, (t ex. alla kernel efter Juni 2012), kan du nu vänta på ett avbrott i ditt program. Detta frigör processorn att utföra andra uppgifter medans den väntar på ett avbrott interrupt. En GPIO kan sättas att avbryta stigande, fallande eller båda händelserna på en inkommande signal.
Notera: Jan 2013: waitForInterrupt() functionen är ogilltig – man ska använda den nyare och lättare att använda wiringPiISR() functionen nedan.
int waitForInterrupt (int pin, int timeOut) ;
- Vid anrop väntar den på en avbrottshändelse ska inträffa på den pinnen och programmet kommer att stanna. timeOutparametern anges i millisekunder, eller kan vara -1    vilket betyder att vänta i evighet.
   Returvärdet är -1 om ett felinträffat (och errno kommer att sätttas till ett lämpligt värde), eller till 0 om tiden löpt ut, eller 1 vid ett lyckat avbrott (interrupt). Innan    man anropar waitForInterrupt måste man först initialisera GPIOpinnen och gällande det enda sättet att göra det är att använda gpioprogram, antingen i ett skript, eller    genom att använda system() anrop innifrån ditt program. t ex. vi vill vänta på en falling-edgeavbrott på GPIOpinne 0, för att sätt upp hårdvaran behöver vi köra:
   gpio edge 0 falling
   innan vi kör programmet.
int wiringPiISR (int pin, int edgeType, void (*function)(void)) ;
- Denna funktion lagrar en funktion för att ta emot avbrott (interrupts) på angiven pinne. edgeType-parametern är antingen INT_EDGE_FALLING,    INT_EDGE_RISING, INT_EDGE_BOTH eller INT_EDGE_SETUP. Om det är INT_EDGE_SETUP kommer inte initiering av pinnen att ske – det förutsetts att man    redan angivit pinnen någon annan stans (t ex. med gpio-programmet), men ifall man specificerat någon av de andra typerna så kommer pinnen att överförd och    initialiserad enligt specificering. Detta fullbordas via ett lämligt anrop till ett gpio-utility-program, så den behöver tillgång till.
   Pinnumret nås i aktuell mode – wiringPi, BCM_GPIO eller Sys modes. Denna funktion fungerar i alla moder och behöver inte rootprivileier för att fungera.    Funktionen anropas när avbrottet triggas. När den är triggad nollställs den innan den anropar din function så om upprepade avbrott inträffar innan du avslutat din    funktion så kommer den inte att missa avbrottet. (Men den kan endast känna av ytterligare ett avbrott/interrupt. Om fler än ett avbrott kommer medans det första    behandlas så kommer de att ignoreras)
   Denna funktion körs med hög prioritet (om programmet körs som root) och exekveras i konkurans med huvudprogrammet. Det har full access till alla globala    variabler, open file handles och så vidare. Se isr.c exampelprogram för flera detaljer och hur man använder dess egenskaper.

Konkurrent processing(multi-threading)
wiringPi är en förenklat gränssnitt till Linux implementering av Posix's trådning, så väl som en (förenklad) mekanism för att accessa mutex’s (inbördes uteslutning).
Med användning av dessa funktioner kan man skapa en ny process (en funktion inom ditt huvudprogram) som körs i samverkan med ditt huvudprogram och använder mutex-mekanismen, och utväxla variables variabler mellan dem på ett säkert sätt.
int piThreadCreate (name) ;
- Denna funktion skapar en tråd som är en annan funktion i ditt program som tidigar deklarerats genom att använda PI_THREAD deklarering. Denna funktion körs i    samverkan med ditt huvudprogram. Ett exampel kan vara att få funktionen att vänta på ett avbrott(interrupt) medans ditt program jobbar vidare med andra uppgifter.    Tråden kan peka på en händelse eller åtgärd genom att använda globala variabler för att meddela tillbaka till huvudprogrammet eller till andra trådar.
   Trådfunktioner deklareras på följande sätt:

   och startas i huvudprogrammet med :

   Detta är verkligen ingeting mer än en förenklat gränssnitt av Posix's trådmekanism som Linux supportar.
   Se manualen för Posix's trådar (man pthread) ifall du behöver större kontrol på dem.
piLock (int keyNum) ;
piUnlock (int keyNum) ;
- Dessa funktioner tillåter dig att synkronisera uppdatering av variabler från ditt huvudprogram program till valfri tråd som körs i ditt program. keyNum är ett tal mellan    0 och 3 och representerar en “key”. När en annan process försöker låsa samma nyckel(key), kommer den att vänta tills den första processen har låst upp samma    nyckel(key).
   Man kan behöva denna function för att försäkra sig om att man får rätt data när byter data mellan sitt huvudprogram och en tråd – annars är det möjligt att tråden    vaknar halvvägs under din kopiering av data eller ändring av data – så att man får en ofullständig kopiering, eller felaktiga data. Se wfi.c programmet i exempelmappen.

Diverse funktioner
piBoardRev (void) ;
- Returnerar Raspberry Pi's kortets revision. Det kommer att vara antingen 1 eller 2. En del av BCM_GPIO pinnar ändrar nummer och funktion när man flyttar från    kortrevision 1 till 2, så om man använder BCM_GPIO pinnummer, så behöver man ta hänsyn till skillnaden.
wpiPinToGpio (int wPiPin) ;
- Returnerar BCM_GPIO pinnummer för angivet wiringPi pinnummer. Den tar hänsyn till kortets revisionnummer.
setPadDrive (int group, int value) ;
- Sätter “styrkan” hos paddrivers för en bestämd grupp pinnar. Det finns 3 grupper pinnar och drive-styrkan är från 0 till 7. Använd inte detta om du inte vet vad du gör.



Till början.



Referenser.


Gordon Hendersson wiringPi.



Till början.