GPIO è l’acronimo di “General Purpuse Input Output” pin.
In una scheda controllata da un Microcontrollore, tutti i pin che sono identificati con il temine “GPIO” sono configurabili con diversi ruoli a seconda di come vengono configurati nel software.
L’uso principale e più comune, è quello di “pin discreto”, ovvero in grado di essere configurato come INPUT o OUTPUT e di poter gestire segnali digitali con valori di tensione 0 / V(*), dove (V) è la tensione di operatività della scheda (generalmente 3.3v o 5v).
Altri impieghi degli stessi pin, laddove le caratteristiche della scheda lo permette, potrebbero essere:
- Ingresso ADC (lettura di un valore di tensione analogico)
- Uscita DAC (generazione di un valore di tensione)
- PWM (Pulse With Modulation)
- Bus digitali vari (Serial, I2C, SPI, ecc…)
In questo articolo prenderemo in considerazione solamente la modalità digitale per la gestione di segnali discreti.
A cosa servono i segnali discreti
Un GPIO (1-bit) usato come “pin discreto” è in grado di gestire solamente valori di tensione 0 o V(*) e mai valori intermedi.
Un GPIO (1-bit), configurato come OUTPUT, potrebbe essere usato, per esempio, per il controllo dell’accensione di un LED, oppure per controllare un BUZZER e farlo suonare con diverse tonalità. Un altro esempio pratico potrebbe essere il controllo di un relè che a sua volta controlla l’interruzione di corrente ad un altro dispositivo che richiede più energia (es. una serratura elettromagnetica o una comune lampadina). Sotto il punto di vista elettronico, si deve fare particolare attenzione affinché il pin di OUTPUT non eroghi una corrente superiore a quella specificata nel datasheet del microcontrollore, pena il danneggiamento permanente dello stesso.

Figura 1 – Rappresentazione di un segnale digitale emesso da un GPIO configurato come OUTPUT.
Quando configuriamo un GPIO come “OUTPUT” ed impostiamo il suo stato come ‘0’ logico (LOW), la tensione presente sul quel pin è prossima a “zero” Volt. Invece quando lo impostiamo come “1” logico (HIGH), la tensione presente sul pin è prossima al valore di tensione di lavoro del microcontrollore, generalmente 5 volt (per Arduino Uno) oppure 3.3 volt per gli altri modelli (esempio: Arduino MKR1000).
Come si configura e si controlla un GPIO
In ambiente Arduino, ci sono tre funzioni fondamentali che permettono la configurazione e il controllo dei GPIO:
pinMode() è la funzione che permette di far “cambiare stato” al pin GPIO.
Le possibili scelte sono:
– OUTPUT il GPIO viene configurato come “uscita”, quindi possiamo controllare il suo stato 0/1 logico tramite la funzione digitalWrite().
– INPUT il GPIO viene configurato come “ingresso”, quindi potremmo leggere il suo stato logico 0/1 attualmente presente in ingresso sul pin (esempio: potremmo sapere se un tasto è premuto o no).
– INPUT_PULLUP viene configurato come “ingresso” con le stesse funzionalità di INPUT, ma con l’aggiunta di attivare una resistenza interna al microcontrollore, collegata tra il pin e il positivo di alimentazione che eleva la tensione sul pin GPIO (pull_up) permettendo un valore stabile e fisso nel caso in cui non sia collegato a nulla (floating).
Questa funzionalità è utile per non creare situazioni di “incertezza” che possano creare dei falsi risultati 0/1 logico nel momento della lettura del GPIO. Infatti quando un pin GPIO non è collegato a nulla (floating), è in uno stato indefinito, situazione sempre da evitare nei circuiti logici.
La funzione pinMode( par1, par2 ) accetta due parametri, il (par1) è il numero del pin GPIO che desideriamo configurare. Questo può essere direttamente il numero del pin, oppure un ‘Alias’ come ad esempio “A0” oppure un altro nome precedentemente definito con la direttiva #define.
Il parametro (par2), può essere una delle tre possibilità spiegate prima, ovvero come vogliamo che il pin venga configurato.
Vediamo qualche esempio:
// Il pin 13 diventa un OUTPUT pinMode( 13, OUTPUT );
oppure in caso di utilizzo della direttiva #define:
// Imposto la direttiva "LED = 13' #define LED 13 // La parola "LED" viene sostituita con '13' dal compilatore pinMode( LED, OUTPUT );
in questo altro esempio, configuriamo il pin A0 come OUTPUT:
pinMode( A0, OUTPUT );
digitalWrite( par1, par2 ) è la funzione che permette di controllare lo stato del GPIO quando è impostato come OUTPUT.
Anche questa funzione deve essere utilizzata con due parametri: (par1) è il numero del pin GPIO, da usare in modo identico a come abbiamo già visto con pinMode(). Invece il parametro (par2) è lo stato che vogliamo impostare: con ‘HIGH‘ impostiamo un valore “1” logico, mentre con ‘LOW‘ impostiamo un valore ‘0’ logico.
Vediamo qualche esempio:
L’esempio che segue, imposta prima il GPIO 13 come uscita (OUTPUT), poi lo imposta a valore logico ‘1’ o “HIGH”. Questa operazione risulta nell’avere 5 volt presenti sul pin 13 di Arduino Uno.
pinMode( 13, OUTPUT ); digitalWrite( 13, HIGH);
digitalRead( par1 ) è la funzione che ci permette di poter leggere lo stato di un pin GPIO precedentemente configurato come ingresso digitale (INPUT). La funzione restituisce un valore 0/1 in funzione del valore di tensione presente sul pin GPIO al momento dell’esecuzione.
Come già detto, prima di usare questa funzione, il pin deve essere pre-configurato con una delle possibili modalità di INPUT disponibili per pinMode().
Qualche esempio:
Nell’esempio che segue, il pin GPIO (4) viene configurato come INPUT, poi una variabile ‘a’ viene dichiarata come ‘int’ e acquisisce il valore 0/1 restituito dalla funzione digitalRead() per il pin (4).
pinMode( 4, INPUT ); int a = digitalRead( 4 );
Il codice che segue, in termini di funzionalità, è identico al precedente.
La differenza sta nel fatto che è più leggibile e più semplice da manutenere:
-Il pin GPIO (4) è definito in precedenza con la direttiva #define e viene chiamato ‘BUTTON’
-la variabile ‘a’ viene dichiarata prima dell’uso.
#define BUTTON 4 int a; pinMode( BUTTON, OUTPUT ); a = digitalRead( BUTTON );
La variabile ‘a’ verrà riempita con il valore 0/1 in funzione della presenza di tensione (0 – 5v) sul pin PIO (4).
Per sperimentare in modo pratico l’uso delle funzioni e dei GPIO, leggete tutto l’articolo con gli esercizi proposti.
Dove sono i GPIO sulla scheda Arduino ?
Nel caso di Arduino UNO Rev.3, i pin GPIO sono collegati direttamente al microcontrollore ATMEGA328P (datasheet). Stessa cosa anche per Arduino UNO R4 equipaggiato con chip Renesas RA4. I pin GPIO digitali sono quelli riportati nella figura seguente. E’ importante sapere che ciascun GPIO è in grado di erogare una quantità di corrente limitata che non deve mai essere superata. Questo valore è riportato normalmente nel datasheet del microcontrollore, ma anche nella pagina web della scheda, il cui valore riportato, nella sezione “Tech specs”, è di Max 20 mA per pin.
Invece per Arduino UNO R4, questo valore è di 8 mA.


Anche i pin analogici (A0 ÷ A5) possono essere configurati come pin digitali. Infatti utilizzando pinMode(), digitalWrite() e digitalRead() su questi pin, possiamo sfruttarli allo stesso modo dei classici pin digitali D0 ÷ D13.
Esempio pratico 1: colleghiamo un LED
L’esempio più semplice ed immediato è il collegamento di un piccolo LED (rosso) da 3mm su di un GPIO di Arduino. La sua resistenza di protezione (fondamentale per non danneggiare il LED) è generalmente del valore di 220Ω considerando che un LED rosso deve essere alimentato tra una tensione compresa tra 1.8v e 2.2v, e la corrente che scorre al suo interno è di circa 10-20 mA.

