Skip to Content

Come usare un sensore di distanza a ultrasuoni HC-SR04 con Arduino

Come usare un sensore di distanza a ultrasuoni HC-SR04 con Arduino

L’HC-SR04 è un sensore di distanza a ultrasuoni economico e facile da usare, con un intervallo da 2 cm a 400 cm. È comunemente utilizzato in robot per evitare ostacoli e progetti di automazione. In questo tutorial, imparerai come funziona il sensore e come usarlo con Arduino.

Ho incluso 5 esempi con uno schema di collegamento e codice per permetterti di iniziare a sperimentare con il tuo sensore. Inizieremo con un esempio che non utilizza una libreria Arduino. Successivamente, ti mostrerò come usare la libreria NewPing per creare un codice più compatto.

Materiali

Componenti hardware

hc-sr04HC-SR04 sensor× 1Amazon
Arduino Uno Rev 3Arduino Uno Rev3× 1Amazon
Breadboard× 1Amazon
Jumper wires~ 10Amazon
USB cable type A/B× 1Amazon
lcd20×4 character I2C LCD (opzionale)× 1Amazon
DHT11 sensor (opzionale)× 1Amazon

Software

Arduino IDEArduino IDE

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Come funziona un sensore di distanza a ultrasuoni?

I sensori a ultrasuoni funzionano emettendo onde sonore con una frequenza troppo alta per essere udite dall’uomo. Queste onde sonore viaggiano nell’aria alla velocità del suono, circa 343 m/s. Se c’è un oggetto davanti al sensore, le onde sonore vengono riflesse e il ricevitore del sensore a ultrasuoni le rileva. Misurando il tempo trascorso tra l’invio e la ricezione delle onde sonore, si può calcolare la distanza tra il sensore e l’oggetto.

How Ultrasonic Sensors Work Maxbotix
Principio di funzionamento dei sensori di distanza a ultrasuoni. Fonte: https://www.maxbotix.com/

A 20°C, la velocità del suono è circa 343 m/s o 0,034 cm/µs. Supponiamo che il tempo tra l’invio e la ricezione delle onde sonore sia di 2000 microsecondi. Moltiplicando la velocità del suono per il tempo di percorrenza delle onde sonore, otteniamo la distanza percorsa dalle onde sonore.

Distanza = Velocità × Tempo

Ma questo non è il risultato che cerchiamo. La distanza tra il sensore e l’oggetto è in realtà solo la metà di questa distanza perché le onde sonore viaggiano dal sensore all’oggetto e poi tornano indietro. Quindi è necessario dividere il risultato per due.

Distanza (cm) = Velocità del suono (cm/µs) × Tempo (µs) / 2

Quindi, per l’esempio, diventa:

Distanza (cm) = 0,0343 (cm/µs) × 2000 (µs) / 2 = 34,3 cm

Dipendenza della velocità del suono dalla temperatura

La velocità del suono dipende fortemente dalla temperatura e in misura molto minore dall’umidità dell’aria. Wikipedia afferma che la velocità del suono aumenta di circa 0,6 m/s per ogni grado Celsius. Nella maggior parte dei casi, a 20°C si può usare 343 m/s, ma se vuoi ottenere misurazioni più precise, puoi calcolare la velocità del suono con la seguente formula:

V (m/s) = 331,3 + (0,606 × T)

V = Velocità del suono (m/s)
T = Temperatura dell’aria (°C)

Questa formula non include l’umidità poiché il suo effetto sulla velocità del suono è molto piccolo.

Qui sotto trovi un tutorial su come usare un DHT11 sensore di temperatura e umidità per calibrare la velocità del suono e ottenere una lettura della distanza più precisa con l’HC-SR04.

Come funziona l’HC-SR04

Nella parte frontale del sensore HC-SR04 si trovano due cilindri argentati (trasduttori a ultrasuoni), uno è il trasmettitore delle onde sonore e l’altro il ricevitore. Per far generare al sensore un impulso sonoro, devi impostare il pin Trig alto per almeno 10 µs. Il sensore crea quindi un impulso di 8 cicli di ultrasuoni a 40 kHz.

Questo impulso sonoro viaggia alla velocità del suono, rimbalza e viene ricevuto dal ricevitore del sensore. Il pin Echo quindi fornisce in uscita il tempo di percorrenza delle onde sonore in microsecondi.

Puoi usare la pulseIn() funzione nel codice Arduino per leggere la durata dell’impulso dal pin Echo. Successivamente, puoi usare la formula menzionata sopra per calcolare la distanza tra il sensore e l’oggetto.

Specifiche HC-SR04

Tensione di funzionamento5 V
Corrente di funzionamento15 mA
Frequenza40 kHz
Intervallo di misura2 – 400 cm
Risoluzione3 mm
Angolo di misura15 gradi
Segnale di ingresso TriggerImpulso alto di 10 µs
CostoCheck price

Per maggiori informazioni puoi consultare il datasheet qui sotto:

Collegamenti – Connettere HC-SR04 ad Arduino UNO

Lo schema di collegamento qui sotto mostra come connettere il sensore HC-SR04 ad Arduino.

HC-SR04-ultrasonic-distance-sensor-with-Arduino-wiring-diagram-schematic-tutorial
Schema di collegamento HC-SR04 con Arduino

Gli esempi di codice qui sotto usano i pin digitali 2 e 3 per il trigger e l’echo rispettivamente, ma ovviamente puoi cambiarli con qualsiasi pin digitale tu voglia.

Collegamenti HC-SR04

HC-SR04Arduino
VCC5 V
TrigPin 2
EchoPin 3
GNDGND

Esempio di codice per HC-SR04 con Arduino

Ora che hai collegato il sensore, è il momento di connettere l’Arduino al computer e caricare del codice. Puoi caricare il seguente esempio di codice sul tuo Arduino usando l’IDE Arduino. Successivamente ti spiegherò come funziona il codice.

/* Example code for HC-SR04 ultrasonic distance sensor with Arduino. 
   No library required. More info: https://www.makerguides.com */

// Define Trig and Echo pin:
#define trigPin 2
#define echoPin 3

// Define variables:
long duration;
int distance;

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  //Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}

void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin, pulseIn() returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);
  // Calculate the distance:
  distance = duration * 0.034 / 2;

  // Print the distance on the Serial Monitor (Ctrl+Shift+M):
  Serial.print("Distance = ");
  Serial.print(distance);
  Serial.println(" cm");

  delay(50);
}

Come funziona il codice

Per prima cosa, vengono definiti il pin trigger e il pin echo. Li chiamo trigPin e EchoPin. Il pin trigger è collegato al pin digitale 2 e il pin echo al pin digitale 3 su Arduino.

L’istruzione #define viene usata per dare un nome a un valore costante. Il compilatore sostituirà ogni riferimento a questa costante con il valore definito quando il programma viene compilato. Quindi ovunque menzioni trigPin, il compilatore lo sostituirà con il valore 2 durante la compilazione.

// Define Trig and Echo pin:
#define trigPin 2
#define echoPin 3

Successivamente definisco due variabili: duration e distance. Duration memorizza il tempo tra l’invio e la ricezione delle onde sonore. La variabile distance serve a memorizzare la distanza calcolata.

// Define variables:
long duration;
int distance;

Nel setup(), inizi impostando trigPin come output e echoPin come input. Poi inizializzi la comunicazione seriale a 9600 baud. Successivamente mostrerai la distanza misurata nel monitor seriale, accessibile con Ctrl+Shift+M o Tools > Serial Monitor. Assicurati che anche il baud rate nel monitor seriale sia impostato a 9600.

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  //Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}

Nel loop(), attivi il sensore impostando trigPin HIGH per 10 µs. Nota che per ottenere un segnale pulito inizi azzerando trigPin impostandolo LOW per 5 microsecondi.

void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

Poi devi leggere la durata dell’impulso inviato da echoPin. Per questo uso la funzione pulseIn() . Questa funzione aspetta che il pin passi da LOW a HIGH, inizia a cronometrare, poi aspetta che il pin torni LOW e ferma il cronometro.

Dopodiché puoi calcolare la distanza usando la formula menzionata all’inizio di questo tutorial.

// Read the echoPin, pulseIn() returns the duration (length of the pulse) in microseconds:
duration = pulseIn(echoPin, HIGH);
// Calculate the distance:
distance = duration * 0.034 / 2;

Infine, la distanza calcolata viene stampata nel monitor seriale.

