Arduino et Course de voiture / PB pour classement

Bonjour,
Je souhaite réaliser pour l’anniversaire de mon fils un “circuit” de petites voitures HotWheels.

Il marcherait de la manière suivante:
1/ 4 voitures au départ et chaque voiture est sur une piste différente.

2/ appuie sur un bouton qui déclenche un servomoteur et “lache” les voitures et déclenchement d’un chronomètre

3/ les voitures roulent vers l’arrivée.

4/ à l arrivée, chaque piste à une cellule photoélectrique qui permet 2 choses
→ afficher sur son digit 7 segment pour afficher la place de chaque piste (ex: voiture sur piste 2 a gagné, la voiture de la piste 4 est deuxième etc…); (chaque piste a son propre digit assigné)
→ arrêter le chronomètre. les temps de chaque voiture seraient afficher sur un écran qui afficherait ceci:
voiture 2 / WINNER / Temps
voiture 4 / 2 eme / Temps / Intervalle vs temps de la gagnante
etc…

5/ au bout de 10sec, la course est finie (que les 4 voitures soient arrivées ou pas), tout est remis a zero et le servomoteur reprend sa position pour un nouveau depart.

J ai déjà construit MECANIQUEMENT le système de départ (me reste a brancher et coder le servomoteur) → voir la photo.

Comme je suis débutant sur arduino (quelque souvenirs en C et C++ vieux de 20ans)… j ai regardé des Tutoriels et je construis mon circuit électronique et codage petit à petit.

J ai réussi a câbler et programmer 4 digits avec 4 cellules. J entends par là que quand je franchi une cellule, j affiche sur le digit le chiffre que j ai rentré. Je precise que les digits sont sur anode commune car Tinkercad met les cellules sur 0 par défaut. Quand j aurai fini, je prendrai a cathode commune et changerai les états HIGH et LOW.

Le challenge est que je n arrive pas à créer le code qui permettrait d afficher le classement des voitures.

Ci joint:

  • La ligne de départ.
  • mon schéma actuel avec 2 digits (anode commune car sur tinkercad les cellules sont par défaut à 0) et le code correspondant ci dessous

La question :
Comment savoir quelle est la voiture qui a franchi en premier la ligne ? d’un point de vue codage …je n’y arrive pas :frowning:

Pourriez vous m’aider?

/////////le code

/* affectation de la cellule*/
long cellPin1 = A0; /*cellule photo piste 1 sur broche analogique A0*/
long cellPin2 = A1; /*cellule photo piste 2 sur broche analogique A1*/
int capteurligne1; /* variable qui prendra l'etat de la cellule photoelectrique de la piste 1*
int capteurligne2; /* variable qui prendra l'etat de la cellule photoelectrique de la piste 2*/
/* affectation des ports de l'afficheur */
long ledPinA = 8;
long ledPinB = 9;
long ledPinC = 10;
long ledPinD = 2;
long ledPinE = 3;
long ledPinF = 5;
long ledPinG = 4;
long ledPinDP = 11;

/* branchements des digits sur les broches digitales*/
long d1 = 6; /* digit 1 sur broche 6*/
long d2 = 12;/* digit 1 sur broche 12*/
/* initialisation des sorties */
void setup()
  /* de la cellule */
  Serial.begin(9600); /* connection serie entre entrée analogique de la carte et le PC */
  pinMode (cellPin1, INPUT);
  pinMode (cellPin2, INPUT);
  /* de l'afficheur */
  pinMode (ledPinA, OUTPUT);
  pinMode (ledPinB, OUTPUT);
  pinMode (ledPinC, OUTPUT);
  pinMode (ledPinD, OUTPUT);
  pinMode (ledPinE, OUTPUT);
  pinMode (ledPinF, OUTPUT);
  pinMode (ledPinG, OUTPUT);
  pinMode (ledPinDP, OUTPUT);
  pinMode (d1, OUTPUT); 
  pinMode (d2, OUTPUT); 
}
void loop()
{
  capteurligne1 = digitalRead(cellPin1); /*lire valeur de la cellule piste 1 */
  Serial.println(capteurligne1); /* debug pour verifier  la valeur */
  if (capteurligne1==HIGH)
      {
    digitalWrite (d1, HIGH);
    afficherDigit1(); // donc on active le digit 1
     afficher_1(); // digit1 affiche la valeur 1, il faudrait afficher le classement
    delay(50);
     }
  capteurligne2 = digitalRead(cellPin2); /*lire valeur de la cellule piste 2*/
  Serial.println(capteurligne2); /* debug pour verifier  la valeur */
  if (capteurligne2==HIGH)
      {
    digitalWrite (d2, HIGH);
    afficherDigit2(); // donc on active le digit 2
     afficher_2(); // digit1 affiche la valeur 2, il faudrait afficher le classement
     delay(50);
     }
}
void afficherDigit1()
  {
  digitalWrite (d1, HIGH);
   digitalWrite (d2, LOW);
  } 
