LED e interruttori con bash

Un LED collegato al RaspBerry Pi

Attenzione

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)

Accendere un LED

Lo schema elettrico

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.

Operazioni preliminari

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

Creazione dell'interfaccia

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

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 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

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!

Note

  1. Per utilizzare questa pagina è necessario utilizzare una versione recente di Raspbian con supporto di gpiomem. Per verificare:
    pi@raspberry:~ $ ls -l /dev/gpiomem
    crw-rw---- 1 root gpio 244, 0 Mar 6 08:59 /dev/gpiomem

Prima di creazione di questa pagina: luglio 2013
Ultima modifica: 5 marzo 2016


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


Pagina principaleAccessibilitàNote legaliPosta elettronicaXHTML 1.0 StrictCSS 3

Vai in cima