Raspberry Pi — SBC e GPIO con Python

📋 Obiettivi di apprendimento
Distinguere un SBC (Raspberry Pi) da un microcontrollore (Arduino) in termini di architettura, sistema operativo e capacità
Descrivere i componenti hardware di Raspberry Pi: SoC, GPIO, interfacce di comunicazione (I²C, SPI, UART) e mancanza dell’ADC
Scrivere script Python per controllare i GPIO: accendere LED, leggere pulsanti e usare la libreria RPi.GPIO
Scegliere tra Arduino e Raspberry Pi per un dato scenario applicativo motivando la scelta
📄
Slides
Raspberry Pi — hardware, GPIO e Python

Un computer intero in 85 × 56 mm

Se Arduino è un microcontrollore — un singolo chip ottimizzato per eseguire un programma in tempo reale — Raspberry Pi è qualcosa di completamente diverso: un computer completo racchiuso in una scheda delle dimensioni di una carta di credito. Ha un processore multi-core, centinaia di MB di RAM, supporta un sistema operativo Linux, esegue qualsiasi applicazione Python, C, Java o Node.js, e si connette a monitor, tastiera, rete Wi-Fi e dispositivi fisici tramite i pin GPIO.

Raspberry Pi nasce nel 2012 come progetto della Raspberry Pi Foundation, un’organizzazione no-profit britannica, con l’obiettivo di rendere accessibile l’informatica alle scuole. Il prezzo di partenza — 35 dollari — ha aperto un mercato enorme di maker, hobbisti, ricercatori e industria.

SBC vs Microcontrollore — la distinzione fondamentale

⚡ Arduino — Microcontrollore
[Sketch (unico programma)]
[ATmega328P — MCU]
[Hardware diretto]
✅ Avvio istantaneo (sub-millisecondo)
✅ Deterministico — risponde in tempi precisi
✅ Basso consumo (50–250 mW)
✅ ADC integrato per segnali analogici
❌ Nessun sistema operativo
❌ Un solo programma alla volta
❌ Limitata potenza di calcolo
🐧 Raspberry Pi — SBC (Single Board Computer)
[App Python / Web server / AI model…]
[Raspberry Pi OS (Linux)]
[BCM2837 — SoC ARM Cortex-A]
✅ Sistema operativo Linux completo
✅ Multitasking — decine di processi simultanei
✅ Wi-Fi, Ethernet, USB, HDMI nativi
✅ Ecosistema software enorme (Python, OpenCV, TensorFlow…)
❌ Avvio lento (15–30 secondi)
❌ Nessun ADC — richiede chip esterno per segnali analogici
❌ Consumo maggiore (2–7 W)

Hardware — Raspberry Pi nel dettaglio

Il SoC — System on Chip

Il cuore di Raspberry Pi è il SoC (System on Chip) Broadcom — un singolo chip che integra tutto: CPU multi-core ARM, GPU per grafica e calcolo, memoria RAM e controller per le interfacce. A differenza dell’ATmega328P di Arduino (8 bit, 16 MHz), il SoC di un Raspberry Pi 4 ha 4 core ARM Cortex-A72 a 1,5 GHz — paragonabile a un laptop low-end.

ModelloCPURAMConnettivitàUso tipico
Pi Zero 2W4-core ARM, 1 GHz512 MBWi-Fi, BTIoT embedded, wearable
Pi 3B+4-core ARM, 1.4 GHz1 GBWi-Fi, BT, EthernetMedia center, laboratori
Pi 4B4-core ARM, 1.8 GHz1–8 GBWi-Fi, BT, 2×USB3, GbEAI, computer vision, server
Pi PicoDual-core ARM M0+, 133 MHz264 KBUSB (no Wi-Fi)Simile ad Arduino, MicroPython
Il Raspberry Pi Pico è un’eccezione nella famiglia: è un microcontrollore (come Arduino) che si programma in MicroPython, senza sistema operativo Linux.

I GPIO — 40 pin programmabili

Il GPIO (General Purpose Input/Output) è l’interfaccia fisica di Raspberry Pi con il mondo esterno. Il connettore da 40 pin include tensioni di alimentazione, massa e pin digitali programmabili. A differenza di Arduino, tutti i pin GPIO operano a 3.3V — non 5V. Collegare un segnale a 5V ai GPIO può danneggiare permanentemente il SoC.

⚠️ ATTENZIONE — I GPIO di Raspberry Pi sono a 3.3V, non 5V

Se colleghi un segnale a 5V (es. proveniente da Arduino o da un sensore con logica 5V) direttamente a un pin GPIO, rischi di bruciare il chip BCM irrimediabilmente. Usa sempre un divisore di tensione o un level shifter per adattare i livelli logici.

I 40 pin GPIO — organizzazione
2 pin 5V (alimentazione esterna)
2 pin 3.3V (alimentazione logica)
8 pin GND (massa)
26 pin GPIO generici (digitali 3.3V)
I²C (SDA=GPIO2, SCL=GPIO3)
SPI (MOSI, MISO, SCLK, CE0, CE1)
UART (TX=GPIO14, RX=GPIO15)

I protocolli di comunicazione seriale

I²C — Inter-Integrated Circuit

Solo 2 fili: SDA (dati) e SCL (clock). Più dispositivi possono condividere gli stessi 2 pin — ognuno ha un indirizzo unico (es. 0x68 per MPU-6050). Velocità: 100–400 kHz.

Uso: sensori (BMP280, DHT12, LCD), display OLED
SPI — Serial Peripheral Interface

4 fili: MOSI, MISO, SCLK, CS. Full-duplex — invia e riceve simultaneamente. Più veloce di I²C (fino a MHz). Ogni dispositivo richiede un CS dedicato.

Uso: display TFT, ADC esterno, schede SD, NFC
UART — Comunicazione seriale

2 fili: TX e RX. Trasmissione asincrona — entrambi i lati devono usare la stessa velocità (baud rate). Usato per comunicare con Arduino, GPS, modem GSM.

Uso: debug console, GPS NEO-6M, Arduino ↔ RPi

Il limite critico — nessun ADC

⚠️ Raspberry Pi non ha ingressi analogici

A differenza di Arduino (che ha 6 pin analogici con ADC 10 bit), Raspberry Pi ha solo GPIO digitali. Non può leggere direttamente un potenziometro, una fotoresistenza LDR o qualsiasi sensore con uscita analogica.

Soluzione: si usa un ADC esterno collegato via SPI o I²C. Il più comune è il MCP3008 — ADC a 8 canali a 10 bit, comunica via SPI. Con una libreria Python si legge esattamente come farebbe Arduino.

Programmazione GPIO con Python

Python è il linguaggio standard per programmare Raspberry Pi. La libreria RPi.GPIO (preinstallata in Raspberry Pi OS) permette di leggere e scrivere sui pin GPIO con poche righe di codice. Più moderna e consigliata per i nuovi progetti è gpiozero — un’astrazione di alto livello che semplifica ulteriormente il codice.

Concetti fondamentali — RPi.GPIO

Le due modalità di numerazione dei pin
import RPi.GPIO as GPIO

# BOARD: numerazione fisica del connettore (pin 1, 2, 3...40)
GPIO.setmode(GPIO.BOARD)

# BCM: numerazione logica del chip BCM (GPIO17, GPIO27...)
# BCM è la più usata nei tutorial — corrisponde alle etichette del pinout
GPIO.setmode(GPIO.BCM)

Esempio 1 — LED blink

# Schema: LED → [330Ω] → GPIO18 — Catodo LED → GND
# (3.3V max! Usare resistenza da 330Ω, non 220Ω come con Arduino)

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)       # usa numerazione BCM
GPIO.setup(18, GPIO.OUT)     # GPIO18 come uscita

try:
    while True:
        GPIO.output(18, GPIO.HIGH)  # LED acceso → 3.3V
        time.sleep(1)
        GPIO.output(18, GPIO.LOW)   # LED spento → 0V
        time.sleep(1)

except KeyboardInterrupt:
    pass                          # Ctrl+C per uscire

finally:
    GPIO.cleanup()               # SEMPRE: rilascia i pin alla fine
Nota critica: il blocco try/finally con GPIO.cleanup() è fondamentale — resetta i pin in stato sicuro all’uscita del programma, evitando che rimangano in uno stato indefinito.

Esempio 2 — Lettura pulsante con pull-up interno

# Pulsante: un terminale → GPIO23, altro → GND
# PUD_UP: resistenza di pullup interna → 3.3V quando il pulsante è aperto

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)                      # LED
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # pulsante con pullup

