Componente · Sensore

Sensore ultrasonico HC-SR04

HC-SR04 è il sensore ultrasonoro più usato nei robot per misurare distanze. Scopri il funzionamento via eco, la portata reale, le zone cieche e il collegamento.

Che cos’è

HC-SR04 è un sensore di distanza ultrasonoro: la piccola scheda con due cilindri argentati che sembrano occhi da robot. Misura la distanza come fanno un pipistrello o un sommergibile: emette un suono troppo acuto da udire, ascolta l’eco e misura il tempo del viaggio di ritorno. Per pochi dollari dà al robot la percezione dello spazio davanti a sé, motivo per cui è il sensore predefinito del primo robot che evita ostacoli, costruito quasi da tutti.

I due cilindri sono un trasmettitore e un ricevitore. Uno emette, l’altro ascolta. Tutto il resto sulla scheda è un circuito di temporizzazione che trasforma quell’eco in un segnale misurabile dal microcontrollore.

Schema di HC-SR04 collegato a un microcontrollore: i fili VCC, Trigger, Echo e GND, colorati, arrivano ai quattro pin del sensore; il sensore emette onde ultrasonore che si riflettono su un oggetto e la distanza è uguale al tempo dell'eco moltiplicato per la velocità del suono e diviso per due.
Invia un impulso, misura il tempo necessario per il ritorno dell'eco e convertilo in distanza: i quattro fili sono alimentazione, terra, trigger ed eco. Scarica SVG

Come funziona

Il sensore parla un semplice linguaggio a due fili:

  1. Impulsi il pin Trigger portandolo HIGH per 10 microsecondi.
  2. Il sensore emette otto impulsi ultrasonori a 40 kHz e porta alto il pin Echo.
  3. Quando l’eco torna, riporta Echo a LOW.
  4. Misuri per quanto tempo Echo è rimasto HIGH.

Questa larghezza dell’impulso è il tempo di andata e ritorno. Il suono viaggia a circa 343 m/s nell’aria, quindi distance = (echo_time × 343) / 2; la divisione per due serve perché il suono è uscito ed è tornato indietro. La maggior parte del codice Arduino racchiude il calcolo in pulseIn() e in poche operazioni aritmetiche.

Poiché dipende dalla velocità del suono, la lettura varia leggermente con la temperatura (il suono è più veloce nell’aria calda). Per un robot che evita muri l’errore è trascurabile; per una misurazione di precisione conta e devi compensarlo in base alla temperatura.

Quando usarlo

Scegli HC-SR04 ogni volta che un robot deve sapere all’incirca a che distanza si trova l’oggetto più vicino, per evitare ostacoli, seguire un muro, impedire di uscire dal tavolo o attivare un comportamento quando qualcosa si avvicina. In questo caso il fascio largo è persino utile, perché è difficile mancare un ostacolo.

Cerca un’altra soluzione quando ti serve una distanza precisa, un fascio stretto o aggiornamenti rapidi. Un sensore a tempo di volo usa la luce invece del suono e restituisce una lettura compatta, rapida e accurata al millimetro, più adatta alla mappatura o a un robot che deve valutare un varco specifico.

Cablaggio e problemi comuni

  • Echo è un pin a 5 V. Su una scheda a 5 V come Arduino Uno va bene. Su una scheda a 3.3 V come ESP32, metti un partitore su Echo o rischi di danneggiare il pin.
  • Fai attenzione alla zona cieca e al cono. Nulla di più vicino di ~2 cm viene rilevato e il fascio di ~15° fa sì che il sensore riporti l’oggetto più vicino in un cono: una gamba del tavolo di lato può attivarlo.
  • Bersagli morbidi e inclinati ingannano. Schiuma, tessuto o un muro con un angolo ripido disperdono l’eco lontano dal ricevitore, quindi il sensore legge «lontano» o nulla. Funziona meglio con superfici piatte e rigide rivolte verso di sé.
  • Non interrogare troppo rapidamente. Lascia ~60 ms tra una lettura e l’altra, così l’eco precedente si estingue; un ping più rapido può generare eco parassite e letture false. Filtrare il flusso aiuta: consulta come domare il rumore dei sensori.