void afficherDigit2()
  {
   digitalWrite (d1,LOW);
  digitalWrite (d2, HIGH);
  } 

void afficher_1()
  {
  digitalWrite (ledPinA, HIGH);
  digitalWrite (ledPinB, LOW);
  digitalWrite (ledPinC, LOW);
  digitalWrite (ledPinD, HIGH);
  digitalWrite (ledPinE, HIGH);
  digitalWrite (ledPinF, HIGH);
  digitalWrite (ledPinG, HIGH);
  digitalWrite (ledPinDP, HIGH);
    }
void afficher_2()
   {
  digitalWrite (ledPinA, LOW);
  digitalWrite (ledPinB, LOW);
  digitalWrite (ledPinC, HIGH);
  digitalWrite (ledPinD, LOW);
  digitalWrite (ledPinE, LOW);
  digitalWrite (ledPinF, HIGH);
  digitalWrite (ledPinG, LOW);
  digitalWrite (ledPinDP, HIGH);
    }

[img width=416 height=500]https://forum.arduino.cc/index.php?action=dlattach;topic=733065.0;attach=409210[/img]

Bonjour

vois en tête du forum la manière de publier le code dans le corps d'un message (mise en forme et utilisation de balises appropriées)

oui mais la présence dans le code des balises couleur n'améliore pas sa lisibilité !

Désolé, j ai enlevé les balises de couleurs à présent.

Je vous remercie

Ci joint le schéma de câblage avec 2 afficheurs anode commune

Il y a plusieurs possibilités pour faire ça.
L'une d'elle serait de coder l'ordre d'arrivée dans un int.
Exemple : ordre d'arrivée d'abord la ligne 3 ensuite la 1 ensuite la 4 ensuite la 2. Code 3142.

Pour ça tu crées une variable globale

int ordre = 0;

puis à chaque fois qu'une voiture arrive tu fais :

ordre = ordre * 10 + numero;

numero est le numéro de la ligne qui arrive.
Ca donnerait un truc comme ça (à tester) :

int ordre = 0;
void loop()
{
  capteurligne1 = digitalRead(cellPin1); /*lire valeur de la cellule piste 1 */
  Serial.println(capteurligne1); /* debug pour verifier  la valeur */
  if (capteurligne1==HIGH)
      {
    ordre = ordre * 10 + 1;
    Serial.println(ordre);  /* debug pour verifier  la valeur */
    digitalWrite (d1, HIGH);
    afficherDigit1(); // donc on active le digit 1
     afficher_1(); // digit1 affiche la valeur 1, il faudrait afficher le classement
    delay(50);
     }
  capteurligne2 = digitalRead(cellPin2); /*lire valeur de la cellule piste 2*/
  Serial.println(capteurligne2); /* debug pour verifier  la valeur */
  if (capteurligne2==HIGH)
      {
   ordre = ordre * 10 + 2;
    Serial.println(ordre);  /* debug pour verifier  la valeur */

   digitalWrite (d2, HIGH);
    afficherDigit2(); // donc on active le digit 2
     afficher_2(); // digit1 affiche la valeur 2, il faudrait afficher le classement
     delay(50);
     }
}

Il te restera à utiliser cette variable comme tu veux.

Je vous remercie lepset!!!
L idée est excellente :relaxed:

Je vais la mettre en œuvre cet après midi et vous tiendrai au courant.

Aussi, concernant le déclenchement et l arrêt du chrono... faut il utiliser la fonction millis() ou avez vous une astuce ?

En effet, c’est avec millis() qu’il faut jouer.
Lorsque tu appuies sur le bouton pour libérer les voitures, il faut sauver le contenu de millis() dans une variable. On prend pour ça un unsigned long, en variable globale par exemple

Déclaration

unsigned long chrono;

Je ne vois pas la déclaration de ton bouton. Supposons qu’il soit déclaré en INPUT_PULLUP

pinmode(pinBouton, INPUT_PULLUP);

Lorsque le bouton est enfoncé, un digitalRead renvoie LOW. A ce moment tu sauves millis() dans ta variable :

if (digitalRead(pinBouton) == LOW) {
  chrono = millis();
  delay(20);  // pour attendre la fon des rebonds du bouton
}

Lorsque chaque voiture franchit la ligne d’arrivée, il te suffit de soustraire la valeur de chrono à millis() pour avoir le temps de parcours :

  if (capteurligne1==HIGH)
      {
    ordre = ordre * 10 + 1;
    Serial.println(ordre);  /* debug pour verifier  la valeur */
    duree1 = millis() - chrono;
    Serial.print("Temps voiture 1 : ");
    Serial.println(duree1);
    digitalWrite (d1, HIGH);
    afficherDigit1(); // donc on active le digit 1
     afficher_1(); // digit1 affiche la valeur 1, il faudrait afficher le classement
    delay(50);
     }

Il faut bien sûr avoir déclaré des variables globales :

unsigned long duree1, duree2, duree3, duree4;

J’ai bien réussi a créer la variable ordre…disons que le resultat est 4231 par exemple.

Comme j 'ai 4 afficheurs de 1 digit (1 au dessus de chaque ligne) et non 1 afficheur avec 4 digits, il faut que je decompose 4231, non?

J’ai crée une fonction classement pour découper 4231

void classement()
  { 
  premier = ordre/1000;
  deuxieme = (ordre/100)%10;
  troisieme = (ordre/10)%10;
  quatrieme = ordre%10;
  
  Serial.print ("premier:");
  Serial.println(premier);
  
  Serial.print ("deuxieme:");
  Serial.println(deuxieme);
    
  Serial.print ("troisieme:");
  Serial.println(troisieme);
  
  Serial.print ("quatrieme:");
  Serial.println(quatrieme);
  }

sauf que forcement sur Tinkercad…c’est chaud à faire avec loop qui tourne sans arrêt…la voiture 4 gagne se classe, 1ere, 2eme , 3eme et 4eme :frowning:

Désolé, je ne connais pas Tinkercad

déja, tu peux raccourcir ton code en utilisant des boucles.
Au lieu d’écrire 4 fois le même code en changeant les variables à chaque fois,

for ( piste=0, piste<4; piste ++ )

il faudra mettre les numéros de pins d1, d2 … dans un tableau d[4]

Par ailleurs, il y plein de delay() dans le code. Si un voiture passe la ligne pendant un delay(), le programme peut ne pas la voir ? Et si l’état de la cellule est persistant, le chronométrage sera qd même faussé.

Quand la voiture passe devant la cellule, celle-ce change d’état pendant “un certain temps”.
Comme ton programme tourne vite, il va donc voir l’état HIGH plusieurs (= de nombreuses) fois.
Par ex. il va t’envoyer des Serial.print() à tours de bras.
Il suffit d’avoir une variable (une par cellule), mise à Faux (ou 0) au début du programme, mise à Vrai (ou 1) des que la celluele passe à HIGH, et testée dans la condition :

bool celluleIsHIGH[4] = { false, false, false, false }

../...

capteurligne = digitalRead( d[piste] ); /*lire valeur de la cellule piste courante */
  Serial.println(capteurligne);
  if ( celluleIsHIGH[piste] == false && capteurligne == HIGH ) {
    celluleIsHIGH[piste] == true;
    // ON NE PASSERA Q'UNE SEULE FOIS ICI
    .../...
  }

Je vous remercie tous pour votre aide, c'est vraiment top!

Biggil --> je ne suis pas encore "facile" avec mes souvenirs de code...donc je code au niveau debutant...et ensuite j'optimiserai. Ton idée sera, bien entendu, reprise :wink:

