La porta GPIO della Raspberry Pi – Seconda parte

Di - 27 November 2013 - in
Post image for La porta GPIO della Raspberry Pi – Seconda parte

Nello scorso articolo abbiamo visto il funzionamento delle porte GPIO della Raspberry Pi a basso livello, scoprendo come possiamo utilizzarle per l’ingresso o l’output di informazioni sia da Python che dalla shell.

In questa seconda parte vedremo invece le principali funzionalità di alto livello che sono implementate su alcune di queste porte, e che possono essere utilizzate per interfacciarsi con dispositivi complessi esterni, come ad esempio i sensori.

1-Wire

Iniziamo con un’interfaccia che non è tra le principali (e non è solitamente fatta notare), ma è molto utile per l’utilizzo di sensori: l’interfaccia 1-Wire. Le principali distribuzioni Linux per Raspberry Pi, come Raspbian, hanno un driver per 1-Wire, che utilizza il pin numero 7 (CLK0/GPIO4).

Si tratta di un’interfaccia di comunicazione seriale che ha la caratteristica di far passare i dati su un solo filo, occupando così un singolo pin di comunicazione. Si possono collegare senza problemi in parallelo più dispositivi assieme ad un singolo resistore di pull-up comune a tutti.

L’uso più comune che si fa di questi dispositivi è il collegamento di sensori ambientali, come termometri, barometri o igrometri, ed esistono circuiti integrati che contengono al loro interno già in serie un gruppo di sensori ambientali, in modo da poter ottenere le diverse informazioni da un singolo package.

Un sensore 1-Wire ha tre piedini, e somiglia spesso ad un comune transistor. Uno dei piedini è per l’alimentazione (ricordiamo che l’elettronica della Raspberry Pi è a 3.3Volt), uno per la trasmissione dei dati e uno per la messa a terra. La connessione del sensore è dunque banale: il primo piedino si collega ad uno dei pin di alimentazione, il secondo al pin 7 e il terzo ad un pin di terra. Tra i primi due pin va inserito il resistore di pull-up. Ecco un esempio con il sensore di temperatura DS18B20, che io stesso utilizzo:

Per attivare il driver 1-Wire va caricato il modulo w1-gpio e l’eventuale driver relativo al tipo di dispositivo (w1-therm per i sensori di temperatura e simili, vi sono altri driver soprattutto per dispositivi di memoria RAM o ROM):

sudo modprobe w1-gpio
sudo modprobe w1-therm

Al solito, se volete che i moduli vengano caricati all’avvio in automatico, date i comandi:

sudo echo w1-gpio >> /etc/modules
sudo echo w1-therm >> /etc/modules

A questo punto troverete una directory in /sys/bus/w1/devices per ogni dispositivo collegato. All’interno della directory, si trovano diversi file che indicano (e permettono di modificare) lo stato del dispositivo. Nel caso del sensore di temperatura in questione, la directory inizia con 28- (ad esempio 28-00000474dd9b) e contiene un file w1_slave con lo stato del sensore e la sua lettura. Il risultato di cat /sys/bus/w1/devices/28-00000474dd9b/w1_slave sarà:

3c 01 4b 46 7f ff 04 10 40 : crc=40 YES
3c 01 4b 46 7f ff 04 10 40 t=19750

ovvero una lettura andata a buon fine (OK) con risultato 19,75°C (19750). Con un minimo di fantasia è facile immaginare programmi che automatizzino la lettura e facciano ad esempio logging dei risultati nel tempo.

I2C

Protocollo simile ad 1-Wire, ma più complesso e più veloce (anche se si tratta comunque di un sistema piuttosto lento), I2C consente di collegare alla Raspberry Pi dispositivi che supportino tale protocollo, in modo da creare letteralmente una rete di circuiti integrati. Fa uso dei pin 3 e 5, il primo usato per la comunicazione (SCL) e il secondo per il clock (CLK). Si tratta infatti di un protocollo sincrono, che necessita dunque di un segnale di sincronizzazione. Un circuito I2C avrà anche un piedino per l’alimentazione ed uno per la terra, analogamente a 1-Wire, e sarà necessario mettere una resistenza di pull-up comune a tutti i circuiti collegati tra l’alimentazione e ognuna delle due linee SCL e CLK.