Piedinatura

Pin Nome Direzione Funzione
1 VCC Ingresso 5 V. La scheda assorbe circa 15 mA, con picchi durante un ping
2 Trig Ingresso Impulso HIGH per 10 µs per avviare una misurazione
3 Echo Uscita HIGH quando parte il gruppo di impulsi, LOW quando torna. Uscita a 5 V
4 GND — Terra

I quattro pin sono sempre in quest’ordine e il modulo è quasi sempre orientato con i pin rivolti nella direzione opposta ai trasduttori, quindi VCC si trova a sinistra mentre guardi gli “occhi”.

Collegamento a un Arduino

HC-SR04 Arduino Uno ESP32
VCC 5 V 5 V (da VIN, non dalla linea di alimentazione a 3.3 V)
Trig Qualsiasi pin digitale Qualsiasi GPIO
Echo Qualsiasi pin digitale Tramite un partitore, vedi sotto
GND GND GND

Il problema dei 3.3 V

Il pin Echo emette un segnale pieno a 5 V, mentre un GPIO di ESP32 o Raspberry Pi è progettato per 3.3 V. Applicare 5 V supera il limite assoluto massimo e, anche se spesso sopravvive per un po’, danneggia realmente il pin. Lo risolvono due resistori:

Echo ──┬── 1 kΩ ──┬── to 3.3 V GPIO
       │          │
       │        2 kΩ
       │          │
       └──────────┴── GND

Questo partitore dà 5 V × 2/(1+2) = 3.33 V. Funziona qualsiasi rapporto vicino a 2:1: 1 kΩ e 2 kΩ, oppure 10 kΩ e 20 kΩ. Non usare valori superiori a circa 20 kΩ, altrimenti la capacità di ingresso del pin rallenta abbastanza il fronte da distorcere i tempi che stai misurando.

L’aritmetica della distanza e dove va storta

distance = (echo_microseconds x speed_of_sound) / 2

A 20 °C il suono viaggia a 343 m/s, cioè 0.0343 cm/µs. Da qui deriva la costante che tutti usano: dividi il tempo dell’eco per 58.2 per ottenere i centimetri.

La velocità del suono dipende dalla temperatura, all’incirca:

speed (m/s) = 331.3 + 0.606 x temperature_celsius
Temperatura Velocità del suono Errore se assumi 20 °C
0 °C 331 m/s Legge 3.5% troppo lontano
20 °C 343 m/s —
40 °C 356 m/s Legge 3.7% troppo vicino

A 2 m si tratta di circa 7 cm in un garage d’inverno rispetto a una stanza calda. Per evitare ostacoli è irrilevante. Per qualsiasi misurazione di un varco, compensa; e se sul robot hai un MPU-6050 o quasi qualsiasi sensore I²C, hai già una lettura della temperatura.

Codice minimo funzionante

const int TRIG = 9, ECHO = 10;
const unsigned long TIMEOUT_US = 25000UL;   // ~4.3 m, past the sensor's range

void setup() {
  Serial.begin(115200);
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);
}

// Returns centimetres, or -1 when nothing came back.
float pingCm() {
  digitalWrite(TRIG, LOW);  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH); delayMicroseconds(10);
  digitalWrite(TRIG, LOW);

  unsigned long us = pulseIn(ECHO, HIGH, TIMEOUT_US);
  if (us == 0) return -1.0f;        // timeout: no echo, NOT "zero distance"
  return us / 58.2f;
}

// Median of three kills the occasional wild reading.
float pingMedianCm() {
  float a = pingCm(); delay(60);
  float b = pingCm(); delay(60);
  float c = pingCm();
  if (a > b) { float t = a; a = b; b = t; }
  if (b > c) { float t = b; b = c; c = t; }
  if (a > b) { float t = a; a = b; b = t; }
  return b;
}

