Go Down

Topic: Compteur de temps entre deux mesures sur Arduino (Read 11364 times) previous topic - next topic

maxdata63

Bonjour,

Ayant eu un problème avec un radar doppler, je souhaite mesurer la vitesse d'un objet avec deux tête à ultrason. En gros, les deux radars sont espacées d'une distance de 30 centimètres et lorsqu' une objet passe devant, la distance captée par le premier va diminuer.
A partir de ce moment je souhaiterai qu'un compteur puisse compter le temps , jusqu'à ce que le deuxième capteur détecte l'objet et donc ensuite obtenir sa vitesse.

Je sais que delay ne va pas fonctionner et millis ne semble pas convenir non plus. Je sollicite donc votre aide pour résoudre ce problème.

Je précise que j'ai déjà le code des têtes à ultrasons et qu'il en me manque juste que cette boucle pour finir le programme.

Merci d'avance à ceux qui prendront de leur temps pour me répondre et bon week-end !

68tjs

Quelle valeur de temps tu veux mesurer ?
Valeur min =
Valeur max =
Précision demandée en s ou ms ou µs =

La solution se trouve dans les timers.
Notes qui delay() et millis() utilisent tout deux le timer 0 mais avec une configuration "arduino".
Il reste les autres timers qu'il est possible de configurer "aux petits oignons".

Mais avant il serait interressant que tu explique pourquoi millis() ne convient pas.

maxdata63

En fait je souhaite mesurer l'intervalle de temps entre la première détection et la deuxième en secondes ou ms.

Avec les timers je ne vois pas comment faire puisqu'ils ont le même effet que les delays

68tjs

Quote
Avec les timers je ne vois pas comment faire puisqu'ils ont le même effet que les delays
Non
Ce n'est pas une question de timer mais de comment la fonction delay() utilise le timer c'est totalement différent.

Pour voir la différence entre la fonction delay() et la fonction millis() regarde l'exemple "blink without delay".

J'avais posé la question :
Quote
Mais avant il serait interressant que tu explique pourquoi millis() ne convient pas.
Ce n'est pas tout à fait la réponse que j'attendais mais j'ai quand même la réponse indirrectement :

Quote
En fait je souhaite mesurer l'intervalle de temps entre la première détection et la deuxième en secondes ou ms.
Donc pas la peine de réinventer la roue la fonction millis() qui compte par incrément de 4µs et qui reboucle au bout de 40 jours convient parfaitement.

maxdata63

Voilà mon code
Code: [Select]
//**********************************************************
//  Capteur de distance à ultrasons HC-SR04 avec Arduino Uno
//  TipTopBoards.com  06 01 2014  Rolland
//  Càabler +5V et GND du détecteur sur l'arduino
//
// Trig -> pin 13
// Echo -> pin 12
// Led verte + 470R  -> pin 10
// Led rouge + 470R  -> pin 11
// Les leds s'allument selon la distance trop près / trop loin
//**********************************************************
#define trigPin 13  //Trig Ultrasons (sortie)
#define echoPin 12  //Echo Ultrasons (entrée)
#define echoPin2 11      //Led verte
#define trigPin2 10     //Led rouge

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);  //Trig est une sortie
  pinMode(echoPin, INPUT);   //Echo est le retour, en entrée
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, OUTPUT);
}

void loop() {
  long duration, distance, vitesse,duration2, distance2;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); //Trig déclenché 10ms sur HIGH
  digitalWrite(trigPin, LOW);
  digitalWrite(trigPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(10); //Trig déclenché 10ms sur HIGH
  digitalWrite(trigPin, LOW);
  // Calcul de l'écho2
  duration = pulseIn(echoPin, HIGH);
  // Distance proportionnelle à la durée de sortie
  distance = duration*340/(2*10000);
  duration2 = pulseIn(echoPin2, HIGH);
  // Distance proportionnelle à la durée de sortie
  distance2 = duration*340/(2*10000);
   
   
  if (distance < 5) {  // Distance trop près
   

 [color=red]Et à ce moment je voudrais lancer un timer


Ensuite , quand distance2 < 5 le timer s'arrete et me donne la valeur, puis le calcul la vitesse
Puis le timer revient à 0[/color]


Il me semble que millis va compter ça à partir du démarrage et ne va pas redémarrer non ?



  }
  delay(100);  //0.1 sec entre deux mesures
}

