Chronomètre + capteurs + calcul

Bonjour je vous met mon programme avec 4 capteur infrarouge, un chronomètre et un calcul, sa fonctionne le problème c'est que j'aimerai bien que quand l'une des deux barrière infrarouge affiche 0 le chronomètre se lance et quand l'autre barrière infrarouge affiche 0 le chronomètre s'arrête.

unsigned long MS;
unsigned long start;
  float x = 0.0001;
  float y = 0.111;
  float z = 0; 
  
void setup()
{
  Serial.begin (9600);     // Serial.begin (115200);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  start=millis();
}

void loop()
{
  Serial.print("Broche 2 : ");
  Serial.print(digitalRead(2));
  Serial.print("   ");
  Serial.print("Broche 6 : ");
  Serial.print(digitalRead(6)); 
  Serial.println();
    while (MS<8000) {
     MS = millis()-start;
  Serial.print ((MS / 1000) / 60);      // minutes
  Serial.print ("' ");
  Serial.print ((MS / 1000) % 60);      // secondes
  Serial.print ("'' ");
  Serial.println (MS % 1000);           // millièmes
  
}  
z = x / y;
  delay(200);
  Serial.println(z);
  }

qu'avez vous essayé?

c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

unsigned long MS;
unsigned long start;
  float x = 0.0001;
  float y = 0.111;
  float z = 0; 
  
void setup()
{
  Serial.begin (9600);     
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  start=millis();
}

void loop()
{
  Serial.print("Broche 2 : ");
  Serial.print(digitalRead(2));
  Serial.print("   ");
  Serial.print("Broche 6 : ");
  Serial.print(digitalRead(6)); 
  Serial.println();
  if (digitalRead(2) == 0) {
    
    while (digitalRead(6) ==HIGH){ 
     MS = millis()-start;
  Serial.print ((MS / 1000) / 60);      // minutes
  Serial.print ("' ");
  Serial.print ((MS / 1000) % 60);      // secondes
  Serial.print ("'' ");
  Serial.println (MS % 1000);           // millièmes
 }
  }
 else 
 {
z = x / y;
  delay(200);
  Serial.println(z);
}
}

Voila un programme que j'ai fais sa marche mais j'aimerai bien que le chronomètre se réinitialise chaque fois qu'il se stop

Je ferais un truc comme ça (régler la console sur 115200 baud) :

unsigned long MS;
unsigned long start;

void setup()
{
  Serial.begin (115200);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
}

void loop()
{
  while (digitalRead(2) == HIGH) {} // Attente du passage devant la première cellule
  start = millis();

  while (digitalRead(6) == HIGH) {} //  Attente du passage devant la seconde cellule
  MS = millis() - start;
  
  Serial.print ((MS / 1000) / 60);      // minutes
  Serial.print ("' ");
  Serial.print ((MS / 1000) % 60);      // secondes
  Serial.print ("'' ");  // <--- ça marche ça ? Sinon essayer Serial.print ("\'' "); 
  Serial.println (MS % 1000);           // millièmes
  
  delay(200); 
}

(pas compilé, pas testé)

Bonjour, votre programme fonction mais j'aimerai bien qu'on fois les 0 et les 1 des barrières infrarouge et qu'on vois le temps s’écouler, pas juste le temps quand le chronomètre s'arrête

je l'ai fusionné avec le mien, sa marche c'est juste le temps ne défile pas.

unsigned long MS;
unsigned long start;
  float x = 0.0001;
  float y = 0.111;
  float z = 0; 
  
void setup()
{
  Serial.begin (9600);     
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  start=millis();
}

void loop()
{
  Serial.print("Broche 2 : ");
  Serial.print(digitalRead(2));
  Serial.print("   ");
  Serial.print("Broche 6 : ");
  Serial.print(digitalRead(6)); 
  Serial.println();
  if (digitalRead(2) == 0) {
  while (digitalRead(2) == HIGH) {} // Attente du passage devant la première cellule
  start = millis();

  while (digitalRead(6) == HIGH) {} //  Attente du passage devant la seconde cellule
  MS = millis() - start;
 
  Serial.print ((MS / 1000) / 60);      // minutes
  Serial.print ("' ");
  Serial.print ((MS / 1000) % 60);      // secondes
  Serial.print ("'' ");
  Serial.println (MS % 1000);           // millièmes
 }
  
 else 
 {
z = x / y;
  delay(200);
  Serial.println(z);
}
}

juste le temps ne défile pas

ben oui puisque vous faites des attentes actives

while (digitalRead(2) == HIGH) {} // Attente du passage devant la première cellule
  start = millis();

  while (digitalRead(6) == HIGH) {} //  Attente du passage devant la seconde cellule
  MS = millis() - start;

Enfaite c'est bon dans mon cahier de charge je n'ai pas besoin que le temps défilent, merci beaucoup

Bon, je poste quand même ...

unsigned long start;
float x = 0.0001;
float y = 0.111;
float z = 0;

void setup()
{
  Serial.begin (9600);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  start = millis();
}

void loop()
{
  Serial.print("Broche 2 : ");
  Serial.print(digitalRead(2));
  Serial.print("   ");
  Serial.print("Broche 6 : ");
  Serial.print(digitalRead(6));
  Serial.println();
  if (digitalRead(2) == LOW) {  // Passage devant la première cellule 
    start = millis();  // Lancement du chrono
    while (digitalRead(6) == HIGH) { //  Attente du passage devant la seconde cellule
      unsigned long MS = millis() - start;
      if (MS%1000 == 0) AfficheTemps (MS); // Affichage toutes les secondes
    } 
    unsigned long MS = millis() - start;
    AfficheTemps (MS);  // Affichage du temps final
  }
  else
  {
    z = x / y;
    delay(200);  // Pourquoi ce délai ici ? Il peut faire louper un passage devant la première cellule
    Serial.println(z);
  }
}

void AfficheTemps (unsigned long MS) {
  Serial.print ((MS / 1000) / 60);      // minutes
  Serial.print ("' ");
  Serial.print ((MS / 1000) % 60);      // secondes
  Serial.print ("'' ");
  Serial.println (MS % 1000);           // millièmes
}

Le delay(200) à la fin me semble inopportun car il peut faire louper un passage devant la première cellule ou retarder le lancement du chrono. Je pense qu'il faut l'enlever. S'il est là uniquement pour ralentir l'affichage, il faut faire ça autrement...

Donc voila j'ai une autre question, donc comme vous avez peut être vu j'ai mis un calcul:
[/code] float x = 0.0001;
float y = 0.111;
float z = 0;
[/code]

z = x / y;
delay(200);
Serial.println(z);

donc la valeur 0.0001 correspond à la distance entre les 4 capteurs qui vaut 10 centimètre mais je devais le convertir en kilomètre, puis j'aimerai que le résultat du chronomètre qu'on obtiendra soit la valeur 'y' (qui actuellement est une valeur au puid) mais en heures, et qu'après avec obtenus le résultat j'aimerai qu'un premier calcul convertisse la minute en heure puis que le calcul z= x/y se lance

Merci beaucoup de votre programme je vais quand-même le prendre il est très utile.

Autant faire un calcul en mètres par secondes, qui sera plus précis, et ensuite le convertir en km/h en multipliant par 3.6

Aussi, il faut privilégier l'utilisation de noms de variables logiques, comme "distance", "vitesse", etc.

unsigned long start;
float distance = 0.1;
float vitesse = 0;

void setup()
{
  Serial.begin (9600);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  start = millis();
}

void loop()
{
  unsigned long MS;
  Serial.print("Broche 2 : ");
  Serial.print(digitalRead(2));
  Serial.print("   ");
  Serial.print("Broche 6 : ");
  Serial.print(digitalRead(6));
  Serial.println();
  if (digitalRead(2) == LOW) {  // Passage devant la première cellule 
    start = millis();  // Lancement du chrono
    while (digitalRead(6) == HIGH) { //  Attente du passage devant la seconde cellule
      MS = millis() - start;
      if (MS%1000 == 0) AfficheTemps (MS); // Affichage toutes les secondes
    } 
    MS = millis() - start;
    AfficheTemps (MS);  // Affichage du temps final
  }
  else
  {
    vitesse = distance / (float)(MS/1000);
    delay(200);  // Pourquoi ce délai ici ? Il peut faire louper un passage devant la première cellule
    Serial.print("Vitesse : ");
    Serial.print(vitesse*3.6);
    Serial.println(" km/h");
  }
}

void AfficheTemps (unsigned long MS) {
  Serial.print ((MS / 1000) / 60);      // minutes
  Serial.print ("' ");
  Serial.print ((MS / 1000) % 60);      // secondes
  Serial.print ("'' ");
  Serial.println (MS % 1000);           // millièmes
}

Attention, ça ne sert à rien d'afficher une vitesse tant que rien n'est passé entre les capteurs : il vaudrait mieux n'afficher la vitesse que si c'est pertinent. Donc autant afficher la vitesse quand MS est calculé :

unsigned long start = 0;
float distance = 0.1;
float vitesse = 0;

void setup()
{
  Serial.begin (9600);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
}