void loop() {
  float cm = pingMedianCm();
  if (cm < 0) Serial.println("no echo");
  else        Serial.println(cm);
  delay(60);
}

Tre dettagli fanno la differenza tra un sensore che funziona e uno che non funziona:

Il timeout non è facoltativo. pulseIn senza timeout blocca finché non arriva un’eco e su una superficie morbida o inclinata questa non arriva mai. Il robot sembra bloccarsi a intervalli casuali e la causa sembra qualsiasi cosa tranne il sensore.

Zero non è una distanza. Un timeout significa «non è tornato nulla», il che di solito significa che l’oggetto più vicino è lontano o invisibile, non a distanza zero. Il codice che tratta un timeout come 0 cm si arresterà d’emergenza in una stanza vuota.

La mediana di tre misure scarta la singola lettura anomala che questi sensori producono regolarmente. Un valore spurio di 20 cm in uno spazio aperto basta a far deviare un robot contro un muro.

Il fascio in pratica

La specifica indica 15°, apparentemente come un fascio stretto di una torcia. Non è così: è il semiangolo del lobo principale e la conseguenza pratica è che a 1 m il sensore ascolta un cono largo circa 50 cm.

Distanza Larghezza approssimativa del cono
20 cm ~10 cm
50 cm ~26 cm
1 m ~53 cm
2 m ~105 cm

Il sensore riporta l’oggetto più vicino in qualsiasi punto di quel cono e non indica dove si trovi all’interno. Ecco perché HC-SR04 rileva un telaio di porta che non riesce a localizzare e perché una gamba del tavolo ben di lato provoca un arresto.

Per muoversi in una stanza è un vantaggio, perché è molto difficile mancare un ostacolo. Per misurare la distanza da un oggetto specifico è invece inaccettabile: serve un VL53L0X.

Che cosa non può vedere

Sono limiti della fisica, non difetti, e progettare di conseguenza è il tuo lavoro:

Superficie Che cosa accade Perché
Muro a più di ~45° Legge lontano oppure nulla Il suono si riflette in una direzione che non raggiunge il ricevitore, come la luce da uno specchio
Cuscini, tende, schiuma Non legge nulla Il materiale assorbe l’impulso invece di rifletterlo
Oggetti molto vicini Non legge nulla sotto ~2 cm Il ricevitore è ancora sordo dopo l’emissione del gruppo di impulsi
Oggetti sottili (il bordo di una gamba della sedia) Rilevati ma mal localizzati Il cono è largo; il ritorno è reale, ma la direzione non lo è
Un altro HC-SR04 nelle vicinanze Letture anomale casuali Sente il ping dell’altro sensore: sfasa le misurazioni

Un robot che dipende solo dalla misura ultrasonora spingerà prima o poi una tenda finché qualcosa non cede. Ecco perché un interruttore di urto è l’elemento di affidabilità più economico dell’intero robot.

Risoluzione dei problemi

Sintomo Causa probabile Soluzione
Legge sempre 0 Sta trattando un timeout come distanza Restituisci un valore sentinella e gestisci esplicitamente «nessuna eco»
Il robot si blocca in modo casuale pulseIn senza timeout Passa un timeout: 25000 µs copre tutta la portata
Le letture saltano in modo brusco Interrogazioni più rapide di ~60 ms Aspetta che l’eco precedente si estingua
Valore stabile ma sbagliato di qualche percento Temperatura Compensa con la formula della velocità del suono
Funziona sul banco, non sul robot Rumore dei motori sulla linea di alimentazione a 5 V Disaccoppia l’alimentazione del sensore e tieni i suoi fili lontani dai cavi dei motori
Due sensori si interferiscono Si sentono a vicenda Attivali in sequenza, mai contemporaneamente
Il pin ESP32 ha smesso di rispondere Echo a 5 V verso un GPIO a 3.3 V Aggiungi il partitore e verifica che il pin funzioni ancora
Rileva oggetti che non sono davanti Il cono di 15° Previsto; riduci meccanicamente l’angolo utile o usa un sensore laser