Lesept --> je me suis débrouillé en creant 4 autres variables qui font une conditions pour rentrer dans les boucles de chaque photocell. A present, je vais tester la decomposition de "ordre" pour afficher sur le bon digit.

Bonjour,

Trop compliqué de partir sur l idée de Lesept qui promettait pourtant... le pb réside dans le cas où des voitures n arriveraient pas, alors je me retrouverais par exemple avec “4300” et faudrait faire donc des tests sur chaque éléments.

L autre solution serait juste de calculer les temps et de les comparer pour trouver la voiture gagnante... simple mais j ai envie de persister dans l idée de trouver le classement.

En ce sens, je vais prendre ton idée Bigill.

Je pense faire un tableau resultat d une ligne avec 4 colonne. Chaque colonne représente le numéro de voie (je ferai attention que la 1ère case est la case 0) et a l intérieur je mettrai le classement grâce à la fonction que tu m a donné.

Ca donnerait ceci par exemple: le classement de la voiture 4 est la valeur de la case 3 du tableau résultat.

Mon problème :
1/ comment créer la fonction dans le for qui va activer le digit voulu ? Digit[piste]
2/ afficher le nombre sur le digit : afficher

Je ne sais pas comment l écrire ... est ce de l syntaxe ou un appel à fonction avec un return... un pointeur de fonction?

Si quelqu un peut m aider ?

Pour traiter le cas où des voitures n’arrivent pas, il suffit de mettre un ‘timeout’ dans ton code.
Supposons que la course ne durera jamais plus de 30 secondes. On choisit donc un timeout de 30000ms.

Dans la loop, tu encapsules tout ton code de suivi des arrivées par un while avec une condition du genre :

millis() < timeout OU toutes les voitures ne sont pas arrivées

Lorsque la condition est fausse, tu passes à l’affichage des résultats.

Pour l’affichage, je pensais que tu l’avais fait :

J ai réussi a câbler et programmer 4 digits avec 4 cellules. J entends par là que quand je franchi une cellule, j affiche sur le digit le chiffre que j ai rentré. Je precise que les digits sont sur anode commune car Tinkercad met les cellules sur 0 par défaut. Quand j aurai fini, je prendrai a cathode commune et changerai les états HIGH et LOW.

Là pour t’aider il faudrait voir ton code…

Je te remercie lesept. J introduirai le sujet bouton et milles dès que j’en aurai terminé avec ce classement!!!

J ai repris l’idée de Bigill et je me suis “formé” aux appels de fonction avec variable.

Je dois mas écrire la syntaxe ou mal declarer le tableau mais “capteurligne” reste à 0 alors que j ai fait un serial.print sur capteurligne1 qui lui affiche bien “1” quand je touche ma cellule photo electrique

capteurligne = digitalRead(cellPin[piste]); 
capteurligne1 = digitalRead(cellPin1);

ci dessous tout le code que j’ai refait :frowning:

float resultat [4]= {0,0,0,0} ; // les places à l'arrivée de chaque piste seront enregistrees ici
char d[4]= {0,0,0,0} ; // tabmeau qui va servir à définir sur quelle broche on travaille
bool celluleIsHIGH[4] = { false, false, false, false }; // tableau qui va servir a mettre une condition dans la boucle for
bool cellule2IsHIGH[4] = { false, false, false, false };
float voie[4]= {1,2,3,4}; // tableau dont les valeurs sont les numeros des pistesfloat cellPin[4]= {cellPin1,cellPin2,cellPin3,cellPin4};
int cellPin[4]= {1,1,1,1};
int capteurligne;
int capteurligne1;
int ordre = 1;
int piste;

/* affectation de la cellule*/
long cellPin1 = A0; /*cellule photo piste 1 sur broche analogique A0*/
long cellPin2 = A1; /*cellule photo piste 2 sur broche analogique A1*/
long cellPin3 = A2; /*cellule photo piste 3 sur broche analogique A2*/
long cellPin4 = A3; /*cellule photo piste 4 sur broche analogique A3*/

long d1 = 6;  //digit 1 sur broche 6
long d2 = 12; // digit 2 sur broche 12
long d3 = 13; //digit 3 sur broche 13
long d4 = 7; //digit 4 sur broche 17