Ogni dispositivo connesso I2C (se ne possono collegare fino a 112) avrà anche alcuni pin per impostare il suo indirizzo attraverso dei jumper.

È impossibile trattare per bene come funzioni l’accesso ad un dispositivo I2C, in quanto ne esistono di diversissimi tra loro. Qualsiasi tipo di circuito integrato può essere realizzato in modo da supportare I2C, e la fantasia non è certo mancata. Uno degli utilizzi più diffusi è probabilmente quello dei GPIO expander, degli integrati che contengono ulteriori porte GPIO per aumentare le possibilità della Raspberry Pi, ma sono diffusi anche display LCD, display a segmenti, memorie, e persino microcontroller per servomotori. In generale, sarà necessario caricare i moduli del kernel opportuni:

sudo modprobe i2c-bcm2708
sudo modprobe i2c-dev

che attivano il protocollo e creano i file di periferica dei dispositivi connessi, ma il resto dipende moltissimo da quale sia il dispositivo in questione. Probabilmente è il protocollo più potente e utile presente sulla Raspberry Pi per chi vuole utilizzarne hardware elettronico in maniera fantasiosa.

SPI

L’altro bus per i progetti più fantasiosi è il bus SPI. Anche in questo caso si tratta di un sistema di comunicazione tra circuiti, ma stavolta i pin utilizzati sono cinque, e si tratta di un sistema full-duplex, ovvero di un sistema che permette la comunicazione contemporanea in entrambi i sensi. Abbiamo un pin di clock (SCLK), uno di input (MOSI), uno di output (MISO) e due pin CE che servono ad indicare chi è il master nella rete e chi lo slave.

L’utilizzo più comune di quest’interfaccia è il collegamento di microcontrollori e convertitori analogico-digitale o digitale-analogico. In pratica l’SPI è l’interfaccia tra il mondo digitale della Raspberry Pi e quello analogico di moltissimi sensori, servomotori e dispositivi vari.

Esistono diverse librerie per l’uso di questa interfaccia, per la quale va al solito caricato il relativo modulo del kernel:

sudo modprobe spi-bcm2708

Una libreria Python per l’utilizzo di SPI è py-spidev. che va installato scaricando il file .c e quello .py, per poi eseguire il secondo da amministratore.

Un esempio di utilizzo lo si può avere collegando un ADC TLC549, che si occupa di convertire segnali analogici in digitale, al quale colleghiamo un potenziometro così da variare il suo segnale di ingresso:

In python scriviamo:

import spidev
import time

spi = spidev.SpiDev()
spi.open(0,0)
while True:
    resp = spi.xfer2([0x00])
    print resp[0]
    time.sleep(1)

Le prime righe importano le librerie necessarie. Poi viene creato un nuovo oggetto per accedere ad spi, e si apre una connessione sul bus 0, CE0. Nel ciclo, poi, ogni secondo, si invia un bit 0 al dispositivo e si legge la risposta, per poi stamparne il primo bit a schermo. La risposta varierà agendo sul potenziometro.

A seconda delle applicazioni, l’uso sarà molto diverso.

PWM

Il pin 12 è utilizzabile per il PWM via hardware. Il PWM (pulse width modulation), diversamente dalle cose viste finora, non è un protocollo. Si tratta di un sistema per inviare impulsi su un pin, ovvero fargli eseguire sequenze prestabilite di acceso/spento.

La Raspberry Pi può erogare sui pin esclusivamente 0 o 3.3Volt, essendo la GPIO un’interfaccia digitale. Questo può essere molto scomodo se volessimo fare cose che richiedano una variazione della tensione. Ad esempio, se abbiamo un LED al quale vogliamo cambiare il livello di luminosità, il modo più ovvio per farlo è aumentare o diminuire la tensione. Allo stesso modo, se abbiamo un motore e vogliamo accelerarlo o rallentarlo, dovremo lavorare sulla tensione.

