Go Down

Topic: Mesurer une vitesse avec un capteur HC-SR 04 (Read 926 times) previous topic - next topic

al1fch

#15
Jan 31, 2019, 09:27 pm Last Edit: Jan 31, 2019, 09:29 pm by al1fch
Bonsoir

le HC-SR04 est une copie 'en moins bon'  (modifications du schéma dégradant les performances) du SFR04 du fabricant anglais  Devantec 

Ce dernier  (doc ici) recommande d'attendre 10mS après la fin de l'echo pour relancer TRIG


Alan46

Je pose la question.
A partir du moment où tu utilises un produit qui contient un microcontroleur dont tu ne connais rien, tu ne pourra faire que ce que le concepteur du programme inconnu a prévu que tu puisse faire.

Par exemple la datasheet du DHT22, qui contient un microcontroleur STM8, précise qu'il faut une pause d'une minute entre deux mesures. Parce que le traitement de l'humidité est long.

J'ai vu des exemples d'utilisation du HC-SR04 qui comportaient des pauses.
Ces pauses sont soit du confort visuel pour ne pas voir les mesures défiler trop vite, soit elles sont nécessaires car imposées par le programme interne.
Cela vaut la peine de se poser la question.

Comme cela vaut la peine d'acheter un HC-SR04 (1€ sur Ebay) et de tester la précision et la reproductibilité des mesures pour différentes distances parce que je ne sais pas si tu as remarqué le fournisseur ne propose strictement aucune documentation.

D'accord, encore merci pour tes réponses. Oui j'ai bien remarqué que le constructeur ne fournit aucune documentation. On trouve uniquement des documents provenant des sites d'achat.
En fait, il faudrait que les mesures s'affichent uniquement lorsque l'objet passe devant le capteur. Dans ce cas là je ne pense pas que les pauses soit une bonne idée car on ne sait pas à quel moment l'objet va arriver devant le capteur.

Alan46

Ce dernier recommande d'attendre 10mS après la fin de l'echo pour relancer TRIG

Le non respect de cette recommandation entraîne une mauvaise précision des mesures ?

al1fch

#18
Jan 31, 2019, 09:45 pm Last Edit: Jan 31, 2019, 10:45 pm by al1fch
probablement .
Il faudrait le schéma et le code du petit microcontrolleur pour le certifier

Au message #6 je disais de faire attention à l'effet doppler.
Soit on l'exploite ...soit il gêne..

A 16m/s le signal réfléchi arrivera vers 42 kHz
Vu la sélectivité de transducteurs récepteurs il apparaîtra comme un écho faible.... problème supplémentaire...

68tjs

Je ne me rappelai plus des infos d'Al1fch mais si tu trouve des SFR04 n'hésite pas a les acheter à la place du HC-SR04.
Pour le HC-SR04 ils se sont gourés sur le calcul du filtre et comme ils ne se sont pas remis en question ils ont ajouté une amplification de malade qui rend le système en limite d'instabilité.


al1fch

En relisant la description du fonctionnement du SFR04 on voit que les 10mS recommandés entre la fin de l'écho et la nouvelle salve sont liés à la remise en route du MAX232 (charge des condensateurs) éteint pendant la réception.
Le non respect de cette recommendations donnerait  des émissions de salves de  faible amplitude.

Alan46

Bonjour,

Après quelques jours de travail, j'ai commencé à coder ce que je voulais c'est à dire mesurer une vitesse avec un capteur HC-SR 04. Seulement, voilà, j'ai déjà le code pour la distance mais comment à partir de ce code je pourrais en sortir une vitesse ?

Code: [Select]

const byte TRIGGER = 12;
const byte ECHO = 13;   
 

const unsigned long MEASURE_TIMEOUT = 25000UL;


const float SOUND_SPEED = 340.0 / 1000;


void setup() {
   
 
  lcd.begin(16,2);
   
 
  pinMode(TRIGGER, OUTPUT);
  digitalWrite(TRIGGER, LOW);
  pinMode(ECHO, INPUT);
}
 
