Questa pagina l'ho scritta molto tempo fa e contiene materiale obsoleto
L'uso è sconsigliato e non posso più fornire alcun supporto
Un classico: scrivere un programma che fa lampeggiare un LED! Ed il seguito (quando la fantasia domina!): accendere un LED quando si preme un pulsante.
Verrà qui descritto come ottenere questo risultato usando la shell Bash di linux, senza installare nulla in più rispetto ad una versione recente del sistema operativo Raspbian. (Nota 1)
L'hardware è semplicissimo: un singolo LED in serie ad una resistenza, collegati tra una delle uscite (per esempio GPIO22 - pin 15) e massa (Ground - pin 25): quando l'uscita vale 1 logico, il LED è acceso, altrimenti è spento. Di seguito lo schema elettrico:
Il valore della resistenza non è critico, va bene un valore qualunque tra 220 e 470 Ω. Per conoscere la numerazione completa presente sul connettore potete andare alla pagina dedicata alla descrizione del connettore GPIO.
Preliminarmente occorre verificare la corretta configurazione del sistema e dell'utente.
L'utente deve appartenere al gruppo gpio:
pi@raspberrypi:~ $ groups
pi adm dialout cdrom sudo audio video plugdev games users input netdev
gpio i2c spi
In caso negativo, occorre aggiungerlo:
pi@raspberry:~ $ sudo usermod -a -G gpio pi
In Linux anche i dispositivi fisici sono visti come file. Per poter leggere e/o scrivere e/o "eseguire" un file occorre che l'utente o il suo gruppo possieda gli opportuni diritti di Read, Write e eXecute. In particolare siamo interessati a quanto si trova al di sotto di /sys/class/gpio:
pi@raspberrypi:~ $ ls -l /sys/class/gpio/export
-rwxrwx---
1 root gpio 4096
Mar 6 11:07 /sys/class/gpio/export
Come prima cosa occorre creare l'interfaccia (cioè il "file") verso un particolare pin, scrivendo il numero del pin che si vuole utilizzare nel file export. Per GPIO22 occorre quindi digitare:
pi@raspberry:~ $ echo 22 > /sys/class/gpio/export
Questo comando crea una struttura formata da molti file:
pi@raspberrypi:~ $ ls -l /sys/class/gpio/gpio22/
total 0
-rwxrwx--- 1 root gpio 4096 Mar 6 11:55 active_low
lrwxrwxrwx 1 root gpio 0 Mar 6 11:55 device -> ../../../20200000.gpio
-rwxrwx--- 1 root gpio 4096 Mar 6 11:55 direction
-rwxrwx--- 1 root gpio 4096 Mar 6 11:55 edge
lrwxrwxrwx 1 root gpio 0 Mar 6 11:55 subsystem -> ../../../../../../class/gpio
-rwxrwx--- 1 root gpio 4096 Mar 6 11:55 uevent
-rwxrwx--- 1 root gpio 4096 Mar 6 11:55 value
Ci interessiamo solo a due di questi due file:
A questo punto siamo in grado di scrivere uno script bash capace di far lampeggiare il LED:
pi@raspberrypi:~ $ nano blink.sh
#!/bin/bash
echo 22 > /sys/class/gpio/export
sleep 0.5
echo out > /sys/class/gpio/gpio22/direction
while :
do
echo 0 > /sys/class/gpio/gpio22/value
sleep 0.2
echo 1 > /sys/class/gpio/gpio22/value
sleep 0.2
done
pi@raspberrypi:~ $ chmod +x blink.sh
pi@raspberrypi:~ $ ./blink.sh
Il ritardo inserito di due decimi di secondo rende visibile il lampeggio del LED che altrimenti verrebbe percepito dall'occhio umano come sempre acceso anche se poco luminoso.
Il ritardo di mezzo secondo è necessario solo al primo utilizzo, per dare al sistema il tempo di attivare il modulo.
Quando non serve più utilizzare il pin è cosa buona liberare la risorsa:
pi@raspberrypi:~ $ echo 22 > /sys/class/gpio/unexport
Se avete installato wiringPi, in questa pagina è mostrato un modo alternativo per ottenere lo stesso effetto
Anche in questo caso il circuito è semplice.
Per poter leggere lo stato dell'interruttore (aperto/chiuso → 1/0) occorre prima configurare il GPIO21 (pin 40) come ingresso e quindi leggere il valore.
vv@vvrpi ~ $ echo 21 > /sys/class/gpio/export
vv@vvrpi ~ $ echo in > /sys/class/gpio/gpio21/direction
vv@vvrpi ~ $ cat /sys/class/gpio/gpio21/value
1
Oppure, dopo aver chiuso l'interruttore:
vv@vvrpi ~ $ cat /sys/class/gpio/gpio21/value
0
É utile sapere che, all'accensione, tutti i pin sono già configurati come ingresso.
Di seguito un esempio di programma che permette di accendere un LED premendo un pulsante (anche se lo stesso risultato poteva essere ottenuto con un semplice filo...). Il circuito e il codice di inizializzazione (export, direction e permessi) sono gli stessi dei due precedenti esempi.
#!/bin/bash
while true;
do
SW=`cat /sys/class/gpio/gpio21/value`
echo $SW > /sys/class/gpio/gpio22/value
done
Ci si potrebbe chiedere quanto tempo richiede l'operazione di accensione o spegnimento di un LED. Molto!
Per esempio, togliendo dal primo degli script sopra presentati la doppia chiamata a sleep, otteniamo frequenze dell'ordine del kHz. Questo significa che la singola operazione di echo (e azioni conseguenti) richiede un tempo dell'ordine delle centinaia di microsecondi, tempo accettabile solo per gestire processi estremamente lenti, tipicamente l'interfaccia verso un "umano".
Ci sono inoltre due problemi assai importanti che rendono problematico tale meccanismo per eseguire codice dove sono richiesti tempi di esecuzione rapidi e certi:
L'effetto è mostrato nel diagramma temporale seguente, dove addirittura si vede un "buco" di diversi millisecondi.
Prima di creazione di questa pagina: luglio 2013
Ultima
modifica: 5 marzo 2016
Raspberry Pi: note di hardware - Versione 1.31 - Luglio
2019
Copyright 2013-2019, Vincenzo Villa (https://www.vincenzov.net)
Quest'opera è stata rilasciata con licenza Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported.