Salta la barra di navigazione [1] - Vai alla barra di navigazione [3] - Scrivimi una mail [4]

Rapsberry Pi: LED e interruttori con bash

Raspberry Pi - Note di hardware - Sommario - Novità - Tutorial - Progetti - Risorse - Non solo elettronica

In fase di sviluppo Questa pagina è obsoleta In fase di sviluppo

Un LED collegato al RaspBerry Pi

Questa pagina va utilizzata solo se dispone di una vecchia versione di Raspbian, senza supporto di /dev/gpiomem (indicativamente anteriore al 2015)

Per sapere se potete utilizzare la versione aggiornata di questa pagina basta verificare l'esistenza del file:
pi@raspberrypi:~ $ ls -l /dev/gpiomem
crw-rw---- 1 root gpio 244, 0 Mar 6 09:37 /dev/gpiomem

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 al sistema operativo Raspbian.

Accendere un LED

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:

Led connesso a massa

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.

Accendere il LED come root

Per le prime prove occorre essere root. Questa è una cosa assolutamente disdicevole! E' come dire ad un bambino: questa è la lama di un rasoio, vediamo cosa riesci a combinare. Diciamo che è una scorciatoia per cominciare e l'ultima risorsa se proprio le cose con vanno...

Comunque, per diventare root occorre digitare, solo se si è parte del gruppo sudo:

vv@vv-raspberrypi:~$ sudo su
[sudo] password for vv:
root@vv-raspberrypi:/home/vv#

Per tornare utenti "normali":

root@vv-raspberrypi:/home/vv# exit
vv@vv-raspberrypi:~$

In Linux i dispositivi fisici sono visti dagli utenti come file. In particolare siamo interessati a quanto si trova al di sotto di /sys/class/gpio.

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, essendo root:

root@vv-raspberrypi:/home/vv# echo 22 > /sys/class/gpio/export

Questo comando crea una struttura formata da molti file:

root@vv-raspberrypi:/home/vv# ls -l /sys/class/gpio/gpio22/
-rw-r--r-- 1 root root 4096 giu 13 20:31 active_low
-rw-r--r-- 1 root root 4096 giu 13 20:31 direction
-rw-r--r-- 1 root root 4096 giu 13 20:31 edge
drwxr-xr-x 2 root root 0 giu 13 20:31 power
lrwxrwxrwx 1 root root 0 giu 13 20:30 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 giu 13 20:30 uevent
-rw-r--r-- 1 root root 4096 giu 13 20:31 value

Ci interessiamo solo a due di questi due file:

A questo punto siamo in grado di scrivere un mini-script bash capace di far lampeggiare il LED:

#!/bin/bash
echo 22 > /sys/class/gpio/export
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

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.

Quando non serve più utilizzare il pin è cosa buona liberare la risorsa:

root@vvrpi:/home/pi# echo 22 > /sys/class/gpio/unexport

Accendere il LED come utente non privilegiato

Questa soluzione, nettamente migliore, prevede la creazione di un gruppo autorizzato a scrivere (e leggere) i pin GPIO lasciando comunque a root l'incombenza di esportare ogni volta i pin utilizzabili. Chiameremo tale gruppo gpio (ma qualunque altro nome va bene). Tutti e soli gli utenti che appartengono al gruppo gpio potranno usate i pin di GPIO.

L'idea è la seguente:

  1. L'utente root crea l'export del pin e imposta la direzione
  2. Sempre l'utente root assegna la proprietà dei file creati ad un gruppo specifico, con premesso di scrittura
  3. L'utente (che appartiene al gruppo gpio) legge e scrive il pin GPIOx

Vediamo il codice per il primo punto, lo stesso passo appena descritto:

root@vvrpi:/home/pi# echo 22  > /sys/class/gpio/export
root@vvrpi:/home/pi# echo out > /sys/class/gpio/gpio22/direction

Il codice per il secondo punto:

root@vvrpi:/home/pi# chown root:gpio /sys/class/gpio/gpio22/value
root@vvrpi:/home/pi# chmod g+w /sys/class/gpio/gpio22/value

Nota: ovviamente occorre prima aver creato il gruppo gpio e inserito in esso l'utente pi. Se così già non è:

root@vvrpi:/home/pi# addgroup gpio
root@vvrpi:/home/pi# usermod pi -a -G gpio

A questo punto l'utente pi può eseguire il codice che fa lampeggiare il LED, lo stesso codice sopra mostrato (escluse le prime due righe che rimangono compito esclusivo di root).

Un problema deriva dal fatto che le operazioni effettuate da root sono temporanee, fino allo spegnimento della macchina. Questo non è necessariamente un male, anzi... Per rendere semi-permanente l'autorizzazione è comunque possibile, per esempio, inserire nel file /etc/rc.local:

echo 22 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio22/direction
chown root:gpio /sys/class/gpio/gpio22/value
chmod g+w /sys/class/gpio/gpio22/value

Leggere un interruttore

Anche in questo caso il circuito è semplice.

Leggere un interruttore

Per poter leggere lo stato dell'interruttore (aperto/chiuso → 1/0) occorre prima configurare il GPIO17 (pin 11) come ingresso (da root) e quindi leggere il valore.

root@vvrpi:/home/pi# echo 17  > /sys/class/gpio/export
root@vvrpi:/home/pi# echo in > /sys/class/gpio/gpio17/direction
root@vvrpi:/home/pi# chown root:gpio /sys/class/gpio/gpio17/value
root@vvrpi:/home/pi# chmod g+w /sys/class/gpio/gpio17/value

vv@vvrpi ~ $ cat /sys/class/gpio/gpio17/value
1

vv@vvrpi ~ $ cat /sys/class/gpio/gpio17/value
0

E' bene sapere che, all'accensione, tutti i pin sono 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/gpio17/value`
echo $SW > /sys/class/gpio/gpio22/value
done

Le prestazioni

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.

Lampeggio del LED controllato da bash: lento e con jiitte!

Ultima modifica di questa pagina, limitatamente alle prime righe: 5 marzo 2016


Raspberry Pi - Note di hardware

Vedi anche: Il taccuino tecnico


Licenza "Creative Commons" - Attribuzione-Condividi allo stesso modo 3.0 Unported


EN - Pagina principale - Sommario - Accessibilità - Note legali e privacy policy - Posta elettronica

XHTML 1.0 Strict - CSS 3