optimiser la carte arduino

Bonjour @ ts,

Fin juillet je suis venu sur le forum pour essayer un 1er montage avec une carte Arduino pour notre club.

"decompte 60s pour départ de course"

Grâce @ "dfgh" et "lesept" j'ai pu arriver à ce que je voulais faire.

Du coup comme ce montage ne sert qu'au début de la course, je me suis dit: "pourquoi ne pas essayer d'optimiser cette carte et pourquoi pas lancer un deuxième programme une fois que le décompte est fini."
Je pensais mettre en place un système qui afficherait la vitesse de passage des voitures à un endroit bien précis.

Ma 1ère question est de savoir si je peux faire cela:
-démarrer mon décompte.
-une fois terminé démarrer le "compteur de vitesse" en utilisant les mêmes afficheurs.

Soit manuellement en commandant l'un ou l'autre des programmes pour boutons poussoirs, ou automatiquement une fois le décompte terminé.

Si cela est possible, ma deuxième question serait de savoir comment à partir de deux entrées de l'arduino, qui proviendraient de 2 contacts qui de déclenchent ( à une distance connue, je pensais à un mètre par exemple) au passage d'une voiture, calculer la vitesse et l'afficher sur mes deux afficheurs 7 segments (en binaire, puisque c'est ce que j'utilise pour le décompte).

J'allais oublier: la vitesse à afficher sera entre 00 et 99 km/h

Merci par avance pour vos réponses.

Cordialement,
Didier

Voici le code que j'ai pour le décompte (à titre d'info)

//BCD 1
const int hexa_A          = 4;
const int hexa_B          = 5;
const int hexa_C          = 6;
const int hexa_D          = 7;
//BCD 2
const int d_hexa_A          = 8;
const int d_hexa_B          = 9;
const int d_hexa_C          = 10;
const int d_hexa_D          = 11;

unsigned long chrono=0;

int n=60; //Setting initial value of n to 0
int d1;
int d2;
int bp = 2; //bouton poussoir
int state = 0;
int memo_state=0;
int ledVerte = 13;
int ledOrange1 = A1;
int ledOrange2 = A2;
int ledOrange3 = A3;
int ledRouge = 3;

void setup()
{ Serial.begin(250000);
  for(int f=3;f<=13;f++){pinMode(f,OUTPUT);}
  for(int g=1;g<=3;g++){pinMode(g,OUTPUT);}
  pinMode(bp,INPUT_PULLUP);//doit faire contact avec GND lorsqu'appuyé
  
}

void loop()
{       
 if (!digitalRead(bp))       //s'i y a eu un appui sur BP
 { delay(500);                //anti rebonds
 memo_state = !memo_state;  //appui mémorisé jusqu'à un nouvel appui qui annulera
 Serial.println(memo_state);
 }

 if(memo_state)            //ctrl si le BP à été appuyé
   {                        //oui, on va ajuster la boucle sur 1 seconde
 
   chrono=millis();        //on initialise le chrono pour la boucle
   n--;
    

 if(n>3)
 {  
   digitalWrite(ledRouge, HIGH); 
 }
if(n==3)
 {
 digitalWrite(ledRouge, LOW);
 digitalWrite(ledOrange1, HIGH);
 }
 if(n==2)
 {
 digitalWrite(ledOrange2, HIGH);
 }
 if(n==1)
 {
 digitalWrite(ledOrange3, HIGH);
 }
if(n==0)
 {
   digitalWrite(ledOrange1, LOW);
   digitalWrite(ledOrange2, LOW);
   digitalWrite(ledOrange3, LOW);
   digitalWrite(ledVerte, HIGH);
 }  
 if(n==-1)
   {
   n=60;
   memo_state = !memo_state; //on stoppe le decomptage
   delay(5000);
   digitalWrite(ledVerte, LOW);
   
   }
 d1=n%10; // This will divide n by 10 and the remainder will be stored in d1
 d2=n/10; // This will divide n by 10 and the value before decimal will be stored in d2
 gestion_afficheur(1,d1);
 gestion_afficheur(2,d2);Serial.println(n);
 while((millis()-chrono)<1000){;}//on ajuste la durée de la boucle pour 1 seconde
}

}
void gestion_afficheur(byte digit,int chiffre)
{
  switch (chiffre)
        { 
         case 0://             D C B A   //chiffre 0
           actionDigital(digit,0,0,0,0);
           break ;
         case 1://             D C B A   //chiffre 1
           actionDigital(digit,0,0,0,1);
           break ;
         case 2://             D C B A    //chiffre 2
           actionDigital(digit,0,0,1,0);
           break ;
         case 3://             D C B A    //chiffre 3
           actionDigital(digit,0,0,1,1);
           break ;
         case 4://             D C B A    //chiffre 4
           actionDigital(digit,0,1,0,0);
           break ;
         case 5://             D C B A    //chiffre 5
           actionDigital(digit,0,1,0,1);
           break ;                         
         case 6://             D C B A    //chiffre 6
           actionDigital(digit,0,1,1,0);
           break ;       
         case 7://             D C B A    //chiffre 7
           actionDigital(digit,0,1,1,1);
           break ;
         case 8://             D C B A    //chiffre 8
           actionDigital(digit,1,0,0,0);
           break ;
         case 9://             D C B A    //chiffre 9
           actionDigital(digit,1,0,0,1);
           break ;
         default:
         break;
       }
  }

   //                      D        C         B         A           
  void actionDigital(byte digit, byte un,byte deux,byte trois,byte quatre)
  {  if(digit==1){
     digitalWrite(hexa_D, un);           // D, est la pinoche 7
     digitalWrite(hexa_C, deux);         // C, est la pinoche 6
     digitalWrite(hexa_B, trois);        // B, est la pinoche 5
     digitalWrite(hexa_A, quatre);       // A, est la pinoche 4
     }
     else{
       if(digit==2){
     digitalWrite(hexa_D+4, un);         // D, est la pinoche 11
     digitalWrite(hexa_C+4, deux);       // C, est la pinoche 10
     digitalWrite(hexa_B+4, trois);      // B, est la pinoche 9
     digitalWrite(hexa_A+4, quatre);     // A, est la pinoche 8
     }
   }
 }

Salut
Oui, c'est possible. Lorsque le décompte est fini, tu vas scruter les contacts. Au premier contact tu déclenches un chrono que tu arrêtes au second contact. Tu as le temps mis par la voiture pour se déplacer sur la distance séparant les deux contacts. Il reste à diviser la distance par le temps pour calculer la vitesse. Rien de bien sorcier...
Pour l'afficheur ce sera un peu plus compliqué que dans ton programme précédent, mais guère plus.

Auras-tu des cas particuliers à gérer, comme deux voitures qui passent dans la zone de mesure de vitesse presque en même temps par exemple ?

Bonjour et merci pour ta réponse "lesept",

Pour faire le calcul de la vitesse ça je pense savoir le faire, mais ce qui est plus compliqué (voir inconnu pour moi -> débutant avec Arduino)) ce sera de le retranscrire en code Arduino.

Pour ce qui est du passage de deux voitures ce serait le top si je pouvais afficher les deux. Mais je pense que se sera impossible si elles sont l'une à côté de l'autre, par contre à étudier si elle se suivent. Je pense qu'il faut que la distance entre les deux contacts soit plus courte que la longueur des voitures. Elles font en gros entre 50 et 70cm de long. Du coup en mettant les contacts à 20cm (par exemple) ça devrait être jouable. Par contre faut savoir qu'elles ont une vitesse moyenne de 50km/h voir plus. En fait je ne sais pas trop -> d'où l'utilité de ce compteur de vitesse.
Je pense que ça va être chaud… Surtout quand elles sont pratiquement "b..e à "c.l" comme on dit chez nous…

Mais bon je ne suis pas pris par le temps pour réaliser ce projet. Je préfère avoir toutes les infos nécessaires (voir plusieurs solutions ) avant de faire quoi que ce soit.

En tout cas merci de t'intéresser à mon projet.

Amitiés,
@+

J'ai besoin de bien comprendre la configuration de la route, des voitures et des capteurs. Peux tu faire un schéma avec des cotes ? Et proposer un scénario standard d'utilisation ? Genre une voiture arrive à droite, une seconde à gauche un peu en arrière, d'une distance inférieure à la longueur des voitures, etc. Le "bitacu" me donne des soucis, de programmation je précise...

Bonjour,

Désolé si je revient tardivement mais pas mal de boulot autre que ce projet d'arduino.
Et merci de t'intéresser à mon projet.

Tout d'abord voici une vidéo qui peut te donner une idée des courses:

Vidéo de la piste

Des photos de là où je voudrai mettre mes capteurs et d'une voiture.
Comme tu peux le voir elles tournent toujours dans le même sens. Leur dimensions sont entre 80 et 90cm de longueur pour une moyenne de 50cm de largeur.