HC-SR04 o VL53L0X?

HC-SR04 VL53L0X
Metodo Suono a 40 kHz Laser a tempo di volo a 940 nm
Portata 2 cm – 4 m 3 cm – 2 m (fino a 4 m nel caso migliore)
Fascio Semiangolo di ~15°, cono largo Campo visivo di ~25°, ma di fatto un fascio stretto
Frequenza di aggiornamento ~16 Hz (ciclo di 60 ms) Fino a 50 Hz
Non adatto a Superfici morbide e molto inclinate Superfici scure opache e a specchio, luce solare intensa
Interfaccia Due pin, nessuna libreria necessaria I²C
Costo ~$2 ~$5

Falliscono su materiali opposti, ed è questo che rende facile la scelta una volta che conosci l’ambiente. Il sonar vede una scatola nera avvolta in tessuto che il laser non vede; il laser vede una porta di vetro a un angolo che il sonar non vede. Su un robot che deve essere affidabile, la risposta onesta è spesso entrambi, più un interruttore di urto per quando sbagliano entrambi.

Esplora il grafo

Usato in queste costruzioni

Progetti, percorsi di apprendimento e simulatori che includono Sensore ultrasonico HC-SR04.

Confronto

Alternative

Domande

FAQ su Sensore ultrasonico HC-SR04

Che cos'è il sensore ultrasonoro HC-SR04?

HC-SR04 è un sensore di distanza a basso costo che misura quanto è lontano un oggetto facendo rimbalzare su di esso un impulso di ultrasuoni, con lo stesso principio usato da pipistrelli e sonar. È il sensore usato dalla maggior parte dei robot alle prime mosse per rilevare ed evitare gli ostacoli.

Come funziona HC-SR04?

Invii un breve impulso al pin Trigger. Il sensore emette otto gruppi di impulsi ultrasonori a 40 kHz e porta alto il pin Echo finché non torna il riflesso. Misuri per quanto tempo Echo resta alto e, poiché il suono viaggia a circa 343 m/s, la distanza è uguale al tempo moltiplicato per la velocità del suono e diviso per due, perché l'onda percorre l'intero tragitto di andata e ritorno.

Qual è la portata massima di HC-SR04?

HC-SR04 misura da circa 2 cm a 4 m. È più preciso nell'intervallo da 5 cm a 2 m; vicino al limite di 4 m le letture diventano inaffidabili e gli oggetti a meno di circa 2 cm rientrano nella sua zona cieca e non possono essere misurati.

HC-SR04 è preciso e affidabile?

È abbastanza preciso per evitare ostacoli: ha una risoluzione di circa 3 mm su un bersaglio piatto e rigido rivolto frontalmente. Fatica con superfici morbide o inclinate, che disperdono l'eco, risente della temperatura e ha un fascio largo di ~15°, quindi misura un cono, non un punto.

Come colleghi HC-SR04 a un Arduino?

Collega VCC a 5 V, GND a terra, Trigger a un qualsiasi pin di uscita digitale ed Echo a un pin di ingresso digitale. Attenzione: Echo emette 5 V, quindi se usi una scheda a 3.3 V come ESP32, riduci la tensione con un partitore prima di leggere il segnale.

HC-SR04 o US-100, quale conviene?

US-100 è un stretto parente con una modalità compensata in temperatura, un'opzione di interfaccia seriale e funzionamento a 3.3–5 V, che lo rende più preciso e più adatto alle schede a 3.3 V. HC-SR04 costa meno e dispone di più tutorial. Per imparare va bene HC-SR04; per la precisione è avanti US-100.

Come verifico se il sensore ultrasonoro funziona?

Stampa la distanza misurata sul monitor seriale e avvicina e allontana la mano dal sensore: la lettura dovrebbe cambiare in modo regolare. Se resta ferma a zero o al valore massimo, controlla il cablaggio di Trigger ed Echo, verifica un'alimentazione stabile a 5 V e accertati che il timeout sia abbastanza lungo per tutta la portata di 4 m.

Per approfondire

Fonti