Arduino et Course de voiture / PB pour classement

Je te propose une version un peu plus sécurisée :

int resultat [4] = {0, 0, 0, 0} ; // tableau des places a l arrivee. la case 0 correspond a la piste 1, la case 1 a la piste 2 et ainsi de suite
int ordre = 1;
int piste;
/* affectation des pins */
int ledPin[8] = {8, 9, 10, 2, 3, 5, 4, 11}; // tableau des segments de l'afficheur
int cellPin[4] = {A0, A1, A2, A3}; /* affectation de la cellule*/
int d[4] = {6, 12, 13, 7};

/* initialisation des sorties */
void setup()
{
  Serial.begin(9600); /* connection entre port série de la carte et le PC */
  for (int i = 0; i < 4; i++) pinMode (cellPin[i], INPUT); // les broches des cellules photo electriques sont des entrées
  for (int i = 0; i < 8; i++) pinMode (ledPin[i], OUTPUT);
  for (int i = 0; i < 4; i++) pinMode (d[i], OUTPUT);
}

void loop()
{
  if (ordre < 4) { // toutes les voitures ne sont pas arrivées
    // boucle for pour remplir le tableau resultat et affficher le classement sur le digit de chaque piste
    for (piste = 0 ; piste < 4 ; piste++) { /* debut de la boucle for */
      if ( resultat[piste] == 0) { // on ne lit que les pistes qui ne sont pas arrivées
        if (digitalRead(cellPin[piste]) == HIGH) { // si la voiture coupe la ligne d'arrivée
          resultat[piste] = ordre; 
          Serial.print("la voiture de la piste :"); Serial.println(piste);
          Serial.print("a terminé :"); Serial.println(ordre);
          ordre++ ; // on incremente ordre pour la prochaine boucle for
        } // fin de la boucle if
      }
    } /*fin de la boucle for*/

  } else { // Toutes les voitures sont arrivées
    for (int j = 0 ; j < 4 ; j++) { // ici, on va afficher le classement de la piste - on va aller chercher dans tableau la valeur la case 0 qui correspond a la voie 1
      digitalWrite(d[j] , HIGH); // on ecrit sur la broche d[0]=1,d[1]=2,d[2]=3 et d[3]=4
      afficheur(j + 1); // on active l afficheur 4 (exemple)
      afficher(resultat[j]); // exemple on va chercher la valeur enregistré dans la case 3 du tableau resultat soit 1
      delay(1000);
    } // end for
  } // end else
}// fin de loop


void afficheur(char chiffre)
{
  if (chiffre == 1)
  {
    digitalWrite (d[0], HIGH);
    digitalWrite (d[1], LOW);
    digitalWrite (d[2], LOW);
    digitalWrite (d[3], LOW);
  }


  if (chiffre == 2)
  {
    digitalWrite (d[0], LOW);
    digitalWrite (d[1], HIGH);
    digitalWrite (d[2], LOW);
    digitalWrite (d[3], LOW);
  }


  if (chiffre == 3)
  {
    digitalWrite (d[0], LOW);
    digitalWrite (d[1], LOW);
    digitalWrite (d[2], HIGH);
    digitalWrite (d[3], LOW);
  }


  if (chiffre == 4)
  {
    digitalWrite (d[0], LOW);
    digitalWrite (d[1], LOW);
    digitalWrite (d[2], LOW);
    digitalWrite (d[3], HIGH);
  }
} // fin void afficheur


void afficher(char chiffre)
{
  if (chiffre == 1)
  {
    digitalWrite (ledPin[0], HIGH);
    digitalWrite (ledPin[1], LOW);
    digitalWrite (ledPin[2], LOW);
    digitalWrite (ledPin[3], HIGH);
    digitalWrite (ledPin[4], HIGH);
    digitalWrite (ledPin[5], HIGH);
    digitalWrite (ledPin[6], HIGH);
    digitalWrite (ledPin[7], HIGH);
  }
  if (chiffre == 2)
  {
    digitalWrite (ledPin[0], LOW);
    digitalWrite (ledPin[1], LOW);
    digitalWrite (ledPin[2], HIGH);
    digitalWrite (ledPin[3], LOW);
    digitalWrite (ledPin[4], LOW);
    digitalWrite (ledPin[5], HIGH);
    digitalWrite (ledPin[6], LOW);
    digitalWrite (ledPin[7], HIGH);
  }


  if (chiffre == 3)
  {
    digitalWrite (ledPin[0], LOW);
    digitalWrite (ledPin[1], LOW);
    digitalWrite (ledPin[2], LOW);
    digitalWrite (ledPin[3], LOW);
    digitalWrite (ledPin[4], HIGH);
    digitalWrite (ledPin[5], HIGH);
    digitalWrite (ledPin[6], LOW);
    digitalWrite (ledPin[7], HIGH);
  }
  if (chiffre == 4)
  {
    digitalWrite (ledPin[0], HIGH); // A
    digitalWrite (ledPin[1], LOW); //B
    digitalWrite (ledPin[2], LOW); //C
    digitalWrite (ledPin[3], HIGH); //D
    digitalWrite (ledPin[4], HIGH); //E
    digitalWrite (ledPin[5], LOW); //F
    digitalWrite (ledPin[6], LOW); //G
    digitalWrite (ledPin[7], HIGH); //DP
  }
} // fin void afficher

hello
dans ton code, il y a ceci qui ne peut fonctionner: celluleIsHIGH[piste] == true;
il faut : celluleIsHIGH[piste] = true;
une autre version, attention j’ai changé l’implantation du hard

