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.
Come funziona
Il sensore parla un semplice linguaggio a due fili:
- Impulsi il pin Trigger portandolo HIGH per 10 microsecondi.
- Il sensore emette otto impulsi ultrasonori a 40 kHz e porta alto il pin Echo.
- Quando l’eco torna, riporta Echo a LOW.
- 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