Esiste un modo alternativo per ottenere un risultato simile. Se vogliamo che un LED abbia una luminosità che sia la metà di quella normale, invece di abbassare la tensione possiamo dargli una sequenza di acceso e spento a frequenza abbastanza alta da non essere percepibile, con periodi di durata dell’acceso e dello spento equivalenti. Il LED sarà dunque acceso per la metà del tempo, apparendo meno luminoso. Lo stesso avviane con un motore. Variando la lunghezza del tempo di accensione rispetto a quello di spegnimento, si ottiene l’effetto di aumentare o diminuire la luminosità del LED o la velocità del motore.

Si tratta di un modo molto scomodo e impreciso di fare le cose, ma è più che sufficiente per molti tipi di utilizzo (LED, ventole di raffreddamento…), ed è quanto di meglio si possa fare senza ricorrere a microcontrollori esterni.

Non conosco librerie di accesso comode per il pin PWM, ed il motivo è che esistono librerie che emulano il PWM via software, come la RPi.GPIO presentata nel primo articolo, su un qualunque pin GPIO. Si tratta di cose meno affidabili del sistema hardware integrato, non basandosi su un sistema operativo realtime, ma sono più semplici da utilizzare. Per le cose che richiedono grande precisione è sempre meglio utilizzare un microcontrollore realtime.

Un’ultima nota a riguardo: se dovete collegare motori alla GPIO, fate molta attenzione a cosa state facendo: richiedono quasi sempre correnti più alte di quelle che la Raspberry Pi sopporta, e richiedono quindi di solito un transistor che regoli il tutto. Inoltre, è bene mettere un diodo tra i due poli del motore, per evitare che il collasso del campo magnetico allo spegnimento dello stesso generi correnti inverse molto pericolose per la delicata porta GPIO. Precauzioni di questo genere vanno prese ogni volta che si colleghi qualcosa di pensato per essere elettrico a qualcosa di pensato per essere elettronico.

UART

L’interfaccia UART è una coppia di pin, uno per la ricezione (10) e uno per la trasmissione (8), per la comunicazione asincrona. Si tratta in sostanza della classica porta di comunicazione seriale, e permette dunque di collegare un PC ad una Raspberry ad esempio per il controllo remoto, grazie ad un adattatore da USB a seriale. In questo modo si potrà ottenere un terminale remoto attraverso uno dei moltissimi tool per terminali seriali su Linux o Mac, o attraverso PuTTY su Windows.

Il baud rate da impostare è 115200, 8 bit, parità: no, stop bit 1, controllo del flusso: no.

Essendo questa interfaccia accesa di default all’avvio, si tratta di una soluzione di emergenza se non si hanno a disposizione mouse e tastiera e non si riesce ad accedere alla Raspberry Pi in nessun altro modo, soprattutto sul modello sprovvisto di interfaccia di rete.

CLK

Abbiamo aperto col pin 4, e concludiamo con lo stesso pin. Il pin 4, infatti, può essere usato per produrre una frequenza di clock per i più svariati scopi. Per farlo, si può utilizzare la libreria RPi.GPIO presentata nel primo articolo, attraverso il comando setclock, che prende in ingresso il numero di pin (che deve essere 4) e la frequenza in Hz (che deve essere tra 4640 e 19000000). Il pin va poi acceso con il comando output, come se si dovesse impostare ad “acceso”.

Buon divertimento!

Via | Adafruit Learning System | 100RandomTask

Leave a Reply

Lorenzo Breda Articolo scritto da

Studente di Informatica a Roma, si occupa di programmazione web sopratutto lato server, e di accessibilità del web. Utilizza e ama Debian GNU/Linux, e si interessa di fisica, fumetto, trekking e fotografia (gli ultimi due possibilmente abbinati). Collabora con Googlab da aprile 2012.

Contatta l'autore

Previous post:

Next post: