Una delle idee iniziali che mi erano venute in mente in fase di realizzazione del mio antifurto era di utilizzare un sensore ad ultrasuoni per la rilevazione della distanza.
Poi sono ripiegato sul modulo PIR.
Ho deciso in ogni caso di rispolverarlo e di leggermi un po’ la documentazione e il datasheet.
La misurazione con questo componente è fatta misurando il tempo impiegato da un segnale sonoro a raggiungere un oggetto e ritornare al sensore.
La misura quindi non è in termini di distanza ma di tempo, in particolare in microsecondi.
Il sensore HC-SR04 dispone di 4 pin: Vcc (+5V), Trigger, Echo, GND.
In linea di massima il funzionamento è così:
- viene inviato un ping sonoro dal pin Trigger
- se viene intercettato un ostacolo l’onda viene riflessa e torna indietro.
- il pin Echo riceve il segnale ritornato
Il tempo impiegato ci permette di stabilire la distanza fra il sensore e l’ostacolo.
Come fare?
Per convertire l’unità di tempo in spazio è necessario sapere la velocità del suono nell’aria: ci aiuta wikipedia.
Nell’aria, la velocità del suono è di 331,45 m/s a 0 °C (pari a 1 193,04 km/h) e di 343,8 m/s (pari a 1 237,68 km/h) a 20 °C (e in generale varia secondo la relazione a = 331,45 + 0,62 t con t misurata in °C).
Quindi consideriamo circa 343 m/s, espresso in centrimetri: 0,0343 cm/microsecondi.
Dato che lo spazio = velocità * tempo (s= v*t) ne risulta che s = 0,0343 *t.
Bisogna però considerare che il tempo individuato dal pin Echo è quello di partenza dal pin Trigger, arrivo all’ostacolo e tornare indietro verso il sensore.
Quindi sarà necessario dividere il tempo: s = 0,0343 *t / 2.
La formula che utilizzeremo in definitiva sarà: s = 0,01715 * t
Passiamo ora ai collegamenti con Arduino:
Pin Arduino | Pin Sensore |
POWER 5V | VCC |
Digital 7 | Trig |
Digital 8 | Echo |
GND | GND |
Passiamo quindi al codice:
int trigger_Port = 7; int echo_Port = 8; void setup() { pinMode( trigger_Port, OUTPUT ); pinMode( echo_Port, INPUT ); Serial.begin( 9600 ); Serial.println( "Sensore distanza ad ultrasuoni: "); } void loop() { //setto uscita bassa su pin del trigger digitalWrite( trigger_Port, LOW ); //invio impulso di 10 micro secondi su pin del trigger digitalWrite( trigger_Port, HIGH ); delayMicroseconds( 10 ); //setto nuovamente uscita bassa su pin del trigger digitalWrite( trigger_Port, LOW ); //leggo la durata sul pin Echo long durata = pulseIn( echo_Port, HIGH ); //calcolo la durata long r = 0.034 * durata / 2; Serial.print( "durata: " ); Serial.print( durata ); Serial.print( " , " ); Serial.print( "distanza: " ); //dopo 38ms è fuori dalla portata del sensore if( durata > 38000 ) Serial.println( "fuori portata"); else { Serial.print( r ); Serial.println( "cm" ); } //aspetta 1.0 secondi delay( 1000 ); }
E’ possibile anche utilizzare la libreria new_ping.
Una volta scaricata la libreria e copiato il contenuto nella cartella libraries di Arduino è possibile semplificare la scrittura del codice:
#include <NewPing.h> #define trigger_Port 7 #define echo_Port 8 #define max_distance 200 NewPing sonar(trigger_Port, echo_Port, max_distance); void setup() { Serial.begin(9600); } void loop() { delay(50); unsigned int uS = sonar.ping_cm(); Serial.print(uS); Serial.println("cm"); }
Con questa libreria è possibile inviare anche un ping multiplo e farsi ritornare la media delle letture effettuate, basta utilizzare:
nsigned int uS = sonar.ping_median(numero misurazioni);
#include <NewPing.h> #define trigger_Port 7 #define echo_Port 8 #define max_distance 200 NewPing sonar(trigger_Port, echo_Port, max_distance); void setup() { Serial.begin(9600); } void loop() { delay(50); unsigned int durata = sonar.ping_median(5); long r = 0.034 * durata / 2; Serial.print(r); Serial.println("cm"); }
In questo caso ho impostato come numero di misurazioni 5. Quindi ci verrà riportata la media di 5 misurazioni.
Che dire…è decisamente una libreria tanto utile quanto facile da usare!