/* affectation des ports de l'afficheur */
long ledPinA = 8;
long ledPinB = 9;
long ledPinC = 10;
long ledPinD = 2;
long ledPinE = 3;
long ledPinF = 5;
long ledPinG = 4;
long ledPinDP = 11;


/* initialisation des sorties */
void setup()
{
  /* de la cellule */
  Serial.begin(9600); /* connection serie entre entrée analogique de la carte et le PC */  
  pinMode (cellPin1, INPUT);
  pinMode (cellPin2, INPUT);
  pinMode (cellPin3, INPUT);
  pinMode (cellPin4, INPUT);
  
  /* de l'afficheur */
  pinMode (ledPinA, OUTPUT);
  pinMode (ledPinB, OUTPUT);
  pinMode (ledPinC, OUTPUT);
  pinMode (ledPinD, OUTPUT);
  pinMode (ledPinE, OUTPUT);
  pinMode (ledPinF, OUTPUT);
  pinMode (ledPinG, OUTPUT);
  pinMode (ledPinDP, OUTPUT);
  pinMode (d1, OUTPUT); 
  pinMode (d2, OUTPUT);
  pinMode (d3, OUTPUT);
  pinMode (d4, OUTPUT);
}


void loop()
{
	// 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 */
		capteurligne = digitalRead(cellPin[piste]); //
        capteurligne1 = digitalRead(cellPin1);
		Serial.print("la valeur du capteur est:");      
		Serial.println(capteurligne); // on affiche sur le PC la valeur qui est sur la broche de la cellule photo electrique
      Serial.print("la valeur du capteur1 est:");      
		Serial.println(capteurligne1); // on affiche sur le PC la valeur qui est sur la broche de la cellule photo electrique


      if ( celluleIsHIGH[piste]==false && capteurligne==HIGH ) 
			{ // 	
        celluleIsHIGH[piste] == true; // permet de ne pas repasser par ici
			resultat[piste] = ordre; // on enregistre la place de la voie dans le tableau resultat
			ordre++ ; // on incremente ordre pour la prochaine boucle for          
          Serial.print("la voiture de la piste :");
           Serial.println(piste); // pour verifier 
           Serial.print("a terminé :");
          Serial.println(ordre); // pour verifier 
          
  			} // fin de la boucle if
		} /*fin de la boucle for*/
  	char j=0;
  	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
    	{ 
      if ( cellule2IsHIGH[j]) 
			{ 
    		celluleIsHIGH[piste] == true; // permet de ne pas repasser par ici
      	digitalWrite(d[j+1] ,HIGH); // on ecrit sur la broche d1,d2,d3 et d4
      	afficheur(voie[j]);
      	afficher(resultat[j]); // on appelle la fonction afficher qui enverra sur le 7segment la place à l'arrivé
         } 
    }   	
}// fin de loop

void afficheur(char chiffre)
  {
  if (chiffre =1)
   {
  digitalWrite (d1, HIGH);
  digitalWrite (d2, LOW);
  digitalWrite (d3, LOW);
  digitalWrite (d4, LOW);
  } 

if (chiffre =2)
  {
   digitalWrite (d1,LOW);
  digitalWrite (d2, HIGH);
  digitalWrite (d3, LOW);
  digitalWrite (d4, LOW);
  } 

if (chiffre =3)
  {
   digitalWrite (d1,LOW);
  digitalWrite (d2, LOW);
    digitalWrite (d3, HIGH);
  digitalWrite (d4, LOW);
  } 

if (chiffre =1)
  {
   digitalWrite (d1,LOW);
  digitalWrite (d2, LOW);
  digitalWrite (d3, LOW);
  digitalWrite (d4, HIGH);
  } 
} // fin void afficheur