Pour l'emplacement des capteurs, ne te fies pas à la distance.

J'espère que tu pourras voir les photos (pas sur qu'elles apparaissent)

Si besoin d'autres infos, n'hésitent pas

@+
Didier

Jolie vidéo ! Merci, ça donne une idée plus claire du contexte.
Avant de se lancer dans quoi que ce soit, il faut se définir un minimum de cahier des charges.

  • Type de capteur : barrière infrarouge, tapis sensible à la pression des roues, LIDAR, RADAR, autre ?
  • Précision de la mesure ?
  • Nombre de voitures à chronométrer en même temps : ça influera sur le type du ou des capteurs. Si plusieurs voitures passent devant une barrière IR en même temps, la mesure sera faussée.
  • Portabilité : est-ce destiné à rester toujours (H24, J365) sur le même circuit ou faut-il prévoir de l'installer avant la course et l'enlever après ?
    D'autres questions à se poser ?

Bonjour,

le système doit-il aussi identifier les bolides lors de leurs passages ?

on avait déjà une question similaire, je crains que cela n'avait pas abouti ...

Bjr @ ts,

@ "lesept":
Pour les capteurs je pense plus à des barrières IR ou

ou encore

Jolis jambe :slight_smile: .
Pour un tapis je ne pense pas que ce soit possible car c'est une piste en terre et elle s’abime au fur et à mesure du passage des voitures. Après si quelqu'un à une autre solution pas chère, bien sur, on est prenant.

Pour la précision, on va dire le km/h. Je rappelle que je vais utiliser l'afficheur 2 digits du décompte de départ de course. Et les bolides ne dépassent pas le 100km/h, enfin pour l'instant, LOL.

Dans une course il y a au max 12 véhicules. Et pas besoin d'identifier les voitures, c'est juste indiquer sa vitesse au moment ou elles passent.
Ce qui répond à la question de "trimarco232"

Pour ce qui est de la portabilité, je pense qu'on laissera les capteurs sur place mais que le reste sera démontable afin de le monter pour la course et démonter à la fin (trop de risque de voir le matos disparaître). Pour ce qui est de cette partie, je pense pouvoir le gérer.

Pour tout ce qui est montage électronique (alim, circuit, coffret) je ne pense pas avoir de problème pour le réaliser. La où ça va coincer pour moi, ça va être la partie programme pour l'intégrer dans celui déjà existant.
Rappel du programme réalisé avec l'aide de "lesept" (encore merci).

//BCD 1
const int hexa_A          = 4;
const int hexa_B          = 5;
const int hexa_C          = 6;
const int hexa_D          = 7;
//BCD 2
const int d_hexa_A          = 8;
const int d_hexa_B          = 9;
const int d_hexa_C          = 10;
const int d_hexa_D          = 11;

unsigned long chrono=0;

int n=60; //Setting initial value of n to 0
int d1;
int d2;
int bp = 2; //bouton poussoir
int state = 0;
int memo_state=0;
int ledVerte = 13;
int ledOrange1 = A1;
int ledOrange2 = A2;
int ledOrange3 = A3;
int ledRouge = 3;

void setup()
{ Serial.begin(250000);
  for(int f=3;f<=13;f++){pinMode(f,OUTPUT);}
  for(int g=1;g<=3;g++){pinMode(g,OUTPUT);}
  pinMode(bp,INPUT_PULLUP);//doit faire contact avec GND lorsqu'appuyé
 
}