byte resultat [5]     = {0, 0, 0, 0, 0} ; // tableau des places a l arrivee. la case 0 correspond a la piste 1, la case 1 a la piste 2 et ainsi de suite
bool celluleIsHIGH[5] = { false, false, false, false, false }; // tableau qui va servir a mettre une condition dans la boucle for
byte voie[5]          = {0, 1, 2, 3, 4}; // tableau dont les valeurs sont les numeros des pistes
byte cellPin[5]       = {0, 2, 3, 4, 5}; /* affectation de la cellule*/
byte d[5]             = {0, 14, 15, 16, 17}; //digit 1, 2, 3, 4
byte capteurligne;
byte piste;
byte ordre = 1;

/* affectation des ports de l'afficheur */
int ledPin[8] = {6, 7, 8, 9, 10, 11, 12, 13}; // tableau des segments de l'afficheur

int capteurligne1;

/* initialisation des sorties */
void setup()
{
  /* de la cellule */
  Serial.begin(115200); /* connection entre port série de la carte et le PC */
  for (int i = 1; i < 5; i++) pinMode (cellPin[i], INPUT_PULLUP); // les broches des cellules photo electriques sont des entrées
  /* de l'afficheur */
  for (int i = 0; i < 8; i++) {pinMode (ledPin[i], OUTPUT);}
  for (int i = 1; i < 5; i++) {pinMode (d[i], OUTPUT);}
  digit=14;actionDigital(digit,1,1,1,0,1,1,1); // inscrit zéro sur le digit 1
  digit=15;actionDigital(digit,1,1,1,0,1,1,1); // inscrit zéro sur le digit 2
  digit=16;actionDigital(digit,1,1,1,0,1,1,1); // inscrit zéro sur le digit 3
  digit=17;actionDigital(digit,1,1,1,0,1,1,1); // inscrit zéro sur le digit 4
}


void loop()
{
  for (piste = 1 ; piste < 5 ; piste++)                         // scrute en boucle les cellules des pistes
  {
    capteurligne = digitalRead(cellPin[piste]);                  // lecture d'une cellule  2,  3,  4,  5
    //                        1,  2,  3,  4
    if (( celluleIsHIGH[piste] == false )&&(capteurligne == LOW ))  // si voiture passe devant cellule et pas dejà chronometrée
    {
      celluleIsHIGH[piste] = true;                               // on la memorise "chronometrée"
      resultat[piste] = ordre;                                   // on lui attribue sa place
      Serial.print("  la voiture de la piste : ");               //et on affiche le résultat sur le moniteur
      Serial.print(voie[piste]);
      Serial.print("  a terminé : ");
      Serial.println(ordre); Serial.flush();
      ordre++ ;                                                  // on incremente ordre pour la prochaine boucle for.
    } // fin de la boucle if
  } /*fin de la boucle for*/

  if (ordre == 5) // Toutes les voitures sont arrivées
  {
    for (int j = 1 ; j < 5 ; j++) // ici, on va afficher le classement de la piste sur les digits
    {
      aiguillage(d[j], resultat[j]);
    }
    /*
      for(byte f=1;f<5;f++)
      {
        Serial.print("la voiture de la piste : ");                  //et on affiche le résultat sur le moniteur
        Serial.print(voie[f]);
        Serial.print("  a terminé : ");
        Serial.println(resultat[f]);
      }
    */
    ordre = 1;
  }
}// fin de loop

void aiguillage(byte digit, byte valeur)
{ Serial.print (digit); Serial.print("  "); Serial.println(valeur);
  switch (valeur)
  {
    case 0://             A B C D E F G    //chiffre 0
      actionDigital(digit, 0, 0, 0, 1, 0, 0, 0);
      break ;
    case 1://             A B C D E F G    //chiffre 1
      actionDigital(digit, 0, 0, 1, 1, 1, 1, 1);
      break ;
    case 2://             A B C D E F G    //chiffre 2
      actionDigital(digit, 0, 0, 1, 0, 0, 1, 0);
      break ;
    case 3://             A B C D E F G    //chiffre 3
      actionDigital(digit, 0, 0, 0, 0, 1, 1, 0);
      break ;
    case 4://             A B C D E F G    //chiffre 4
      actionDigital(digit, 1, 0, 0, 1, 1, 0, 0);
      break ;
    default:
      break;
  }
}

//                                A        B         C          D           E        F        G
void actionDigital(byte digit, byte un, byte deux, byte trois, byte quatre, byte cinq, byte six, byte sept)
{
  digitalWrite(digit  , un);           //Segment A
  digitalWrite(digit + 1, deux);       //Segment B
  digitalWrite(digit + 2, trois);      //Segment C
  digitalWrite(digit + 3, quatre);     //Segment D
  digitalWrite(digit + 4, cinq);       //Segment E
  digitalWrite(digit + 5, six);        //Segment F
  digitalWrite(digit + 6, sept);       //Segment G
}

mince lesept…je n’ai pas d’emoji pour les applaudissements !!!

ca marche …mais la 4eme voiture qui franchie la ligne n’est pas enregistrée à cause du “ordre<4”.

