Logo sheen.bot

← Approfondimenti

Perché il pin di Arduino legge HIGH quando non c'è nulla di collegato (e come risolvere)

14 ott 2026·Sheen Robotics
Perché il pin di Arduino legge HIGH quando non c'è nulla di collegato (e come risolvere)

Un pin di input di Arduino non collegato non assume come valore predefinito zero volt: rimane fluttuante in uno stato ad alta impedenza, fungendo da antenna che cattura disturbi elettrostatici dispersi.

Un pin di input di Arduino non collegato legge HIGH — oppure oscilla in modo imprevedibile tra HIGH e LOW — perché si trova in uno stato ad alta impedenza noto come pin flottante (floating pin). Non essendo collegato a una tensione di riferimento, si comporta come una minuscola antenna, captando i campi elettromagnetici ambientali, l'elettricità statica delle mani e il ronzio a 50 Hz della rete elettrica circostante.

Per ottenere una lettura prevedibile, ogni pin di input digitale deve essere sempre collegato in modo netto al binario di alimentazione positivo (HIGH) o a massa (LOW). Non serve saldare resistori esterni né ingombrare la breadboard degli studenti per riuscirci: quasi tutti i microcontrollori moderni includono resistori di pull-up interni attivabili con una sola riga di codice.

Il problema dell'alta impedenza

Quando si configura un pin usando pinMode(pin, INPUT), il microcontrollore imposta la circuiteria interna di quel pin in uno stato di alta impedenza. Su un ATmega328P (il microcontrollore alla base delle classiche schede Arduino Uno e Nano), la resistenza d'ingresso di un normale pin GPIO è di circa 100 megaohm (100.000.000 Ω). Il pin non assorbe quasi corrente: meno di un singolo microampere.

Si tratta di una caratteristica voluta: consente al microcontrollore di misurare un circuito esterno senza caricarlo né distorcerne il segnale. Tuttavia, tale sensibilità comporta una conseguenza fisica diretta. Poiché serve una corrente pressoché nulla per alterare la tensione di gate all'interno del chip, cariche elettrostatiche minuscole sulla superficie del pin o su un breve cavetto jumper bastano a portare la tensione del pin oltre la soglia logica digitale.

Su una scheda a 5V, qualsiasi valore superiore a circa 3,0V viene registrato come HIGH, mentre qualsiasi valore inferiore a circa 1,5V viene registrato come LOW. Quando un pin non è collegato a nulla, la sua tensione oscilla senza controllo in quella fascia intermedia. Non appena si muove una mano, si sfregano i piedi sulla moquette sintetica dell'aula o si avvicina l'alimentatore di un portatile, l'accoppiamento capacitivo spinge la tensione oltre la soglia e digitalRead() restituisce 1 (HIGH).

Il classico scenario di errore in classe

Nelle aule scolastiche e nei club di robotica, questo fenomeno genera una serie tipica di grattacapi durante il debugging:

  • Pressioni fantasma del pulsante: uno studente scrive il codice per accendere un LED quando viene premuto un pulsante. Non appena carica lo sketch, il LED si accende subito, anche se il pulsante non è stato toccato.
  • L'effetto "fluttuazione": il sensore del robot scatta semplicemente perché la mano di uno studente si avvicina a dieci centimetri dalla scheda, inducendo la classe a credere che il cavetto jumper si sia trasformato in un sensore di prossimità improvvisato.
  • Comportamento intermittente sulla breadboard: un progetto funziona in modo affidabile sul banco del docente, ma dà problemi una volta posizionato su un banco scolastico con telaio metallico sotto l'illuminazione a tubi fluorescenti.

Il rimedio classico da manuale consiste nell'aggiungere un resistore esterno di pull-down o pull-up da 10kΩ sulla breadboard. Per una classe di principianti, tuttavia, i resistori esterni introducono attriti inutili: gli studenti li collegano alla pista sbagliata, confondono le bande colorate o creano cortocircuiti diretti tra 5V e GND quando premono i pulsanti.

La soluzione pulita: INPUT_PULLUP

I progettisti di microcontrollori hanno previsto questo problema decenni fa. Microcontrollori come l'ATmega328P, l'RP2040 e l'ESP32 integrano resistori ricavati direttamente nel silicio accanto a ciascun pin GPIO. Su un Arduino Uno o Nano, questi resistori interni presentano una resistenza effettiva compresa tra 20kΩ e 50kΩ.