void loop() {
 
 
  digitalWrite(TRIGGER, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER, LOW);
 
 
  long measure = pulseIn(ECHO, HIGH, MEASURE_TIMEOUT);
   
 
  float distance_mm = measure / 2.0 * SOUND_SPEED;
   

 
  lcd.print(distance_mm);
  lcd.home();


J'ai effectué une expérimentation pour la distance, cela fonctionne. La précision est bonne de l'ordre de +/- 1 mm mais cela devient moins précis au delà de 20 cm de distance.

Merci de vos réponses.

lesept

La réponse est dans le message #4 de fdufnews
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Alan46

Bonjour,

J'ai essayé de retranscrire ce qu'avait dit fdufnews dans son message, en code. Voilà, ce que j'ai obtenu.

Code: [Select]
int pinTrig = 12; //reliée à la broche 2 de la carte
int pinEcho = 13; //reliée à la broche 3 de la carte
int vitesse1; //vitesse du véhicule de la première mesure
int vitesse2; //vitesse du véhicule de la deuxième mesure
int vitesseR; //vitesse réelle du véhicule
long deltat; //delta temps entre les mesures
long tempsUS1; //durée de l'impulsion aller retour en microsecondes
long tempsUS2; //durée de l'impulsion en microsecondes
long tempsS1; //durée de l'impulsion en secondes
long tempsS2; //durée de l'impulsion en secondes
long deltad; //delta distance entre les mesures
float distance1; //distance entre le capteur et le véhicule
float distance2;
float vson; //valeur de la vitesse du son

void setup() {
  vson=343,5;
  pinMode (pinTrig, OUTPUT); //configuration de TRIGGER en sortie, elle sera raccordée à l'entrée Trig du capteur.
  pinMode (pinEcho, INPUT); //configuration de ECHO en entrée, elle sera raccordée à la sortie Echo du capteur.

  digitalWrite(pinTrig,LOW); //elle est à 0 au démarrage.
  lcd.begin(16,2);
  lcd.createChar(0, smiley);
  lcd.createChar(1, emoji_mechant);
 
}

void loop() {
  vitesse1=millis();
  digitalWrite(pinTrig,HIGH); //trigger envoie une impulsion
  delayMicroseconds(10); //création d'une impulsion trigger de 10 us.
  digitalWrite(pinTrig,LOW); //impulsion terminée
 
  tempsUS1=pulseIn(pinEcho,HIGH); //mesure la durée de l'impulsion aller retour en microsecondes
  tempsS1=tempsUS1/1000/1000/2; //durée de l'impulsion en secondes
  distance1=vson*tempsS1; //formule pour calculer la distance entre le capteur et la voiture (en m)
  vitesse2=millis();
  digitalWrite(pinTrig,HIGH); //impulsion trigger
  delayMicroseconds(10); //impulsion trigger de 10us
  digitalWrite(pinTrig,LOW); //impulsion terminée
  tempsUS2=pulseIn(pinEcho,HIGH); //mesure la durée de l'impulsion aller retour
  tempsS2=tempsUS2/1000/1000/2; //durée de l'impulsion en secondes
  distance2=vson*tempsS2; //calcule la distance entre l'obstacle et le capteur (en m)
  deltat=tempsS1-tempsS2;
  deltad=distance1-distance2;
  vitesseR=((vitesse1-vitesse2)/deltat)*3,6; //vitesse réelle du véhicule en (en km/h)
 

Il y a semble t-il une erreur dans le calcul et dans la procédure de calcul de la vitesse car cela m'affiche toujours 3 km/h.
Merci de votre réponse.

fdufnews

#24
Mar 24, 2019, 09:27 am Last Edit: Mar 24, 2019, 09:29 am by fdufnews
En même temps, tu ne fais rien pour que ça marche  :smiley-evil: Il n'y a pas qu'une erreur.
Code: [Select]
vitesse1=millis();
moi, j'aurais plutôt appelé ça
Code: [Select]
temps1=millis();
Ensuite
Code: [Select]
  deltat=tempsS1-tempsS2;
  deltad=distance1-distance2;
  vitesseR=((vitesse1-vitesse2)/deltat)*3,6; //vitesse réelle du véhicule en (en km/h)
tu calcules un deltat, mais ce n'est pas le temps écoulé c'est la différence de durée des 2 impulsions du télémètre.
Tu calcules un deltad, mais tu ne l'utilises pas
Et tu fais le calcul avec vitesse1 - vitesse2, mais on a vu au-dessus que tu appelles vitesse le temps.

Tes pas loin de la solution mais on sent que c'est un peu la pagaille.
Je pense qu'il faudrait :
  • que tu poses calmement les choses sur le papier
  • que tu réfléchisses un peu
  • que tu donnes des noms clairs (et cohérent avec leur contenu) à tes variables

Alan46

J'ai essayé de suivre tes conseils, j'ai donc modifié le code :

Code: [Select]
tempsS1=millis();
  digitalWrite(pinTrig,HIGH); //trigger envoie une impulsion
  delayMicroseconds(10); //création d'une impulsion trigger de 10 us.
  digitalWrite(pinTrig,LOW); //impulsion terminée
 
  dureeM1=pulseIn(pinEcho,HIGH); //mesure la durée de l'impulsion aller retour en microsecondes
  dureeS1=dureeM1/1000/1000/2; //durée de l'impulsion en secondes
  distance1=vson*dureeS1; //formule pour calculer la distance entre le capteur et la voiture (en m)
  tempsS2=millis();
  digitalWrite(pinTrig,HIGH); //impulsion trigger
  delayMicroseconds(10); //impulsion trigger de 10us
  digitalWrite(pinTrig,LOW); //impulsion terminée
  dureeM2=pulseIn(pinEcho,HIGH); //mesure la durée de l'impulsion aller retour
  dureeS2=dureeM2/1000/1000/2; //durée de l'impulsion en secondes
  distance2=vson*dureeS2; //calcule la distance entre l'obstacle et le capteur (en m)
  vitesseR=((distance2-distance1)/(tempsS2-tempsS1))*3,6; //vitesse réelle du véhicule en (en km/h)


J'ai simulé, cela m'affiche 0 km/h donc déjà une valeur plus cohérente.
Merci pour vos conseils.

higgins91

Salut,
un petit conseil, rajout des traces sur la liaison série. 0 chaque calcul, tu affiche le résultat dans la console, cela te permet de vérifier qu'il n'y a pas une erreur (soit une variable, soit une opération erronée)
 

lesept

Si la vitesse affichée est nulle c'est que les distances mesurées sont égales. Ajoute un délai entre les deux mesures et fais varier sa longueur afin de voir à partir de combien tu commences à avoir une vitesse correcte.

Commence par exemple avec delay (20) puis change ce nombre pour améliorer ton résultat
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

fdufnews

En estimant la vitesse des véhicule sur lesquels on doit faire les mesures, il n'est pas très difficile par le calcul de déterminer une période de mesure en-dessous de laquelle les mesures ne seront pas pertinentes

Alan46

Bonjour, j'ai essayé vos conseils c'est à dire de faire varier la longueur entre le capteur et l'objet à mesurer. Aucun résultat positif, la valeur affichée reste nulle. Ensuite, j'ai rajouté un delay entre les deux mesures, je l'ai fait varier, mais la valeur affichée est nulle encore une fois. 
Alors je me suis posé la question, cela viendrait-il pas d'une mauvaise conversion ou d'une mauvaise unité ?

Car, pour information lorsque je souhaite mesurer une distance, cette dernière est affichée, elle est correcte et très précise. Le problème ne vient donc pas du capteur, mais bien du code pour afficher la vitesse.

Si cette solution n'aboutit pas, j'ai toujours la solution de rajouter un deuxième capteur à une distance d de l'autre et lancer une mesure sur les deux capteurs et à partir ce cela, j'obtiendrais un delta de temps et je pourrais enfin en déduire une vitesse.

Merci d'avance pour votre aide.

Go Up