Figura 2 – Un led controllato da un GPIO di Arduino Uno.
Calcolare il valore della resistenza (nel disegno R3) è molto semplice:
Considerando che la tensione di uscita del GPIO in questione è 5v, la tensione di lavoro del LED è 2v circa e la corrente di operatività del LED è di circa 15mA (0.015A), la resistenza la calcoliamo secondo la legge di OHM:
RLed = 5.0 – 2.0 / 0,015 = 200Ω
che approssimiamo al valore commerciale di 220Ω.
Nello standard di valori di resistenze (serie E12) con una tolleranza del 5% sul valore, corrisponde a:
ROSSO (2)- ROSSO (2)- MARRONE (x10)- ORO (5%) = 220Ω valore – 5% tolleranza
Come faccio ad accendere il Led
A questo punto, come faccio ad accendere il Led?
Ora dobbiamo dare sufficienti istruzioni al codice Arduino al fine di accendere il Led.
Come abbiamo già detto, in ambiente Arduino, il controllo dei pin GPIO si fa tramite due funzioni dedicate: pinMode(), digitalWrite() e digitalRead().
Nel caso dell’esempio che segue, useremo solo pinMode() e digitalWrite(), in quanto useremo il GPIO (13) solo come USCITA (OUTPUT).
L’esercizio è il classico ‘blink’, ovvero un codice di esempio che fa lampeggiare un LED.
Dopo aver collegato un LED come in figura 2, useremo pinMode() solo nella funzione setup(). Questo perché l’impostazione del GPIO è necessario farlo una sola volta e non ripetutamente.
#define LED 13
setup() {
pinMode( LED, OUTPUT );
}
Invece nella funzione loop() useremo digitalWrite() più volte per accendere e spegnere il LED, modificando ogni volta lo stato logico del pin GPIO:
loop() {
digitalWrite( LED, HIGH );
delay(200);
digitalWrite( LED, LOW );
delay(200);
}
la funzione delay() è necessaria per rallentare l’esecuzione del programma e vedere l’effetto ‘lampeggio’ del LED. Il valore 200 indica il numero di milliSecondi di ‘pausa’ prima di eseguire l’istruzione successiva.
Discorso diverso invece se si vuole controllare un carico più impegnativo in termini di corrente richiesta. Per fare un esempio, una bobina di un relè non sarebbe controllabile se collegata direttamente ad un pin GPIO di Arduino perché richiederebbe troppa corrente per essere eccitata. In questo caso dovremmo utilizzare un transistor NPN o MOSFET per controllare la bobina del relè. Nell’esempio della figura 2, un transistor NPN è controllato e mandato in stato di saturazione attraverso la corrente erogata dal GPIO e che scorre sulla base (B). In questo caso la corrente che scorre nella resistenza (R1) è calcolabile, con una certa approssimazione, con la seguente formula:
I(R1) = vGPIO – 0,7 / R1 -> 5.0 – 0.7 / 10.000 = 0,43 mA
Dove 0,7 è la caduta di tensione della giunzione B-E del transistor NPN, e la corrente che scorre in R2, nel calcolo è trascurata. La resistenza R2 ha lo scopo di mantenere la base del transistor ad un valore di tensione basso durante i cambi di stato (input/output) del GPIO e durante gli stati di RESET.

Figura 2 – Esempio di controllo di un relè dal un pin di Arduino impostato come OUTPUT.
Esempio pratico 2: Leggere lo stato di un pulsante
Questa volta useremo il GPIO configurato come INPUT e collegheremo ad esso un tasto, il quale, ad ogni pressione, modifica il livello di tensione presente sul pin.
Nelle immagini che seguono, è raffigurato un tipico circuito di collegamento di un pulsante su di un GPIO digitale (il GPIO 7 nell’esempio). In condizione di riposo, il pulsante è un circuito aperto, quindi la tensione nel punto del GPIO (7) è pari alla tensione VCC (5 volt), che è veicolata attraverso la resistenza da 10k ohm. Quindi in condizioni di riposo, il livello “logico” all’ingresso del GPIO (7) è pari a “1”. Quando il tasto viene premuto, la tensione presente nel punto del GPIO (7) è pari a ZERO volt, perché il tasto mette in corto-circuito il punto GPIO (7) con il pin GND (ground). In questa condizione il livello “logico” del GPIO (7) è pari a “0”.

Figura 3: Schema elettrico del collegamento del tasto

Figura 4: Schema circuitale del collegamento del tasto
Dal punto di vista del software, questa volta dovremmo configurare il GPIO come INPUT:
pinMode( 7, INPUT );
…e poi leggere lo stato logico del GPIO riportandolo in una variabile numerica:
int a = digitalRead( 7 );
A questo punto il contenuto della variabile è possibile stamparla nel monitor seriale o utilizzarla per far un’altra azione.
Nell’esempio (completo) che segue, viene eseguita la lettura continua del GPIO (7) e stampato il suo livello logico nel monitor seriale:
#define BUTTON 7
void setup() {
pinMode( BUTTON, INPUT );
Serial.begin(9600);
}
void loop() {
int a;
a = digitalRead( BUTTON );
Serial.print("GPIO:");
Serial.println( a );
delay(200);
}
Di seguito il suo output: quanto il tasto è rilasciato, il livello logico è “1”, quando viene premuto, il livello logico è “0”.