void afficher(char chiffre)
  {
  if (chiffre =1) 
    {
    digitalWrite (ledPinA, HIGH);
    digitalWrite (ledPinB, LOW);
    digitalWrite (ledPinC, LOW);
    digitalWrite (ledPinD, HIGH);
    digitalWrite (ledPinE, HIGH);
    digitalWrite (ledPinF, HIGH);
    digitalWrite (ledPinG, HIGH);
    digitalWrite (ledPinDP, HIGH);
    }
  if (chiffre =2)
  	{
    digitalWrite (ledPinA, LOW);
    digitalWrite (ledPinB, LOW);
    digitalWrite (ledPinC, HIGH);
    digitalWrite (ledPinD, LOW);
    digitalWrite (ledPinE, LOW);
    digitalWrite (ledPinF, HIGH);
    digitalWrite (ledPinG, LOW);
    digitalWrite (ledPinDP, HIGH);
    }
  
   if (chiffre =3)
  {
  digitalWrite (ledPinA, LOW);
  digitalWrite (ledPinB, LOW);
  digitalWrite (ledPinC, LOW);
  digitalWrite (ledPinD, LOW);
  digitalWrite (ledPinE, HIGH);
  digitalWrite (ledPinF, HIGH);
  digitalWrite (ledPinG, LOW);
  digitalWrite (ledPinDP, HIGH);
    }
 if (chiffre =4)
  {
  digitalWrite (ledPinA, HIGH);
  digitalWrite (ledPinB, LOW);
  digitalWrite (ledPinC, LOW);
  digitalWrite (ledPinD, HIGH);
  digitalWrite (ledPinE, HIGH);
  digitalWrite (ledPinF, LOW);
  digitalWrite (ledPinG, LOW);
  digitalWrite (ledPinDP, HIGH);
}
  } // fin void afficher

Le test d'égalité c'est == pas simplement =

Tu n'as pas besoin de float ni de long, déclare tes variables en int, c'est suffisant

Je te propose une nouvelle version, plus compacte, avec des tableaux et une subtilité : j’ai changé ta façon de stocker les résultats : au lieu de

resultat[piste] = ordre;

j’ai mis :

resultat[ordre] = piste;

Comme ça le résultat stocke les pistes dans l’ordre d’arrivée : resultat[0] contient le numéro de la piste du gagnant, resultat[1] celui du suivant, etc.

Code (pas testé ni compilé, il y a peut-être des erreurs) :

int resultat [4] = {0, 0, 0, 0} ; // les places à l'arrivée de chaque piste seront enregistrees ici
char d[4] = {0, 0, 0, 0} ; // tableau qui va servir à définir sur quelle broche on travaille
bool celluleIsHIGH[4] = { false, false, false, false }; // tableau qui va servir a mettre une condition dans la boucle for
bool cellule2IsHIGH[4] = { false, false, false, false };
int voie[4] = {1, 2, 3, 4}; // tableau dont les valeurs sont les numeros des pistes
int cellPin[4] = {A0, A1, A2, A3}; /* affectation de la cellule*/
int capteurligne;
int ordre = 0;
int piste;


int d[4] = {6, 12, 13, 7};


/* affectation des ports de l'afficheur */
int ledPin[8] = {8, 9, 10, 2, 3, 5, 4, 11};


/* initialisation des sorties */
void setup()
{
  /* de la cellule */
  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);


  /* de l'afficheur */
  for (int i = 0; i < 8; i++) pinMode (ledPin[i], OUTPUT);


  pinMode (d[0], OUTPUT);
  pinMode (d[1], OUTPUT);
  pinMode (d[2], OUTPUT);
  pinMode (d[3], OUTPUT);
}




void loop()
{
  // 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 */
    capteurligne = digitalRead(cellPin[piste]); //
    Serial.print("la valeur du capteur est:");
    Serial.println(capteurligne); // on affiche sur le PC la valeur qui est sur la broche de la cellule photo electrique




    if ( celluleIsHIGH[piste] == false && capteurligne == HIGH )
    { //
      celluleIsHIGH[piste] == true; // permet de ne pas repasser par ici
      resultat[ordre] = piste; // on enregistre la place de la voie dans le tableau resultat
      ordre++ ; // on incremente ordre pour la prochaine boucle for
      Serial.print("la voiture de la piste :");
      Serial.println(piste); // pour verifier
      Serial.print("a terminé :");
      Serial.println(ordre); // pour verifier


    } // fin de la boucle if
  } /*fin de la boucle for*/


  if (ordre == 3) // 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 + 1] , HIGH); // on ecrit sur la broche d[0],d[1],d[2] et d[3]
      afficheur(j);
      afficher(resultat[j]); // on appelle la fonction afficher qui enverra sur le 7segment la place à l'arrivé
    }
  }
}// 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);
    digitalWrite (ledPin[1], LOW);
    digitalWrite (ledPin[2], LOW);
    digitalWrite (ledPin[3], HIGH);
    digitalWrite (ledPin[4], HIGH);
    digitalWrite (ledPin[5], LOW);
    digitalWrite (ledPin[6], LOW);
    digitalWrite (ledPin[7], HIGH);
  }
} // fin void afficher