try:
    while True:
        stato = GPIO.input(23)      # legge il pin
        if stato == GPIO.LOW:       # LOW = pulsante premuto (pullup)
            GPIO.output(18, GPIO.HIGH)
            print("Pulsante premuto — LED acceso")
        else:
            GPIO.output(18, GPIO.LOW)
        time.sleep(0.05)           # 50 ms polling

except KeyboardInterrupt:
    pass
finally:
    GPIO.cleanup()

Esempio 3 — Lettura DHT11 (temperatura e umidità)

# Installazione: pip install adafruit-circuitpython-dht
# Schema: DHT11 pin dati → GPIO4 (con resistenza 10kΩ pullup a 3.3V)

import adafruit_dht
import board
import time

sensore = adafruit_dht.DHT11(board.D4)   # sensore su GPIO4

while True:
    try:
        temperatura = sensore.temperature
        umidita = sensore.humidity
        print(f"Temperatura: {temperatura}°C  Umidità: {umidita}%")
    except RuntimeError as e:
        # Il DHT11 può fallire una lettura su 10 — è normale
        print(f"Lettura fallita: {e} — riprovo...")
    time.sleep(2)                          # DHT11: max 1 lettura ogni 2 sec

gpiozero — la libreria moderna e semplificata

gpiozero — stesso risultato, codice più leggibile
from gpiozero import LED, Button
from signal import pause

led = LED(18)
button = Button(23)

# Associa automaticamente il pulsante al LED
button.when_pressed = led.on
button.when_released = led.off

# Mantieni il programma in esecuzione
pause()
gpiozero gestisce automaticamente il cleanup, i pullup e gli eventi. Il codice è più leggibile e meno soggetto a errori.

Arduino vs Raspberry Pi — come scegliere

Guida alla scelta — scenario per scenario
Scenario
Arduino ✅
Raspberry Pi ✅
Lettura sensori analogici (LDR, NTC, potenziometro)
✅ ADC integrato
❌ Serve ADC esterno
Risposta in tempo reale (<1ms, controllo PID veloce)
✅ Deterministico
⚠️ OS introduce jitter
Server web, database, API REST
❌ Troppo limitato
✅ Flask/Django nativo
Computer vision (OpenCV, riconoscimento oggetti)
❌ RAM/CPU insufficienti
✅ OpenCV, TensorFlow Lite
Alimentazione a batteria, anni di autonomia
✅ 50–250 mW
❌ 2–7 W
Progetto IoT complesso (sensori + Wi-Fi + cloud + display)
⚠️ Con shield aggiuntivi
✅ Tutto integrato
📌 La scelta non è esclusiva — Arduino e Raspberry Pi si usano insieme

Molti progetti professionali usano entrambi: Arduino come front-end per il controllo in tempo reale di sensori e attuatori (lettura analogica, PWM preciso, timing critico), connesso via UART a Raspberry Pi che gestisce il backend (elaborazione complessa, interfaccia web, connessione cloud, machine learning). Arduino fa il lavoro sporco vicino al hardware, Raspberry Pi fa il lavoro intelligente nel software.

📌 Riepilogo — Punti chiave
  • Raspberry Pi è un SBC — ha un OS Linux completo, CPU multi-core, RAM, USB, HDMI, Wi-Fi. Arduino è un microcontrollore — esegue un solo sketch in loop, senza OS, ma con risposta deterministica in microsecondi
  • I GPIO operano a 3.3V (non 5V come Arduino). Raspberry Pi non ha ADC — per leggere segnali analogici serve un chip esterno (es. MCP3008 via SPI)
  • I protocolli di comunicazione: I²C (2 fili, multi-device, fino a 400 kHz), SPI (4 fili, full-duplex, veloce, un CS per device), UART (2 fili, asincrono, comunicazione seriale punto-punto)
  • Programmazione GPIO in Python: GPIO.setmode(BCM)GPIO.setup(pin, OUT/IN)GPIO.output()/GPIO.input()GPIO.cleanup() nel blocco finally. La libreria gpiozero semplifica ulteriormente il codice
  • Scegli Arduino per: sensori analogici, timing preciso, basso consumo, semplicità. Scegli Raspberry Pi per: web server, computer vision, machine learning, interfaccia utente. Spesso si usano insieme nello stesso progetto

Lascia un commento