// Print the distance on the Serial Monitor (Ctrl+Shift+M):
Serial.print("Distance = ");
Serial.print(distance);
Serial.println(" cm");

delay(50);

Esempio di codice HC-SR04 con Arduino e libreria NewPing

La libreria NewPing scritta da Tim Eckel può essere usata con molti sensori di distanza a ultrasuoni. L’ultima versione di questa libreria può essere scaricata qui su bitbucket.org. Potresti notare che il codice qui sotto, che usa la libreria NewPing, è molto più corto rispetto a quello usato prima. Inoltre, la libreria NewPing include altre funzionalità interessanti. Ti permette di impostare una distanza massima da leggere, non si blocca per un secondo intero quando non riceve eco e ha un filtro mediano integrato.

Puoi installare la libreria andando su Sketch > Include Library > Add .ZIP Library nell’IDE Arduino.

La libreria include alcuni esempi che puoi usare, ma dovrai modificarli per adattarli al tuo hardware. Ho incluso un esempio modificato qui sotto che può essere usato con lo stesso schema di collegamento di prima.

/* HC-SR04 ultrasonic distance sensor with 
   NewPing library example code. 
   More info: www.www.makerguides.com */

// Include the library:
#include "NewPing.h"

// Define pins and max distance:
#define trigPin  2
#define echoPin  3
#define MAX_DISTANCE 350 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(trigPin, echoPin, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
float duration, distance;

void setup() {
  Serial.begin(9600); // Open serial monitor at 9600 baud to see ping results.
}

void loop() {
  delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  
  duration = sonar.ping();
  distance = (duration / 2) * 0.0343;
  
  Serial.print("Distance = ");
  Serial.print(distance); // Distance will be 0 when out of set max range.
  Serial.println(" cm");
}

Puoi anche usare distance = sonar.ping_cm() o distance = sonar.ping_in() che restituiscono la distanza misurata in centimetri interi o pollici. Con questa funzione non è necessario misurare la durata e calcolare la distanza.

Interfacciare sensori a ultrasuoni in modalità a 3 pin

La libreria NewPing rende facile anche interfacciare sensori a ultrasuoni usando un solo pin I/O. Questo può essere utile se hai pochi pin I/O disponibili o se vuoi usare un sensore a ultrasuoni a 3 pin come il Parallax Ping.

Per creare una configurazione a 3 pin (GND, 5V e SIG) devi collegare sia il pin trigger che il pin echo allo stesso pin digitale su Arduino. Nel codice, l’unica cosa da cambiare sono le righe 6-7, definendo lo stesso pin sia per trigPin che per echoPin. Per esempio il pin digitale 2.

//Define Trig and Echo pin
#define trigPin 2
#define echoPin 2

Come usare il filtro digitale ping_median()

La cosa che mi piace di più della libreria NewPing è che ha un filtro mediano integrato. Questo filtro può migliorare notevolmente la precisione delle letture dell’HC-SR04. La ping_median() funzione prende molte misurazioni di durata di seguito, scarta quelle fuori intervallo e poi fa la media di quelle rimanenti. Di default prende 5 letture, ma puoi specificare quante deve prendere. Sostituisci la riga 19 con le righe qui sotto.

int iterations = 5;
duration = sonar.ping_median(iterations);

Esempio di codice HC-SR04 con LCD I2C e Arduino

Per visualizzare la distanza misurata su un 20041602 LCD I2C, tutto quello che devi fare è effettuare i seguenti collegamenti e caricare il codice qui sotto. Il sensore HC-SR04 è collegato come prima.

HC-SR04 with I2C LCD and Arduino UNO wiring
Schema di collegamento HC-SR04 con Arduino e LCD I2C.

Collegamenti LCD I2C

LCD I2CArduino
GNDGND
VCC5 V
SDAA4
SCLA5

Se non usi un Arduino Uno, i pin SDA e SCL possono trovarsi in posizioni diverse. Un Arduino UNO con layout R3 (pinout 1.0) ha anche i pin header SDA (linea dati) e SCL (linea clock) vicino al pin AREF. Consulta la tabella qui sotto per maggiori dettagli.

SchedaSDASCL
Arduino UnoA4A5
Arduino NanoA4A5
Arduino Micro23
Arduino Mega 25602021
Arduino Leonardo23
Arduino Due2021
Posizioni dei pin I2C per diverse schede Arduino