void loop()
{       
 if (!digitalRead(bp))       //s'i y a eu un appui sur BP
 { delay(500);                //anti rebonds
 memo_state = !memo_state;  //appui mémorisé jusqu'à un nouvel appui qui annulera
 Serial.println(memo_state);
 }

 if(memo_state)            //ctrl si le BP à été appuyé
   {                        //oui, on va ajuster la boucle sur 1 seconde
 
   chrono=millis();        //on initialise le chrono pour la boucle
   n--;
   

 if(n>3)
 { 
   digitalWrite(ledRouge, HIGH);
 }
if(n==3)
 {
 digitalWrite(ledRouge, LOW);
 digitalWrite(ledOrange1, HIGH);
 }
 if(n==2)
 {
 digitalWrite(ledOrange2, HIGH);
 }
 if(n==1)
 {
 digitalWrite(ledOrange3, HIGH);
 }
if(n==0)
 {
   digitalWrite(ledOrange1, LOW);
   digitalWrite(ledOrange2, LOW);
   digitalWrite(ledOrange3, LOW);
   digitalWrite(ledVerte, HIGH);
 } 
 if(n==-1)
   {
   n=60;
   memo_state = !memo_state; //on stoppe le decomptage
   delay(15000);
   digitalWrite(ledVerte, LOW);
   
   }
 d1=n%10; // This will divide n by 10 and the remainder will be stored in d1
 d2=n/10; // This will divide n by 10 and the value before decimal will be stored in d2
 gestion_afficheur(1,d1);
 gestion_afficheur(2,d2);Serial.println(n);
 while((millis()-chrono)<1000){;}//on ajuste la durée de la boucle pour 1 seconde
}

}
void gestion_afficheur(byte digit,int chiffre)
{
  switch (chiffre)
        {
         case 0://             D C B A   //chiffre 0
           actionDigital(digit,0,0,0,0);
           break ;
         case 1://             D C B A   //chiffre 1
           actionDigital(digit,0,0,0,1);
           break ;
         case 2://             D C B A    //chiffre 2
           actionDigital(digit,0,0,1,0);
           break ;
         case 3://             D C B A    //chiffre 3
           actionDigital(digit,0,0,1,1);
           break ;
         case 4://             D C B A    //chiffre 4
           actionDigital(digit,0,1,0,0);
           break ;
         case 5://             D C B A    //chiffre 5
           actionDigital(digit,0,1,0,1);
           break ;                         
         case 6://             D C B A    //chiffre 6
           actionDigital(digit,0,1,1,0);
           break ;       
         case 7://             D C B A    //chiffre 7
           actionDigital(digit,0,1,1,1);
           break ;
         case 8://             D C B A    //chiffre 8
           actionDigital(digit,1,0,0,0);
           break ;
         case 9://             D C B A    //chiffre 9
           actionDigital(digit,1,0,0,1);
           break ;
         default:
         break;
       }
  }

   //                      D        C         B         A           
  void actionDigital(byte digit, byte un,byte deux,byte trois,byte quatre)
  {  if(digit==1){
     digitalWrite(hexa_D, un);           // D, est la pinoche 7
     digitalWrite(hexa_C, deux);         // C, est la pinoche 6
     digitalWrite(hexa_B, trois);        // B, est la pinoche 5
     digitalWrite(hexa_A, quatre);       // A, est la pinoche 4
     }
     else{
       if(digit==2){
     digitalWrite(hexa_D+4, un);         // D, est la pinoche 11
     digitalWrite(hexa_C+4, deux);       // C, est la pinoche 10
     digitalWrite(hexa_B+4, trois);      // B, est la pinoche 9
     digitalWrite(hexa_A+4, quatre);     // A, est la pinoche 8
     }
   }
 }

Petite question:
Comment mettre une photo de mon pc, svp?
Quand je clic sur l’icône de "image+" -> insert a image, ça me demande une URL. Sur d'autre forum en général ça demande d'aller sélectionner ton image pour la charger.

Amitiés et @+

Hello
Dans le setup du code COMPTEUR, les indices des boocles FOR se recouvrent.
Une boucle commence avec g=1 ??? Tu utilises le Serial.
Une seule boucle pourrait remplacer les deux.

Pour compléter la réponse de dfgh : tu utilises des pins pour ton afficheur : ces pins vont de 4 à 11

//BCD 1
const int hexa_A          = 4;
const int hexa_B          = 5;
const int hexa_C          = 6;
const int hexa_D          = 7;
//BCD 2
const int d_hexa_A          = 8;
const int d_hexa_B          = 9;
const int d_hexa_C          = 10;
const int d_hexa_D          = 11;

Tu n'as donc pas besoin de toutes ces définitions dans le setup, mais simplement des 4 à 11

void setup()
{ Serial.begin(250000);
  for(int f=4;f<=11;f++){pinMode(f,OUTPUT);}
  pinMode(bp,INPUT_PULLUP);//doit faire contact avec GND lorsqu'appuyé
}

Les pins 0 et 1 sont réservées à la liaison série avec le PC, si tu t'en sers. Or c'est le cas, puisque tu utilises Serial.print. Donc, ne pas utiliser ces pins dans le code pour autre chose.

Bjr @ Ts,

Merci encore pour ces infos à tous les deux.

Je pense que j'ai du mélanger plusieurs codes et c'est pour cela que la liaison série est active alors que je ne m'en sert pas dans le montage.
A moins que cela soit indispensable dans le code.