68tjs

Je me suis intéressé de près aux timers, j'essaye de partager les connaissances acquises mais j'ai assez de mal avec mon propre code pour rentrer dans celui des autres.

Si tu teste est-ce que cela fait ce que tu voulais ?
Si non explique ce qui ne convient pas il se trouvera toujours quelqu'un pour t'aider mais n'attend pas de nous qu'on teste à ta place.

maxdata63

Non c'est que je n'arrive pas à mettre en place le code. En utilisant TimerThree en librairie ça me met variable non déclarée quand je mets dans void loop
start(Timer3)

68tjs

Je ne comprend pas.
As tu chargé l'exemple blink without delay et regardé comment cela fonctionne avant de lancer des trucs bizarres.
Il n'y a aucune raison objective que millis() ne convienne pas à ton application.

infobarquee

bonjour,
moi ce que je verrai en code

détection du 1er capteur => distance1
distance11 = distance1
si distance1 < distance11 => distance11 = distance1  et temps1 =milli() // l'objet se rapproche toujours
si distance1 NULL => on lance le 2eme capteur

détection du 2eme capteur => distance2
distance22 = distance2
si distance2 < distance22 => distance22 = distance22  et temps2 =milli() // l'objet se rapproche toujours
si distance2 NULL => temps_différence = temps2 - temps1

calcul de la vitesse pour 30cm
AUCUNE AIDE PAR MP

maxdata63

Bonjour, j'ai essayé cette methode et voilà ce que ça me donne :
#define trigPin 12  //Trig Ultrasons (sortie)
#define echoPin 13  //Echo Ultrasons (entrée)
#define echoPin2 11      //Led verte
#define trigPin2 10     //Led rouge

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);  //Trig est une sortie
  pinMode(echoPin, INPUT);   //Echo est le retour, en entrée
  pinMode(echoPin2, INPUT);
  pinMode(trigPin2, OUTPUT);
}

void loop() {
  long duration, distance, duration2, second, vitesse;
  unsigned long temps,temps2,tempsf,tempsfinal;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); //Trig déclenché 10ms sur HIGH
  digitalWrite(trigPin, LOW);
 
  // Calcul de l'écho
  duration = pulseIn(echoPin, HIGH);
  // Distance proportionnelle à la durée de sortie
  distance = duration*340/(2*10000);  //Vitesse du son théorique

  delay(100);

 
 

  digitalWrite(trigPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(10); //Trig déclenché 10ms sur HIGH
  digitalWrite(trigPin2, LOW);
 
  // Calcul de l'écho
  duration2 = pulseIn(echoPin2, HIGH);
  // Distance proportionnelle à la durée de sortie
  second = duration2*340/(2*10000);  //Vitesse du son théorique

    if(distance<7){
    temps = millis();
  }
  if(second<7){
   temps2=millis();
   tempsf=temps2-temps;
   tempsfinal=pow(tempsf,-3);
   vitesse= 5/tempsf;
   Serial.print(tempsfinal);
   Serial.print("     ");
   Serial.print(vitesse);
   delay (1000);
  }
 
 
}



Le soucis c'est que mon tempsfinal est toujours aussi grand (non exposant -3 comme demandé)
et que la vitesse vaut zéro puisque 5/+l'infini ça n'a pas l'air de lui plaire.

Es-ce normal que millis me donne ça ?

maxdata63

Je vois. J'avais tenté d'utiliser millis comme mon professeur me le conseillait.

Si je ne passe par par millis, comment faire pour avoir le temps entre le passage devant le capteur 1 et le passage devant le capteur 2 ? Je précise que j'ai pu récupérer les cartes pour tester le programme.

le point (6) je voulais mettre cette valeur en 10^-3 pour avoir ensuite une vitesse en mètre par seconde.

Pour le point (7) il faudrait donc mettre float ?


