Mesurer la vitesse du son avec un microcontrôleur et le capteur de distance HCSR04
Objectif
On détourne l'usage initialement prévu pour déterminer la vitesse de l'onde ultrasonore en mesurant le temps mis par l'onde pour parcourir une distance connue.
Méthode : Principe de la mesure
Il s'agit de connecter l'émetteur/récepteur d'ultrasons comme indiqué précédemment puis de placer un obstacle permettant la réflexion de l'onde.
On mesure le plus précisément possible la distance qui sépare le composant de l'obstacle en prenant comme référence les capsules protégées par la grille du capteur.
Cette valeur peut être entrée dans un programme en tant que variable. Le programme mesure le temps mis par l'onde pour effectuer un aller-retour et renvoie la valeur en microsecondes. Il est alors possible de calculer la vitesse du son et de l'afficher.
On peut utiliser le moniteur série (plus simple) ou un écran LCD pour afficher le résultat.
Le code ci-dessous affiche la valeur de la vitesse mesurée sur le moniteur série.
/*Principe du montage :
On place l'émetteur-récepteur US à une distance
connue d'un obstacle entre 30 cm et 2 m (mesurée à la règle).
La distance est entrée dans la variable distance
Le microcontrôleur mesure la durée d'un A/R
Il affiche la valeur de la vitesse du son mesurée.
*/
int echo = 9;//Définition de la borne E/S Echo
int trig = 8;//Définition de la borne E/S de déclenchement
unsigned long temps;//Variable temps durée de l'écho
float Vson,tempsAR,distance=0.50; //Variable vitesse du son, durée de l'AR
//La valeur de la distance peut être modifiée en fonction de l'expérience
void setup() {
Serial.begin(9600);//Initialisation de la communication série
pinMode(echo, INPUT);//Déclaration de la borne Echo en ENTREE
pinMode(trig, OUTPUT);//Déclaration de la borne de déclenchement en SORTIE
digitalWrite(trig, 0);//Déclenchement à 0 -> pas de mesure
}
void loop() {
// put your main code here, to run repeatedly:
/*Envoi de l'impulsion déclenchant l'émission de la salve d'ultrasons
Il faut passer la borne Trig à l'état haut pendant 10 microsecondes
*/
digitalWrite(trig, 1);
delayMicroseconds(10);
digitalWrite(trig, 0);
//Fin de l'impulsion de déclenchement
temps = pulseIn(echo, 1, 30000);//On recueille la durée (en µs) de l'impulsion (un A/R)
tempsAR = float(temps); //la variable temps est un entier, on en fait un décimal (tempsAR) pour les calculs.
Vson = 2 * distance / (tempsAR / 1000000); //On calcule la vitesse du son (le temps est en µs)
//Affichage de la vitesse du son mesurée
Serial.print("V=");
Serial.print(Vson, 0);
Serial.println(" m/s");
delay(1000);//On effectue une mesure toutes les secondes
}
Exemple : Exemple de code à fournir aux élèves
Selon le niveau de maîtrise du langage, on peut fournir aux élèves un code à compléter plus ou moins lacunaire. À minima, on peut exiger d'eux qu'ils complètent la relation permettant de calculer la vitesse à partir de la distance et de la mesure de la durée de l'aller-retour.
Cela peut aussi être l'occasion de répéter plusieurs mesures et d'en faire une analyse statistique.
/*Principe du montage :
On place l'émetteur-récepteur US à une distance
connue d'un obstacle entre 30 cm et 2 m (mesurée à la règle).
Le microcontrôleur mesure la durée d'un A/R
Vous devez compléter la relation permettant de calculer la vitesse du son
*/
int echo = 9;//Définition de la borne E/S Echo
int trig = 8;//Définition de la borne E/S de déclenchement
unsigned long temps;//Variable temps durée de l'écho
float distance = 0.50, Vson, tempsAR; //Variable distance (ADAPTER À VOTRE EXPÉRIENCE), vitesse du son et temps de l'aller-retour
void setup() {
//****NE PAS MODIFIER CETTE SECTION****
Serial.begin(9600);
pinMode(echo, INPUT);//Déclaration de la borne Echo en ENTREE
pinMode(trig, OUTPUT);//Déclaration de la borne de déclenchement en SORTIE
digitalWrite(trig, 0);//Déclenchement à 0 -> pas de mesure
}
void loop() {
// put your main code here, to run repeatedly:
/*Envoi de l'impulsion déclenchant l'émission de la salve d'ultrasons
Il faut passer la borne Trig à l'état haut pendant 10 microsecondes
*/
digitalWrite(trig, 1);
delayMicroseconds(10);
digitalWrite(trig, 0);
//Fin de l'impulsion de déclenchement
temps = pulseIn(echo, 1, 30000);//On recueille la durée (en µs) de l'impulsion (un A/R)
tempsAR = float(temps); //la variable temps est un entier, on en fait un décimal (tempsAR) pour les calculs.
//****ENTREZ ICI LA RELATION PERMETTANT DE CALCULER Vson
//À PARTIR DE distance et tempsAR
Vson= Votre relation
//Affichage sur le moniteur série
Serial.print("V=");
Serial.print(Vson,0);
Serial.println("m/s");
delay(2000);//On effectue une mesure toutes les 2 secondes
}
Complément : Réglage de la distance capteur - obstacle à l'aide d'un potentiomètre et affichage sur écran LCD
Au lieu d'entrer la valeur de la distance manuellement dans le programme, l'utilisation du montage suivant permet de l'ajuster à l'aide d'un potentiomètre entre deux bornes définies dans le programme.
On gagne en souplesse d'utilisation pour effectuer des mesures en faisant varier la distance capteur - obstacle.
Il faut modifier le programme pour :
définir la valeur de la variable
distance
à l'aide du potentiomètre dont le curseur est relié à l'entrée analogique A0.afficher les résultats des mesures sur l'écran LCD.
/*Principe du montage :
On place l'émetteur-récepteur US à une distance
connue d'un obstacle entre 30 cm et 2 m (mesurée à la règle).
Le potentiomètre sert à la définir dans la variable
distance (contrôler sur l'écran LCD)
Le microcontrôleur mesure la durée d'un A/R
Il affiche la valeur de la vitesse du son mesurée.
*/
//Pour utiliser l'écran LCD I2C
int echo = 9;//Définition de la borne E/S Echo
int trig = 8;//Définition de la borne E/S de déclenchement
unsigned long temps;//Variable temps durée de l'écho
float Dmin, Dmax, distance, vSon, tempsAR; //Variable distance (bornes et distance capteur-obstacle), vitesse du son et temps de l'aller-retour
LiquidCrystal_I2C lcd(0x27, 20, 4);//Déclaration de l'écran LCD : adresse, nb colonnes, nb lignes
void setup() {
Dmin = 0.30; //Distance minimale Capteur-Obstacle
Dmax = 2.00; //Distance maximale Capteur-Obstacle
//Initialisation des réglages
lcd.init();//On initialise l'écran
lcd.backlight();//Rétroéclairage de l'écran
lcd.clear();//On efface l'écran
pinMode(echo, INPUT);//Déclaration de la borne Echo en ENTREE
pinMode(trig, OUTPUT);//Déclaration de la borne de déclenchement en SORTIE
digitalWrite(trig, 0);//Déclenchement à 0 -> pas de mesure
}
void loop() {
// put your main code here, to run repeatedly:
/*Ajustement de la distance à l'aide du potentiomètre
On envisage une distance entre Dmin et Dmax (peut être modifié dans la boucle setup())
*/
//Lecture de la distance (en m) ajustée à l'aide du potentiomètre
distance = Dmin + (analogRead(A0) / 1023.0 * (Dmax - Dmin));
/*Envoi de l'impulsion déclenchant l'émission de la salve d'ultrasons
Il faut passer la borne Trig à l'état haut pendant 10 microsecondes
*/
digitalWrite(trig, 1);
delayMicroseconds(10);
digitalWrite(trig, 0);
//Fin de l'impulsion de déclenchement
temps = pulseIn(echo, 1, 30000);//On recueille la durée (en µs) de l'impulsion (un A/R)
tempsAR = float(temps); //la variable temps est un entier, on en fait un décimal (tempsAR) pour les calculs.
vSon = 2 * distance / (tempsAR / 1000000); //On calcule la vitesse du son
//lcd.clear();
lcd.setCursor(0, 0);//Positionnement du curseur sur l'écran
lcd.print("D=");
lcd.print(distance, 3);
lcd.print(" m");
lcd.setCursor(0, 1);
if (temps == 0) {//Au-delà du délais défini, pulseIn renvoie la valeur 0 si pas d'écho
lcd.print("Pas d'echo");
delay(500);//On attend 0.5 seconde avant de faire la prochaine mesure
}
else {
//Affichage de la vitesse du son mesurée
lcd.print("V=");
lcd.print(vSon, 0);
lcd.print(" m/s");
delay(500);//On effectue une mesure toutes les 0.5 seconde
}
}