Ne connaissant pas les subtilités de tes fonctions d’affichage, je n’ai pas vérifié si elles fonctionnent comme il faut.

Tu peux changer la fonction afficheur comme suit (plus compact) :

void afficheur(char chiffre)
{
  for (int i = 0; i < 4; i++) digitalWrite (d[i], LOW);
  digitalWrite (d[chiffre - 1], HIGH);
} // fin void afficheur

Pour la fonction afficher, on peut aussi compacter mais c’est un peu plus compliqué et demande d’utiliser des tableaux, donc pas besoin pour l’instant…

Bonjour lesept

J ai intégré le code et avec quelques modifs (des ; oubliés), le code compile.

Le logiciel de simulation me fait tourner en bourrique, desfois il lit bien cellpin et parfois pas du tout... du coup, capteurligne marche ou pas.

Je pense que je vais aller m acheter une carte et les composants et tout tester en direct.

Je vous tiens au courant. Merci et bon dimanche

Bonjour,

Je m’y suis remis a tete reposée.

Les quelques soucis qui se présentent sont (le fait de faire sous tinkercad peut sans doute générer les pb ci dessous?):

  • le classement est sans fin…elle ne s’arrête pas à piste <4.
  • Une meme voiture a plusieurs classement :frowning: comme si la condition “celluleIsHigh” ne remplissait pas son role
  • si je change que l’état d’une seule cellule (par exemple la voiture de la voie 4) et si son classement est 1ere, 2eme et 3eme (voir point 1) alors les 3 afficheurs affichent la valeur 3. Le digit de la voie 1 n’affichent pas la valeur 3 et c’est bien normal. En ce sens, ca prouve que les fonctions afficheur et afficher fonctionnent !!!
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
bool celluleIsHIGH[4] = { false, false, false, false }; // tableau qui va servir a mettre une condition dans la boucle for
int voie[4] = {1, 2, 3, 4}; // tableau dont les valeurs sont les numeros des pistes
int cellPin[4] = {A0, A1, A2, A3}; /* affectation de la cellule*/
int capteurligne;
int ordre=1;
int piste;
int d[4] = {6, 12, 13, 7}; 
int cellPin1 = A0;

/* affectation des ports de l'afficheur */
int ledPin[8] = {8, 9, 10, 2, 3, 5, 4, 11}; // tableau des segments de l'afficheur

int capteurligne1;

/* initialisation des sorties */
void setup()
{
  /* de la cellule */
  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
  /* de l'afficheur */
  for (int i = 0; i < 8; i++) {pinMode (ledPin[i], OUTPUT);}
  for (int i = 0; i < 4; i++) {pinMode (d[i], OUTPUT); }
}


void loop()
{
  // 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 */
    capteurligne = digitalRead(cellPin[piste]); // on affecte a la variable capteur l'etat de la broche de chaque cellule photo electrique
    if ( celluleIsHIGH[piste] == false && capteurligne == HIGH )
    { 
      celluleIsHIGH[piste] == true; // permet de ne pas repasser par ici
      resultat[piste] = ordre; // exemple la case 3 du tableau, correspondant a la voie 4 prend la valeur ordre, c'est a dire 1
      Serial.print("la voiture de la piste :");
      Serial.println(voie[piste]); // exemple la voiture de la piste 4
      Serial.print("a terminé :");
      Serial.println(ordre); // a terminer 1, soit premiere
      ordre++ ; // on incremente ordre pour la prochaine boucle for. exemple, ordre est egal a 2 a present
    } // fin de la boucle if
  } /*fin de la boucle for*/

  if (ordre == 4) // 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);
    }
  }
}// 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