È possibile attivare questo resistore direttamente all'interno della funzione setup() passando una singola costante a pinMode():

void setup() {
  pinMode(2, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
}

Quando viene richiamato INPUT_PULLUP, il microcontrollore collega internamente il pin 2 alla propria alimentazione a 5V attraverso un resistore da 20kΩ–50kΩ. Questo debole collegamento porta dolcemente il pin a 5V ogni volta che il circuito rimane aperto. Essendo ora vincolato attivamente a una sorgente di tensione, il pin non subisce più l'influenza dei disturbi elettrostatici dispersi. Se lasciato libero, il pin leggerà in modo affidabile e stabile il valore HIGH.

Il cambio di logica: cablaggio per logica attiva-bassa (Active-LOW)

L'uso di INPUT_PULLUP richiede un piccolo adattamento logico da parte degli studenti: il circuito deve impiegare la logica attiva-bassa (active-LOW).

Dato che il pin si trova a livello HIGH per impostazione predefinita, un pulsante non deve collegarlo ai 5V. Il pulsante deve invece collegare il pin direttamente a GND:

  • Pulsante non premuto (circuito aperto): il pull-up interno mantiene il pin a 5V. digitalRead(pin) restituisce HIGH.
  • Pulsante premuto (circuito chiuso): il pin è collegato direttamente a massa (0V). La minuscola corrente che attraversa il resistore di pull-up interno fluisce in sicurezza verso GND. digitalRead(pin) restituisce LOW.

Il cablaggio hardware diventa più semplice: bastano due soli collegamenti per l'interruttore, uno al pin digitale e uno a qualsiasi pin di massa (GND) della scheda. Si eliminano del tutto il collegamento al binario dei 5V e i resistori esterni.

Nel software, è sufficiente invertire la condizione:

void loop() {
  int buttonState = digitalRead(2);

  // Con INPUT_PULLUP, LOW indica che il pulsante è premuto
  if (buttonState == LOW) {
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Quando utilizzare invece resistori esterni

Sebbene INPUT_PULLUP debba rappresentare la scelta predefinita per gli interruttori digitali a scuola, presenta limiti dettati dalle leggi della fisica:

ScenarioPull-up interno (20k–50kΩ)Resistore esterno (1k–10kΩ)
Pulsante standard su breadboardIdeale (nessun componente aggiuntivo)Complessità non necessaria
Tratte di cavo lunghe (> 1 metro)Soggetto a ritardo capacitivo e rumoreNecessario (utilizzare un pull-up forte da 1kΩ o 4,7kΩ)
Linee di comunicazione I2C (SDA/SCL)Troppo debole per velocità di bus elevateNecessario (in genere da 2,2kΩ a 4,7kΩ)
Requisiti di output del sensore in logica attiva-alta (Active-HIGH)Impossibile invertire il binario interno hardwareNecessario (utilizzare un pull-down esterno verso GND)

Per l'hardware STEM modulare e le piattaforme di prototipazione per la classe in cui è necessario ridurre al minimo gli errori di cablaggio, esplorate la selezione di sensori e componenti per microcontrollori disponibili su Sheen Robotics Store.

Promemoria riassuntivo per i docenti

  1. Non lasciare mai un ingresso flottante: se un pin di input è configurato semplicemente con INPUT, deve essere continuamente vincolato a una tensione definita tramite un circuito esterno.
  2. Usare INPUT_PULLUP come scelta predefinita: aggiornare i modelli di lezione standard per inizializzare i pin con pinMode(pin, INPUT_PULLUP).
  3. Collegare i pulsanti a GND, non a 5V: questo riduce il numero di componenti sulla breadboard, elimina i rischi di cortocircuito e rispecchia le convenzioni di cablaggio industriale standard.
  4. Insegnare presto la logica attiva-bassa: spiegare perché LOW significa "acceso" introduce gli studenti alla logica elettrica reale, dove collegare a massa un circuito attivo è più sicuro e robusto rispetto a instradare binari positivi attraverso interruttori esterni.
#arduino#elettronica#coding#didattica#robotica

Altri post in Approfondimenti