en code de base pour que les deux capteurs donnent juste la distance , sans le calcul ni la temporisation j'ai ça :
 
Code: [Select]


#define trigPin 12  //Trig Ultrasons (sortie)
#define echoPin 13  //Echo Ultrasons (entrée)
#define echoPin2 11 //Echo2 Ultrasons (entrée2)
#define trigPin2 10 //Trig2 Ultrasons (sortie2)

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);  //Trig est une sortie
  pinMode(echoPin, INPUT);   //Echo est le retour, en entrée
  pinMode(echoPin2, INPUT);
  pinMode(trigPin2, OUTPUT);
}

void loop() {
  long duration, distance, duration2, second, vitesse;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); //Trig déclenché 10ms sur HIGH
  digitalWrite(trigPin, LOW);
 
  // Calcul de l'écho
  duration = pulseIn(echoPin, HIGH);
  // Distance proportionnelle à la durée de sortie
  distance = duration*340/(2*10000);  //Vitesse du son théorique

 

 
 

  digitalWrite(trigPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(10); //Trig déclenché 10ms sur HIGH
  digitalWrite(trigPin2, LOW);
 

 
  // Calcul de l'écho
  duration2 = pulseIn(echoPin2, HIGH);
  // Distance proportionnelle à la durée de sortie
  second = duration2*340/(2*10000);  //Vitesse du son théorique

  Serial.print(distance);
  Serial.print("cm");
  Serial.print("   ");
  Serial.print(second);
  Serial.print("cm");
  Serial.print("   ");
 
   
  delay(1000);


 
}


C'est vraiment la partie temporisation qui bloque. J'avais essayé avec les librairies timerOne mais ça n'avait pas fonctionné non plus...

En tout cas merci beaucoup de prendre du temps pour m'aider :)

maxdata63

Je souhaite effectivement lire millis quand la voiture passe devant le premier et quand elle passe devant le second et faire la différence des deux. C'est ce qui me semblait le plus simple.

Pourrais tu me monter juste cette partie en code pour comparer avec ce que je fais, histoire de voir le problème ?

Je vais donc utiliser float, et le problème des valeurs semble résolu donc.

Plus que le temps ^^

quand je fais temps2 - temps par rapport au premier code pour obtenier la différence, ça ne fonctionne pas correctement ?

Code: [Select]

  if(distance<7){
    temps = millis();
  }
  if(second<7){
   temps2=millis();
   tempsf=temps2-temps;

maxdata63

#12
Apr 17, 2016, 12:34 am Last Edit: Apr 17, 2016, 12:46 am by maxdata63
J'ai fait un schéma sous paint pour expliquer un peu le système et son fonctionnement, j'espère qu'il est compréhensible :




J'explique ce que je veux faire avec millis , et ainsi me dire si c'est bien possible avec cette fonction où si cela n'es pas adapté à mon système.

Cordialement,

BrUnO14200

Ton petit bout de code précêdent  avec les 2 if marche ?

Normalement oui même si perso j'ajouterais un flag dans le 2ième if qui vérifie qu'on est bien d'abord passé par le premier if ... En gros tu calcules ta vitesse quand tu est passé devant les 2 capteurs ;)

Envoie tes temps sur le moniteur série pour le débug si besoin !
Ma couveuse :https://forum.arduino.cc/index.php?topic=571843.0

maxdata63

Code: [Select]

En modifiant tout ça j'ai donc ceci :

code]if(distance < 7){
    temps = millis();
  }

  if(distance2 < 7){
    temps2= millis();
    vitesse= 30000/(temps2-temps);
  Serial.print(vitesse);
  Serial.print("m/s");
  Serial.print("  ");
  }
 


Je mesure donc désormais le temps si il passe en 1, puis plus tard si il passe en deux, donc plus en même temps.

Pour le calcul j'ai passé 3 à 30000micromètres et la vitesse est en float.

Je vois mes distance en serial print mais j'ai toujours ma vitesse à zéro :
   8cm   14cm   14cm   14cm   5cm   0.00m/s  <-- vitesse
     ^                                     ^
      l                                      l
passage devant 1                 passage devant 2

Go Up