Figura 5: Output sul monitor seriale dell’esempio 2.
Esempio pratico 3: Usiamo il tasto con il LED
In questo ultimo esempio, usiamo contemporaneamente le due funzioni di GPIO, sia come OUTPUT che come INPUT. Rispetto all’esempio precedente, la parte del tasto è invariata, mentre per la parte OUTPUT, useremo un LED collegato al GPIO (13), in modo simile al primo esempio.
NOTA: Il LED potrebbe anche essere omesso e visualizzare il LED che sta direttamente sulla scheda Arduino. Nelle schede Arduino Uno Rev3 il LED è collegato al pin GPIO (13).

Figura 6: Schema circuitale del collegamento tasto-LED.
Il codice che segue effettua un lettura continua dello stato GPIO (BUTTON) e lo confronta con “1” ( vedere la riga “if (a == 1)” ). Se la condizione si verifica, viene eseguita la funzione “digitalWrite( LED, HIGH );”, altrimenti se non si verifica, viene eseguita la funzione “digitalWrite( LED, LOW );”.
Quindi il LED, collegato al GPIO (13), pre-impostato come OUTPUT, verrà alimentato in funzione dello stato logico del GPIO.
#define BUTTON 7
#define LED 13
void setup() {
pinMode( BUTTON, INPUT );
pinMode( LED, OUTPUT );
Serial.begin(9600);
}
void loop() {
int a;
a = digitalRead( BUTTON );
if (a == 1) {
digitalWrite( LED, HIGH );
} else {
digitalWrite( LED, LOW );
}
Serial.print("GPIO:");
Serial.println( a );
delay(200);
}
Codice completo dell’esempio.
Conclusioni
Una volta compreso questo esempio e come si “legge” uno stato di un GPIO digitale, configurato come INPUT, è facile comprendere che lo stesso potrebbe essere usato, per esempio, per verificare lo STATUS di un sensore di presenza ad infrarossi o della posizione di uno switch. Sotto il punto di vista elettronico, si deve fare particolare attenzione affinché il pin di INPUT non riceva una tensione fuori dai suoi limiti operativi, pena il danneggiamento permanente del microcontrollore.
Questo limite è generalmente il valore di operatività della logica della scheda. Nel caso di Arduino UNO Rev 3 e le nuove schede Rev 4, ovvero tutte quelle della famiglia Arduino equipaggiate con il microcontrollore Renesas RA4M1, sono a 0-5 volt, mentre ad esempio la scheda Arduino Nano 33 IoT funziona a 3.3 volt, quindi sarà 0-3.3 volt. E’ necessario prestare attenzione alla tensione applicata al pin verificando le specifiche del costruttore.
In questo articolo abbiamo visto:
- Cosa sono i GPIO e come si usano in ambiente Arduino
- A cosa servono i segnali discreti
- Come si configura e si controlla un GPIO in Arduino
- Dove sono i GPIO sulla scheda Arduino
- Esempio pratico 1: Colleghiamo un LED
- Come faccio ad accendere il LED
- Esempio pratico 2: Leggere lo stato di un pulsante
Contribuisci a far crescere questo sito
Se sei arrivato alla fine di questa pagina, ci auguriamo che l’argomento è stato di tuo interesse.
L’obiettivo di questo sito è divulgare tutorial e corsi sulle materie Elettronica e Programmazione, con la speranza di poter aiutare sempre più persone che desiderano aumentare le proprie conoscenze.
Tutti i tutorial e gli articoli sono scritti con cura e verificati. Per mantenere sempre alto il livello di qualità delle informazioni fornite, puoi aiutarci nei seguenti modi:
- ✅ Acquista un corso di formazione. I corsi sono di elevata qualità, curati nei dettagli e sempre aggiornati.
- ✅ Acquista un articolo consigliato nella pagina partner. Per te il prezzo sarà sempre uguale. Il nostro partner ci riserverà una piccola quota contributiva sul tuo acquisto.
Inoltre non dimenticare di rimanere in contatto con noi attraverso i Social Network. Se non lo fai adesso, probabilmente non ci rivedrai più: ⬇️
Grazie per il tuo contributo !!