Il codice usa la libreria LiquidCrystal_I2C che puoi scaricare su GitHub. Assicurati di avere installato esattamente questa libreria! Include anche la libreria Wire.h che permette di comunicare con dispositivi I2C. Questa libreria dovrebbe essere preinstallata con l’IDE Arduino.

Se vuoi imparare di più su come controllare un LCD I2C con Arduino, puoi consultare il nostro tutorial su How to control a character I2C LCD with Arduino.

/* HC-SR04 ultrasonic distance sensor with 
   Arduino and I2C LCD example code.
   More info: https://www.makerguides.com
*/

#include "Wire.h"
#include "LiquidCrystal_I2C.h"

// Define Trig and Echo pin:
#define trigPin 2
#define echoPin 3

// Define SDA and SCL pin for LCD:
#define SDAPin A4 // Data pin
#define SCLPin A5 // Clock pin

// Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered):
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27,20,4); //Change to (0x27,16,2) for 1602 LCD 

// Define variables:
long duration;
int distance;

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 

  // Initiate the LCD:
  lcd.init();
  lcd.backlight();
}

void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin. This returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);

  // Calculate the distance:
  distance = duration*0.034/2;

  // Display the distance on the LCD:
  lcd.setCursor(0,0); // Set the cursor to column 1, line 1 (counting starts at zero)
  lcd.print("Distance = "); // Prints string "Display = " on the LCD
  lcd.print(distance); // Prints the measured distance
  lcd.print(" cm  "); // Prints "cm" on the LCD, extra spaces are needed to clear previously displayed characters
  
  delay(50);
}

Nota che ho usato un display LCD 20 x 4. Se hai un LCD di dimensioni diverse (16 x 2 è comune) devi cambiare la riga 20 in LiquidCrystal_I2C lcd(0x27,16,2);. Se il tuo LCD non ha l’indirizzo I2C predefinito, 0x27, consulta il tutorial completo sull’I2C dove spiego come scoprire qual è l’indirizzo.

Esempio di codice HC-SR04 con sensore di temperatura DHT11 e Arduino

Come detto prima, la velocità del suono dipende molto dalla temperatura dell’aria. Se vuoi misurare distanze lunghe (3-4 m) può essere una buona idea aggiungere un sensore DHT11 o DHT22 di temperatura e umidità al tuo setup. Questo ti permetterà di calibrare la velocità del suono in tempo reale e aumentare così la precisione delle misurazioni.

Aggiungere un sensore DHT11 è molto semplice. Lo schema di collegamento qui sotto mostra quali connessioni fare. Nota che sto usando un DHT11 con breakout board, quindi devo collegare solo 3 pin. Assicurati di controllare l’etichetta del sensore, l’ordine dei pin può variare a seconda del produttore. Il sensore HC-SR04 è collegato come prima.

HC-SR04 with DHT11 and Arduino UNO wiring
Schema di collegamento HC-SR04 con Arduino e DHT11.

Collegamenti DHT11

DHT11Arduino
VCC (+)5 V
Segnale (s)Pin 4
GND (-)GND

Il codice qui sotto usa la libreria Adafruit DHT Humidity & Temperature Sensor che puoi scaricare da GitHub. Questa libreria funziona solo se hai anche installato la libreria Adafruit_Sensor, anch’essa disponibile su GitHub. Puoi scaricare entrambe le librerie cliccando sui pulsanti qui sotto:

Puoi cliccare il pulsante in alto a destra nel campo del codice per copiarlo.

/* HC-SR04 ultrasonic distance sensor with 
   DHT11 and Arduino example code.
   More info: https://www.makerguides.com */

#include "Adafruit_Sensor.h" //https://github.com/adafruit/Adafruit_Sensor
#include "DHT.h" //https://github.com/adafruit/DHT-sensor-library

// Define Trig pin, Echo pin and DHTPin:
#define trigPin 2
#define echoPin 3
#define DHTPin 4

// Define DHT sensor type:
#define DHTType DHT11

// Define variables:
long duration;
int distance;
float speedofsound;

// Create a DHT sensor object:
DHT dht = DHT(DHTPin,DHTType);

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 

  dht.begin();

  // Begin Serial communication:
  Serial.begin(9600); // Starts the serial communication
}