void loop()
{
 if (ordre < 4) { // toutes les voitures ne sont pas arrivées

pour le moment…je laisse le code comme cela car le code permet quand meme d’afficher sur les digits le classement de chaque piste si 3 voitures franchissent l’arrivée.

Dans la pratique, si une voiture n’arrive pas, mon fils appuiera sur le bouton “course annulée” pour refaire une course.

Il ne me reste plus qu’à continuer pour créer mes autres fonctions (temps, le servo moteur, le bouton de déclenchement de course, le compte à rebours voire meme une photo finish).
en attendant … pour que tu puisses voir qui tu rends heureux …notre chaine YouTube pour les circuits hotwheels : LGX Express - YouTube
Lesept: tu y verras ton super code :slight_smile: (j ai mis ordre<=4 pour le moment)

Cool
On peut ajouter un timeout pour forcer l’affichage des résultats après un temps donné

Tu changes

if (ordre <= 4 && millis() < 30000ul)

Pour une durée de trente secondes.

Si tu ajoutes un bouton pour libérer les voitures, il faudra initialiser un chrono à ce moment

unsigned long chrono; // variable globale

Après l’action liée à l’appui sur le bouton :

chrono = millis();

Et le timeout deviendra :

if (ordre <= 4 && millis() - chrono < 30000ul)

dfgh:
hello
dans ton code, il y a ceci qui ne peut fonctionner: celluleIsHIGH[piste] == true;
il faut : celluleIsHIGH[piste] = true;
une autre version, attention j’ai changé l’implantation du hard

byte resultat [5]     = {0, 0, 0, 0, 0} ; // tableau des places a l arrivee. la case 0 correspond a la piste 1, la case 1 a la piste 2 et ainsi de suite

bool celluleIsHIGH[5] = { false, false, false, false, false }; // tableau qui va servir a mettre une condition dans la boucle for
byte voie[5]          = {0, 1, 2, 3, 4}; // tableau dont les valeurs sont les numeros des pistes
byte cellPin[5]       = {0, 2, 3, 4, 5}; /* affectation de la cellule*/
byte d[5]             = {0, 14, 15, 16, 17}; //digit 1, 2, 3, 4
byte capteurligne;
byte piste;
byte ordre = 1;

/* affectation des ports de l’afficheur */
int ledPin[8] = {6, 7, 8, 9, 10, 11, 12, 13}; // tableau des segments de l’afficheur

int capteurligne1;

/* initialisation des sorties /
void setup()
{
 /
de la cellule /
 Serial.begin(115200); /
connection entre port série de la carte et le PC /
 for (int i = 1; i < 5; i++) pinMode (cellPin[i], INPUT_PULLUP); // les broches des cellules photo electriques sont des entrées
 /
de l’afficheur */
 for (int i = 0; i < 8; i++) {pinMode (ledPin[i], OUTPUT);}
 for (int i = 1; i < 5; i++) {pinMode (d[i], OUTPUT);}
 digit=14;actionDigital(digit,1,1,1,0,1,1,1); // inscrit zéro sur le digit 1
 digit=15;actionDigital(digit,1,1,1,0,1,1,1); // inscrit zéro sur le digit 2
 digit=16;actionDigital(digit,1,1,1,0,1,1,1); // inscrit zéro sur le digit 3
 digit=17;actionDigital(digit,1,1,1,0,1,1,1); // inscrit zéro sur le digit 4
}

void loop()
{
 for (piste = 1 ; piste < 5 ; piste++)                         // scrute en boucle les cellules des pistes
 {
   capteurligne = digitalRead(cellPin[piste]);                  // lecture d’une cellule  2,  3,  4,  5
   //                        1,  2,  3,  4
   if (( celluleIsHIGH[piste] == false )&&(capteurligne == LOW ))  // si voiture passe devant cellule et pas dejà chronometrée
   {
     celluleIsHIGH[piste] = true;                               // on la memorise “chronometrée”
     resultat[piste] = ordre;                                   // on lui attribue sa place
     Serial.print("  la voiture de la piste : “);               //et on affiche le résultat sur le moniteur
     Serial.print(voie[piste]);
     Serial.print(”  a terminé : ");
     Serial.println(ordre); Serial.flush();
     ordre++ ;                                                  // on incremente ordre pour la prochaine boucle for.
   } // fin de la boucle if
 } /fin de la boucle for/

if (ordre == 5) // Toutes les voitures sont arrivées
 {
   for (int j = 1 ; j < 5 ; j++) // ici, on va afficher le classement de la piste sur les digits
   {
     aiguillage(d[j], resultat[j]);
   }
   /*
     for(byte f=1;f<5;f++)
     {
       Serial.print("la voiture de la piste : “);                  //et on affiche le résultat sur le moniteur
       Serial.print(voie[f]);
       Serial.print(”  a terminé : ");
       Serial.println(resultat[f]);
     }
   */
   ordre = 1;
 }
}// fin de loop

void aiguillage(byte digit, byte valeur)
{ Serial.print (digit); Serial.print("  "); Serial.println(valeur);
 switch (valeur)
 {
   case 0://             A B C D E F G    //chiffre 0
     actionDigital(digit, 0, 0, 0, 1, 0, 0, 0);
     break ;
   case 1://             A B C D E F G    //chiffre 1
     actionDigital(digit, 0, 0, 1, 1, 1, 1, 1);
     break ;
   case 2://             A B C D E F G    //chiffre 2
     actionDigital(digit, 0, 0, 1, 0, 0, 1, 0);
     break ;
   case 3://             A B C D E F G    //chiffre 3
     actionDigital(digit, 0, 0, 0, 0, 1, 1, 0);
     break ;
   case 4://             A B C D E F G    //chiffre 4
     actionDigital(digit, 1, 0, 0, 1, 1, 0, 0);
     break ;
   default:
     break;
 }
}

//                                A        B         C          D           E        F        G
void actionDigital(byte digit, byte un, byte deux, byte trois, byte quatre, byte cinq, byte six, byte sept)
{
 digitalWrite(digit  , un);           //Segment A
 digitalWrite(digit + 1, deux);       //Segment B
 digitalWrite(digit + 2, trois);      //Segment C
 digitalWrite(digit + 3, quatre);     //Segment D
 digitalWrite(digit + 4, cinq);       //Segment E
 digitalWrite(digit + 5, six);        //Segment F
 digitalWrite(digit + 6, sept);       //Segment G
}

Bonsoir dfgh,
je te remercie pour ton aide et surtout pour le “=” au lieu du “==”
j’ai changé mes broches pour coller à ton code mais…

  • le code ne compile pas car la variable digit n’était pas déclaré (référence aux déclarations quand digit=10 etc…). Du coup, j’ai crée une variable int digit; c’est ce qu il fallait faire?
  • pqoi faire des tableaux a 5 cases ? pour ne pas s’emmeler les pinceaux entre les numéros de cases et de pistes?

Allez j’ajoute mon grain de sel, je reprends le code de lesept et je code les afficheurs 7 segments dans un tableau.

int resultat [4] = {0, 0, 0, 0} ; // tableau des places a l arrivee. la case 0 correspond a la piste 1, la case 1 a la piste 2 et ainsi de suite
int ordre = 1;
int piste;
/* affectation des pins */
int ledPin[8] = {8, 9, 10, 2, 3, 5, 4, 11}; // tableau des segments de l'afficheur
int cellPin[4] = {A0, A1, A2, A3}; /* affectation de la cellule*/
int d[4] = {6, 12, 13, 7};
/* Codes affichage 7 segments */
byte code7segments [10][8] { // LOW = allumé
//  0     1     2     3     4     5     6      7
  {LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  HIGH},  // code 0
  {HIGH, LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH},  // code 1
  {LOW,  LOW,  HIGH, LOW,  LOW,  HIGH, LOW,  HIGH},  // code 2
  {LOW,  LOW,  LOW,  LOW,  HIGH, HIGH, LOW,  HIGH},  // code 3
  {HIGH, LOW,  LOW,  HIGH, HIGH, LOW,  LOW,  HIGH},  // code 4
  {LOW,  HIGH, LOW,  LOW,  HIGH, LOW,  LOW,  HIGH},  // code 5
  {LOW,  HIGH, LOW,  LOW,  LOW,  LOW,  HIGH, HIGH},  // code 6  
  {LOW,  LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH},  // code 7  
  {LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  HIGH},  // code 8  
  {LOW,  LOW,  LOW,  HIGH, HIGH, LOW,  LOW,  HIGH},  // code 9
} ;

/* initialisation des sorties */
void setup()
{
  Serial.begin(9600); /* connection entre port série de la carte et le PC */
  for (int i = 0; i < 4; i++) pinMode (cellPin[i], INPUT); // les broches des cellules photo electriques sont des entrées
  for (int i = 0; i < 8; i++) pinMode (ledPin[i], OUTPUT);
  for (int i = 0; i < 4; i++) pinMode (d[i], OUTPUT);
}

void tache1 () {
    // boucle for pour remplir le tableau resultat et affficher le classement sur le digit de chaque piste
    for (piste = 0 ; piste < 4 ; piste++) { /* debut de la boucle for */
      if ( resultat[piste] == 0) { // on ne lit que les pistes qui ne sont pas arrivées
        if (digitalRead(cellPin[piste]) == HIGH) { // si la voiture coupe la ligne d'arrivée
          resultat[piste] = ordre; 
          Serial.print("la voiture de la piste :"); Serial.println(piste);
          Serial.print("a terminé :"); Serial.println(ordre);
          ordre++ ; // on incremente ordre pour la prochaine boucle for
        } // fin de la boucle if
      }
    } /*fin de la boucle for*/  
}

void tache2 () {
    for (int j = 0 ; j < 4 ; j++) { // ici, on va afficher le classement de la piste - on va aller chercher dans tableau la valeur la case 0 qui correspond a la voie 1
      for (int i = 0 ; i < 4 ; i++) digitalWrite (d[i], i==j ? HIGH : LOW) ;  
      for (int segment = 0 ; segment <8 ; segment++)
        digitalWrite (ledPin [segment], code7segments [resultat[j]][segment]);
      delay(1000);
    } // end for
}

void loop()
{
  if (ordre < 4) tache1 () ;
  else tache2 () ;
}

hello, oui tu as bien fait de créer digit, en fait, j’ai ajouté ces lignes dans le setup apres avoir posté le code
pour les tableaux, pour un petit code, je prefere sacrifier la case zéro du tableau.
cela permet de coder piste 1 dans case 1 et pas dans case 0
c’est tres perso, je prefere plutot que d’avoir des" indice -1"
le sept t’ayant solutionné ton prob, j’ai hésité à te poster ma version, puis je me suis dit que voir plusieurs codes pour le meme résultat pouvait etre formateur

dfgh:
hello, oui tu as bien fait de créer digit, en fait, j'ai ajouté ces lignes dans le setup apres avoir posté le code
pour les tableaux, pour un petit code, je prefere sacrifier la case zéro du tableau.
cela permet de coder piste 1 dans case 1 et pas dans case 0
c'est tres perso, je prefere plutot que d'avoir des" indice -1"
le sept t'ayant solutionné ton prob, j'ai hésité à te poster ma version, puis je me suis dit que voir plusieurs codes pour le meme résultat pouvait etre formateur

Bonjour dfgh,
ok je comprends.
si je change les valeurs de tes tableaux pour que cela corresponde avec mes broches...ca ne marche pas:

  • est ce que c'est parce que la case0 du tableau "d" et celle de cellPin à pour valeur 0 ?
  • quand je lance le programme, la voiture 1 a fini première, la voiture 2 deuxième et ainsi de suite alors que je n ai meme pas changer l'état des cellules électrique ...pourtant, tes digits sont bien en anode...a moins que cela ne soit mes cellules photo qui soient montées à l'envers
  • les leds de digits ne font pas zéro au début `

je regarderai plus en detail.

je te remercie dans tous les cas :slight_smile:

JiPe38:
Allez j’ajoute mon grain de sel, je reprends le code de lesept et je code les afficheurs 7 segments dans un tableau.

int resultat [4] = {0, 0, 0, 0} ; // tableau des places a l arrivee. la case 0 correspond a la piste 1, la case 1 a la piste 2 et ainsi de suite

int ordre = 1;
int piste;
/* affectation des pins /
int ledPin[8] = {8, 9, 10, 2, 3, 5, 4, 11}; // tableau des segments de l’afficheur
int cellPin[4] = {A0, A1, A2, A3}; /
affectation de la cellule*/
int d[4] = {6, 12, 13, 7};
/* Codes affichage 7 segments */
byte code7segments [10][8] { // LOW = allumé
//  0     1     2     3     4     5     6      7
 {LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  HIGH},  // code 0
 {HIGH, LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH},  // code 1
 {LOW,  LOW,  HIGH, LOW,  LOW,  HIGH, LOW,  HIGH},  // code 2
 {LOW,  LOW,  LOW,  LOW,  HIGH, HIGH, LOW,  HIGH},  // code 3
 {HIGH, LOW,  LOW,  HIGH, HIGH, LOW,  LOW,  HIGH},  // code 4
 {LOW,  HIGH, LOW,  LOW,  HIGH, LOW,  LOW,  HIGH},  // code 5
 {LOW,  HIGH, LOW,  LOW,  LOW,  LOW,  HIGH, HIGH},  // code 6  
 {LOW,  LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH},  // code 7  
 {LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  HIGH},  // code 8  
 {LOW,  LOW,  LOW,  HIGH, HIGH, LOW,  LOW,  HIGH},  // code 9
} ;

/* initialisation des sorties /
void setup()
{
 Serial.begin(9600); /
connection entre port série de la carte et le PC */
 for (int i = 0; i < 4; i++) pinMode (cellPin[i], INPUT); // les broches des cellules photo electriques sont des entrées
 for (int i = 0; i < 8; i++) pinMode (ledPin[i], OUTPUT);
 for (int i = 0; i < 4; i++) pinMode (d[i], OUTPUT);
}

void tache1 () {
   // boucle for pour remplir le tableau resultat et affficher le classement sur le digit de chaque piste
   for (piste = 0 ; piste < 4 ; piste++) { /* debut de la boucle for */
     if ( resultat[piste] == 0) { // on ne lit que les pistes qui ne sont pas arrivées
       if (digitalRead(cellPin[piste]) == HIGH) { // si la voiture coupe la ligne d’arrivée
         resultat[piste] = ordre;
         Serial.print(“la voiture de la piste :”); Serial.println(piste);
         Serial.print(“a terminé :”); Serial.println(ordre);
         ordre++ ; // on incremente ordre pour la prochaine boucle for
       } // fin de la boucle if
     }
   } /fin de la boucle for/  
}

void tache2 () {
   for (int j = 0 ; j < 4 ; j++) { // ici, on va afficher le classement de la piste - on va aller chercher dans tableau la valeur la case 0 qui correspond a la voie 1
     for (int i = 0 ; i < 4 ; i++) digitalWrite (d[i], i==j ? HIGH : LOW) ;  
     for (int segment = 0 ; segment <8 ; segment++)
       digitalWrite (ledPin [segment], code7segments [resultat[j]][segment]);
     delay(1000);
   } // end for
}

void loop()
{
 if (ordre < 4) tache1 () ;
 else tache2 () ;
}

Bonjour Jipe38 !

ton grain de sel est le bienvenu et celui des autres aussi :slight_smile:

j’ai mis ton code et j’ai fait quelque modifications car sinon, le digit de la dernière voiture ne s’affichait pas (pb dans la boucle for au niveau de la case à prendre). bref…
cela donne cela :

int resultat [4] = {0, 0, 0, 0} ; // tableau des places a l arrivee. la case 0 correspond a la piste 1, la case 1 a la piste 2 et ainsi de suite
int ordre = 1;
int piste;
int voie[4] = {1,2,3,4};
/* affectation des pins */
int ledPin[8] = {8, 9, 10, 2, 3, 5, 4, 11}; // tableau des segments de l'afficheur
int cellPin[4] = {A0, A1, A2, A3}; /* affectation de la cellule*/
int d[4] = {6, 12, 13, 7};
/* Codes affichage 7 segments */
byte code7segments [10][8] { // LOW = allumé
//  0     1     2     3     4     5     6      7
  {LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  HIGH},  // code 0
  {HIGH, LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH},  // code 1
  {LOW,  LOW,  HIGH, LOW,  LOW,  HIGH, LOW,  HIGH},  // code 2
  {LOW,  LOW,  LOW,  LOW,  HIGH, HIGH, LOW,  HIGH},  // code 3
  {HIGH, LOW,  LOW,  HIGH, HIGH, LOW,  LOW,  HIGH},  // code 4
  {LOW,  HIGH, LOW,  LOW,  HIGH, LOW,  LOW,  HIGH},  // code 5
  {LOW,  HIGH, LOW,  LOW,  LOW,  LOW,  HIGH, HIGH},  // code 6  
  {LOW,  LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH},  // code 7  
  {LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  HIGH},  // code 8  
  {LOW,  LOW,  LOW,  HIGH, HIGH, LOW,  LOW,  HIGH},  // code 9
} ;

/* initialisation des sorties */
void setup()
{
  Serial.begin(9600); /* connection entre port série de la carte et le PC */
  for (int i = 0; i < 4; i++) pinMode (cellPin[i], INPUT); // les broches des cellules photo electriques sont des entrées
  for (int i = 0; i < 8; i++) pinMode (ledPin[i], OUTPUT);
  for (int i = 0; i < 4; i++) pinMode (d[i], OUTPUT);
}

void tache1 () {
    // boucle for pour remplir le tableau resultat et affficher le classement sur le digit de chaque piste
    for (piste = 0 ; piste < 4 ; piste++) { /* debut de la boucle for */
      if ( resultat[piste] == 0) { // on ne lit que les pistes qui ne sont pas arrivées
        if (digitalRead(cellPin[piste]) == HIGH) { // si la voiture coupe la ligne d'arrivée
          resultat[piste] = ordre; 
          Serial.print("la voiture de la piste :"); Serial.println(voie[piste]);
          Serial.print("a terminé :"); Serial.println(ordre);
          ordre++ ; // on incremente ordre pour la prochaine boucle for
        } // fin de la boucle if
      }
    } /*fin de la boucle for*/  
}

void tache2 () {
    for (int j = 0 ; j < 4 ; j++) { // ici, on va afficher le classement de la piste - on va aller chercher dans tableau la valeur la case 0 qui correspond a la voie 1
      for (int i = 0 ; i < 4 ; i++) digitalWrite (d[i], i==j ? HIGH : LOW) ;  
      for (int segment = 0 ; segment <8 ; segment++)
        digitalWrite (ledPin [segment], code7segments [resultat[j]][segment]);
      delay(50);
    } // end for
}

void loop()
{
  if (ordre <= 4) tache1 () ;
  else tache2 () ;
}

A present je vais créer le circuit avec mon bouton pour intégrer la fonction de chronométrage.

Bonjour,

je suis en train de faire les calculs d’intervalle de temps entre la voiture gagnante et les suivantes.

j’ai déclaré un tableau chronométré (temps de chaque voiture) et un tableau intervalle qui sera en charge d’enregistrer les intervalles de temps par rapport a la voiture gagnante

// tableau des temps de chaque voiture
unsigned long chronometre [4] = {0, 0, 0, 0} ;
unsigned long chrono;
// tableau qui va enregistrer les intervalle de temps par rapport a la voiture qui a franchie en premier la ligne
unsigned long intervalle [4] = {0, 0, 0, 0} ;
unsigned long meilleur_chrono=0;

dans la boucle for, j’enregistre le meilleur_chrono si ordre ==1 puis je veux faire une soustraction entre meilleur chrono et les autres chrono…

void Classement () {
    // boucle for pour remplir le tableau resultat et affficher le classement sur le digit de chaque piste
    for (piste = 0 ; piste < 4 ; piste++) { /* debut de la boucle for */
      if ( resultat[piste] == 0) { // on ne lit que les pistes qui ne sont pas arrivées
        if (digitalRead(cellPin[piste]) == HIGH) 
        	{ // si la voiture coupe la ligne d'arrivée
          	resultat[piste] = ordre; 
          	chronometre[piste] = millis() - chrono; // le chrono de chaque voiture est enregistre dans le tableau chronometre
          	if (ordre == 1) // on enregistre le meilleur temps
          		{
         		meilleur_chrono = chronometre[piste];
              	Serial.print("meilleur chrono :"); Serial.println(meilleur_chrono);
          		}
          	else 
           		{
         		intervalle[piste] = meilleur_chrono - chronometre[piste];
          		Serial.print("et la voiture suivante a fait un chrono de :"); Serial.println(chronometre[piste]);
          		Serial.print("et intervalle :"); Serial.println(intervalle[piste]);
            	}
          ordre++ ; // on incremente ordre pour la prochaine boucle for 
        	} // fin de la boucle if de digital read
      } // fin de if de resultat[piste]
    } /*fin de la boucle for*/  
} // fin de void classement

et ca donne cela…

meilleur chrono :891
et la voiture suivante a fait un chrono de :1163
et intervalle :4294967024
et la voiture suivante a fait un chrono de :1772
et intervalle :4294966415

Change simplement

Serial.println(intervalle[piste]);

par

Serial.println(chronometre[piste] - meilleur_chrono);

ou bien l'ordre de tes argument de la soustraction ici :

intervalle[piste] = meilleur_chrono - chronometre[piste];

après un peu d lecture de Tuto et forum, j'ai changé la déclaration des variables intervalle et meilleur chrono par:

// tableau des temps de chaque voiture
unsigned long chronometre [4] = {0, 0, 0, 0} ;
unsigned long chrono;
// tableau qui va enregistrer les intervalle de temps par rapport a la voiture qui a franchie en premier la ligne
int intervalle [4] = {0, 0, 0, 0} ;
int meilleur_chrono=0;

du coup, ca me donne quelque chose d plus digeste:

meilleur chrono :888
et la voiture suivante a fait un chrono de :1129
et intervalle :-241
et la voiture suivante a fait un chrono de :1337
et intervalle :-449
et la voiture suivante a fait un chrono de :1552
et intervalle :-664

le signe négatif est normal car j ai soustrait le plus petit temps aux plus grands :frowning:

mais est ce que ces valeurs sont de milli secondes ?

Oui, ce sont des millisecondes

Bonjour,

C’est encore moi :slight_smile:

Pour la “porte” de départ…il faudra appuyer sur un bouton qui déclenchera la rotation d’un servomoteur (pour “libérer” les voitures) et le chronomètre millis ().

Avec le code ci dessous, il faudrait que je maintienne mon doigt sur le bouton (pullup) jusqu’à la fin de la course.

if (etatBouton == LOW)// depart de la course equand on appuie sur le bouton
    { 
    Serial.print("l etat bouton vient de changer"); // c'est juste pour voir si le pullup marche
    chrono=millis(); // le depart de la course = variable chrono
    running = 1;
    delay(20);  // pour attendre la fin des rebonds du bouton
  	if (running == 1 && ordre <=4 && millis() <tpsMax) 
     	{
    	//Serial.print("je suis dans la boucle");// c'est juste pour voir si la condition bool marche
    	Classement ();
    	}

Y a t il un moyen d’enregistrer le fait d’avoir appuyer une fois sur le bouton ?

ci dessous tout le code

// si une voiture n'arrive pas, son digit reste eteint


// variable pour savoir si une course est en cours 
int running = 0;
// tableau des places a l arrivee. la case 0 correspond a la piste 1, la case 1 a la piste 2 et ainsi de suite
int resultat [4] = {0, 0, 0, 0} ; 

// tableau des temps de chaque voiture
unsigned long chronometre [4] = {0, 0, 0, 0} ;
unsigned long chrono;
// tableau qui va enregistrer les intervalle de temps par rapport a la voiture qui a franchie en premier la ligne
int intervalle [4] = {0, 0, 0, 0} ;
int meilleur_chrono=0;

// la premiere voiture qui franchira l'arrivée aura pour position ordre
int ordre = 1;
int piste;

// tableau dont les valeurs sont les numeros de voie
int voie[4] = {1,2,3,4};

// bouton pousoir 
int pinBouton=A4;
int etatBouton;

int j=0;

// variable pour la durée maximale de la course
int tpsMax = 20000ul;

/* affectation des pins */
int ledPin[8] = {8, 9, 10, 2, 3, 5, 4, 11}; // tableau des segments de l'afficheur
int cellPin[4] = {A0, A1, A2, A3}; /* affectation de la cellule*/
int d[4] = {6, 12, 13, 7};
/* Codes affichage 7 segments */
byte code7segments [10][8] { // LOW = allumé
//  0     1     2     3     4     5     6      7
  {HIGH,  HIGH,  HIGH,  HIGH,  HIGH,  HIGH,  HIGH,  HIGH},  // code 0 = ne rien n'afficher si une voiture n'est pas arrivée
  {HIGH, LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH},  // code 1
  {LOW,  LOW,  HIGH, LOW,  LOW,  HIGH, LOW,  HIGH},  // code 2
  {LOW,  LOW,  LOW,  LOW,  HIGH, HIGH, LOW,  HIGH},  // code 3
  {HIGH, LOW,  LOW,  HIGH, HIGH, LOW,  LOW,  HIGH},  // code 4
  {LOW,  HIGH, LOW,  LOW,  HIGH, LOW,  LOW,  HIGH},  // code 5
  {LOW,  HIGH, LOW,  LOW,  LOW,  LOW,  HIGH, HIGH},  // code 6  
  {LOW,  LOW,  LOW,  HIGH, HIGH, HIGH, HIGH, HIGH},  // code 7  
  {LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  LOW,  HIGH},  // code 8  
  {LOW,  LOW,  LOW,  HIGH, HIGH, LOW,  LOW,  HIGH},  // code 9
} ;



/* initialisation des sorties */
void setup()
{
  Serial.begin(9600); /* connection entre port série de la carte et le PC */
  pinMode(pinBouton,INPUT_PULLUP); // le bouton est pullup envoi 0 à la broche quand on appuie dessus
  for (int i = 0; i < 4; i++) pinMode (cellPin[i], INPUT); // les broches des cellules photo electriques sont des entrées
  for (int i = 0; i < 8; i++) pinMode (ledPin[i], OUTPUT);
  for (int i = 0; i < 4; i++) pinMode (d[i], OUTPUT);
}

void Classement () {
    // boucle for pour remplir le tableau resultat et affficher le classement sur le digit de chaque piste
    for (piste = 0 ; piste < 4 ; piste++) { /* debut de la boucle for */
      if ( resultat[piste] == 0) { // on ne lit que les pistes qui ne sont pas arrivées
        if (digitalRead(cellPin[piste]) == HIGH) 
        	{ // si la voiture coupe la ligne d'arrivée
          	resultat[piste] = ordre; 
          	chronometre[piste] = (millis() - chrono)/1000; // le chrono de chaque voiture est enregistre dans le tableau chronometre
          Serial.print("la voiture de la ligne:"); Serial.println(voie[piste]);	Serial.print("termine :"); Serial.println(resultat[piste]);
          if (ordre == 1) // on enregistre le meilleur temps
          		{
         		meilleur_chrono = chronometre[piste];
              	Serial.print("et realise le meilleur chrono en  :"); Serial.println(meilleur_chrono); 
          		}
          	else 
           		{
         		intervalle[piste] = chronometre[piste] - meilleur_chrono;
          		Serial.print("et realise un temps de:"); Serial.println(chronometre[piste]);
          		Serial.print("soit :"); Serial.println(intervalle[piste]);Serial.print("ms de plus que la gagnante");
            	}
          ordre++ ; // on incremente ordre pour la prochaine boucle for 
        	} // fin de la boucle if de digital read
      } // fin de if de resultat[piste]
    } /*fin de la boucle for*/  
} // fin de void classement

void afficherDigit () 
	{
	for (int j = 0 ; j < 4 ; j++) 
    	{ // ici, on va afficher le classement de la piste - on va aller chercher dans tableau la valeur la case 0 qui correspond a la voie 1
      	for (int i = 0 ; i < 4 ; i++) digitalWrite (d[i], i==j ? HIGH : LOW) ;  
      		for (int segment = 0 ; segment <8 ; segment++)
      			digitalWrite (ledPin [segment], code7segments [resultat[j]][segment]);
     	 		delay(50);
    } // end for
}

  

void loop()
{
  etatBouton= digitalRead(pinBouton);
  if (etatBouton == LOW)// depart de la course equand on appuie sur le bouton
    { 
    Serial.print("l etat bouton vient de changer"); // c'est juste pour voir si le pullup marche
    chrono=millis(); // le depart de la course = variable chrono
    running = 1;
    delay(20);  // pour attendre la fin des rebonds du bouton
  	if (running == 1 && ordre <=4 && millis() <tpsMax) 
     	{
    	//Serial.print("je suis dans la boucle");// c'est juste pour voir si la condition bool marche
    	Classement ();
    	}  
  }  
  else afficherDigit () ;
}

j'ai peut être trouvé quelque chose sur ce Tuto:

j'avais tenté d'enregistrer des états boolean ....je vais suivre cet exemple et le faire.

je vous tiens au courant

xavier38:
Y a t il un moyen d'enregistrer le fait d'avoir appuyer une fois sur le bouton ?

Oui, ça s'appele créer une variable :slight_smile:
que tu initialises à 0
que tu mets à 1 des que le bouton est appuyé.

C'est fou, non ?

Tant qu'à faire, déplace le delay() dans ton code parce que là:

  • tu lances le chrono
  • tu bloques 20 ms -> ça fausse le chrono

Je te remercie Bigill pour le sujet Delay mais je me suis mal exprimé concernant l'état du bouton.

Si j'arrête d'appuyer sur mon pullup, son état repasse à HIGH et donc je ne rentre plus dans ma boucle for.

L'idée est comme sur le Tuto, tant que je n'ai pas appuyé de nouveau sur mon pullup, ma variable reste à l'état précédent et donc pas besoin de maintenir un appui sur le bouton.

La petite différence avec le Tuto (où chaque appuie change l'état de la LED) est que passé un délais de course, tout se remet à zéro. Et si j'appui de nouveau sur le bouton, les voitures s'élancent.

Le code du tuto:

//Parameters
const int pinBouton  = A4; // pinBouton
const int ledPin = 13;

//Variables
int etatBouton  = 0;
bool btnState  = false;
bool oldbtnState  = false;
bool ledState  = LOW;


void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init btn
  pinMode(pinBouton, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}



void testPushBtn( ) 
{ /* function testPushBtn */
  ////Read pushbutton
  etatBouton = analogRead(pinBouton);
  if (etatBouton == LOW) 
  	{
    btnState = true;
    Serial.print("je suis ici");Serial.println(etatBouton);
  	} 
 else 
 	{
   	btnState = false;
  	}
  
 if (oldbtnState != btnState) 
 	{
    if(btnState==true)
    	{
        Serial.print(F("Button was pressed")); Serial.print(F("-->")); Serial.print(F("LED "));
        ledState = !ledState;
        Serial.println(ledState);
        digitalWrite(ledPin, ledState);
    	}
  	}
	oldbtnState = btnState;
}
void loop() {
  testPushBtn();
}

apparemment, j'avais un souci avec notre amie variable boolean >:(

Bonsoir,

J'ai bien galéré et je galère encore :frowning:

mes problèmes :
1a/ je voudrais mettre un bouton qui me permette de revenir a l'état initial (tant pendant la course qu'après celle ci )....mais j'ai essayé plein de chose et je ne trouve pas. Pour le moment, je l'ai fait avec la variable "RAZ"..j'ai pas mieux ....si vous pouvez me donner une piste a suivre?
2/ sans doute la conséquence de RAZ de la façon d avoir codé mais les digits disparaissent rapidement :frowning:
3/ je souhaiterais faire un compte a rebours avant que le servomoteur (pas encore réalisé) ne libère les voitures....auriez vous un Tuto a me recommander ou des pistes a me donner? idéalement il afficherait 3,2,1,0 et chaque chiffre sur un seul des 4 digits.
4/ je souhaiterais écrire des infos sur un écran OLED...je ne trouve pas de Tuto qui permette d'envoyer des variables dessus....seulement du texte

je vous remercie pour votre aide.

Pour relancer l'Arduino tu crées une fonction

void(* resetFunc) (void) = 0;

Et tu appelles cette fonction lorsque le bouton est enfoncé. Si tu as déclaré ton bouton en INPUT_PULLUP, il renvoie LOW dans ce cas
Il suffit de mettre ceci dans la loop

if (digitalRead (resetButton)==LOW) resetFunc ();

Pour le compte à rebours, il faut mettre ça dans le setup. Tu fais une boucle qui compte de 3 à 0 et qui affiche les chiffres sur ton afficheur avec un delay (1000); pour une temporisation d'une seconde. Il faudra en tenir compte si tu mesures les temps de tes voitures car millis démarre avant ce compte à rebours. Donc tes temps auront 3 secondes en trop.