void loop()
{
  unsigned long MS;
  Serial.print("Broche 2 : ");
  Serial.print(digitalRead(2));
  Serial.print("   Broche 6 : ");
  Serial.print(digitalRead(6));
  Serial.println();
  
  if (digitalRead(2) == LOW) {  // Passage devant la première cellule
    start = millis();  // Lancement du chrono
    while (digitalRead(6) == HIGH) { //  Attente du passage devant la seconde cellule
      MS = millis() - start;
      if (MS % 1000 == 0) AfficheTemps (MS); // Affichage toutes les secondes
    }
    MS = millis() - start;
    AfficheTemps (MS);  // Affichage du temps final
    vitesse = distance / (float)(MS / 1000);
    Serial.print("Vitesse : ");
    Serial.print(vitesse * 3.6);
    Serial.println(" km/h");
    //      delay(200);  // Pourquoi ce délai ici ? Il peut faire louper un passage devant la première cellule
  }
}

void AfficheTemps (unsigned long MS) {
  Serial.print ((MS / 1000) / 60);      // minutes
  Serial.print ("' ");
  Serial.print ((MS / 1000) % 60);      // secondes
  Serial.print ("'' ");
  Serial.println (MS % 1000);           // millièmes
}

Bonjour, tout d'abord excuser moi de cette absence mais j'étais partis en sortie, je suis de retour maintenant, j'ai pu tester votre programme et il marche à merveille, merci infiniment.

Par contre pouvez vous juste m'expliquez plus précisément ce passage:

AfficheTemps (MS);  // Affichage du temps final
    vitesse = distance / (float)(MS / 1000);
    Serial.print("Vitesse : ");
    Serial.print(vitesse * 3.6);
    Serial.println(" km/h");

La première ligne appelle la fonction d'affichage du temps (minutes, secondes, millièmes) et les dernières affichent la vitesse

Entre les deux :

vitesse = distance / (float)(MS / 1000);

ça calcule la vitesse en forçant MS à passer provisoirement en float (ce n'est peut-être pas nécessaire, mais c'est plus sûr) pour faire une division avec tous les arguments de même type

En fait pouvez vous expliquez tout le programme parce-que vous avez fait quelque modification et je n'ai pas tout compris

unsigned long start = 0;
float distance = 0.1;
float vitesse = 0;

void setup()
{
  Serial.begin (9600);
  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
}

void loop()
{
  unsigned long MS;
  Serial.print("Broche 2 : ");
  Serial.print(digitalRead(2));
  Serial.print("   Broche 6 : ");
  Serial.print(digitalRead(6));
  Serial.println();
 
  if (digitalRead(2) == LOW) {  // Passage devant la première cellule
    start = millis();  // Lancement du chrono
    while (digitalRead(6) == HIGH) { //  Attente du passage devant la seconde cellule
      MS = millis() - start;
      if (MS % 1000 == 0) AfficheTemps (MS); // Affichage toutes les secondes
    }
    MS = millis() - start;
    AfficheTemps (MS);  // Affichage du temps final
    vitesse = distance / (float)(MS / 1000);
    Serial.print("Vitesse : ");
    Serial.print(vitesse * 3.6);
    Serial.println(" km/h");
    //      delay(200);  // Pourquoi ce délai ici ? Il peut faire louper un passage devant la première cellule
  }
}

void AfficheTemps (unsigned long MS) {
  Serial.print ((MS / 1000) / 60);      // minutes
  Serial.print ("' ");
  Serial.print ((MS / 1000) % 60);      // secondes
  Serial.print ("'' ");
  Serial.println (MS % 1000);           // millièmes
}

En sois je ne comprend pas ces lignes:

unsigned long start = 0;
float distance = 0.1;
float vitesse = 0;
unsigned long MS;
if (MS % 1000 == 0) AfficheTemps (MS);
void AfficheTemps (unsigned long MS) {

Mes réponses en rouge :

maxime676767:
En sois je ne comprend pas ces lignes:

unsigned long start = 0;

float distance = 0.1;
float vitesse = 0;



Ce sont des déclarations et initialisations de variables



unsigned long MS;



Déclaration d'une variable globale, ça évite de la passer en argument à des fonctions qui en ont besoin



if (MS % 1000 == 0) AfficheTemps (MS);



% est le calcul du reste de la division (fonction modulo). C'est pour afficher le temps uniquement chaque seconde plutôt qu'à chaque exécution de la loop



void AfficheTemps (unsigned long MS) {



C'est une fonction qui affiche le temps écoulé : ça évite de recopier les instructions plusieurs fois

merci déjà je comprends déjà mieux, et juste que veut dire ou qu'est ce que c'est que "Float"