void loop() {
  //  Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin. This returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);

  // Read the temperature:
  float temperature = dht.readTemperature();

  // Calculate speed of sound in m/s:
  speedofsound = 331.3+(0.606*temperature);

  // Calculate the distance in cm:
  distance = duration*(speedofsound/10000)/2;

  // Print the distance and temperature on the Serial Monitor:
  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.print(" Celsius");
  Serial.print(", Distance = ");
  Serial.print(distance);
  Serial.println("cm");
  delay(100);
}

Esempio di codice HC-SR04 con DHT11 e LCD I2C

HC-SR04 with DHT11, I2C LCD and Arduino UNO wiring
Schema di collegamento HC-SR04 con Arduino, DHT11 e LCD I2C.

Il codice qui sotto può essere usato per combinare tutti e 3 gli esempi precedenti. Visualizza temperatura, velocità del suono e distanza misurata sul display LCD.

/* HC-SR04 ultrasonic distance sensor with 
   DHT11, I2C LCD and Arduino example code.
   More info: https://www.makerguides.com */

#include "Adafruit_Sensor.h" // https://github.com/adafruit/Adafruit_Sensor
#include "DHT.h" // https://github.com/adafruit/DHT-sensor-library
#include "Wire.h" // Library for I2C communication
#include "LiquidCrystal_I2C.h" // Library for LCD

// Define Trig pin, Echo pin and DHTPin:
#define trigPin 2
#define echoPin 3
#define DHTPin 4

// Define SDA and SCL pin from LCD:
#define SDAPin A4 // Data pin
#define SCLPin A5 // Clock pin

// Connect to LCD via i2c, default address 0x27 (A0-A2 not jumpered):
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27,20,4);

// Define DHT sensor type:
#define DHTType DHT11

// Define variables:
long duration;
int distance;
float speedofsound;

// Create a DHT sensor object:
DHT dht = DHT(DHTPin,DHTType);

void setup() {
  // Define inputs and outputs:
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 

  dht.begin();

  // Initiate the LCD:
  lcd.init();
  lcd.backlight();

  // Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}

void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin. This returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);

  // Read the temperature:
  int temperature = dht.readTemperature();

  // Calculate speed of sound in m/s:
  speedofsound = 331.3+(0.606*temperature);

  // Calculate the distance in cm:
  distance = duration*(speedofsound/10000)/2;

  // Print the distance and temperature on the Serial Monitor:
  lcd.setCursor(0,0);
  lcd.print("Temperature: ");
  lcd.print(temperature);
  lcd.print(" " "\xDF" "C");
  lcd.setCursor(0,1);
  lcd.print("Speed: ");
  lcd.print(speedofsound);
  lcd.print(" m/s ");
  lcd.setCursor(0,2);
  lcd.print("Distance: ");
  lcd.print(distance);
  lcd.print(" cm  ");
  delay(100);
}

Dimensioni HC-SR04

Qui sotto trovi le dimensioni del sensore a ultrasuoni HC-SR04. Ho notato che ci sono piccole differenze tra i produttori, quindi ti consiglio di verificare con il tuo sensore.

HC-SR04 Dimensions
Dimensioni HC-SR04

CAD HC-SR04

Ho creato disegni CAD base del sensore a ultrasuoni HC-SR04 che puoi scaricare qui sotto.

Conclusione

In questo articolo ti ho mostrato come funziona il sensore di distanza a ultrasuoni HC-SR04 e come usarlo con Arduino.

Progetto personale: tempo fa ho realizzato un’installazione murale interattiva con alcuni amici. Abbiamo usato circa 30 sensori di distanza a ultrasuoni per rilevare le persone che camminavano davanti al muro. Il muro includeva luci ed effetti sonori che cambiavano in base alla distanza delle persone.

HC-SR04 Example AMS Prototypes
Foto: Guus Schoonewille

I sensori di distanza/prossimità a ultrasuoni economici sono ottimi, ma in alcuni progetti potresti aver bisogno di un sensore impermeabile come il JSN-SR04T o di un sensore IR che non sia influenzato dai cambiamenti di temperatura. In tal caso, gli articoli qui sotto potrebbero esserti utili:

Se hai domande, suggerimenti o pensi che manchi qualcosa in questo tutorial, lascia pure un commento qui sotto.