Pour revenir à mon montage de compteur de vitesse, comme je l'ai dit plus haut, pas besoin de savoir à qui est la voiture. Pour les courses on a un logiciel spécial pour ça. Chaque voiture a une puce numérotée et lorsque qu'elle passe sur une boucle de cuivre elle est identifiée et on peut savoir avec un logiciel son temps au tour, sa position par rapport au autre, etc...

Ce qui me préoccupe c'est de savoir comment retranscrire mon temps de passage en vitesse.

@+
Didier

Salut Didier
As-tu avancé dans ton projet ?

Pour mettre une image, soit tu connais son URL et tu utilise le bouton "Insert an image" dans la fenêtre d'écriture des messages. Si c'est une image de ton PC, tu dois le faire en deux temps : d'abord tu uploades le fichier sur le forum (attachments and other options) et tu publies le message. Ensuite, tu copies l'adresse de ton image qui apparaît en lien lorsque tu affiches ton message. Tu édites le message est tu fais comme pour le premier cas.
Tout ça est décrit dans les messages épinglés en haut du forum Français.

Pour calculer la vitesse, tu dois mesurer le temps T que met la voiture entre les deux capteurs,séparés d'une distance D que tu connais puisque tu les as installés toi-même. La vitesse est le rapport de la distance sur le temps de parcours :

float vitesse = D/T;

Si tu mesures T avec la fonction millis(), tu l'auras en millisecondes. Ta distance étant a priori en mètres, si tu veux la vitesse en km/h, il faut faire :

float vitesse = 3.6*D/(T/1000.0);

Bsr "lesept"

Pour ce qui est du projet, pour l'instant c'est en stand-by, je veux finir le montage de mon décompte et j'ai aussi pas mal de boulot à la maison.

Du coup je vais essayer de mettre une image avec tes explications…

en prévisualisation j'ai un message d'erreur qui me dit que je ne peux le publier (faut que j'attende 5mn, suis encore un jeune sur le forum. Faut que je fasse plus de 100 publication pour ne plus avoir de limite)

Bon ça à l'air d'avoir fonctionné…

Merci "lesept"

Et je te tiendrai au courant de l'avancement du projet

@
Didier

Bjr @ ts et:

bananée.jpg

@ tout ceux qui liront ce post.

Je reviens vers vous car j'ai pas mal avancé sur le premier projet (je vais essayer de mettre une vidéo).

Décompte pour départ de course

Du coup je voudrai commencer à voir pour calculer ma vitesse, mais en y allant pas à pas pour comprendre ce que je fais.

Je voudrai tout d'abord faire un montage avec la breadborden mettant 2 boutons poussoirs, qui simuleront mes détecteurs de passage, et avec le moniteur série afficher le temps qui s'écoule entre le moment où je fais un appui sur le premier bouton et celui où j'appuie sur le 2ème. Malheureusement avec mes connaissances sur l'Arduino, ça commence mal, je ne vois pas quel code utiliser .

Je met un petit diagramme de ce que je voudrai en sachant que ce que je veux mesurer sera entre les 2 fronts descendants des contacts et non des fronts montants car, suivant la vitesse de la voiture T1 et T2 n'auront pas la même valeur.

Après une fois que j'aurai cette durée je pourrai, en fonction de la distance entre mes capteurs, déterminer la vitesse et l'afficher.

Par contre, une petite question @ "lesept" ou toute personne qui lira ce poste:
Que signifie "float" dans le petit bout de code que tu as mis pour calculer la vitesse? (suis vraiment novice avec les codes Arduino... ::slight_smile:

Merci par avance pour vos réponses.

@ bientôt...

Soyons clairs, les fronts montants et descendant sont équidistants sauf si la voiture change de taille entre le passage devant le capteur 1 et le capteur 2. Par contre la durée du niveau bas est fonction de la vitesse.

float c'est un type de variable qui permet de faire des calculs avec des décimales. Alors qu'int ou long ne permettent de faire que des calculs sur des entiers et ne fournissent donc que des résultats sous forme d'entiers.
Soit l'opération C = A/B.
Avec des variables de type int, si A= 1 et B=2 le résultat C vaut 0
Avec des variables de type float, si A= 1.0 et B=2.0 le résultat C vaut 0.5

Bjr @ ts,

Merci pour tes explications sur "float".

Tu as raison, en y réfléchissant un peu ( même beaucoup), quelque soit la longueur de la voiture, que ce soit qd elle arrive sur les capteurs ou qd elle en sort, le temps sera le même....

Alors front montant ou descenda., Peut importe.

@+
Didier