Indicateur de rapport engagé voiture rallye

Bonjour
J'ai commencé a fabriquer un indicateur de rapport engagé pour un ami qui fait du rallye. Pour ce faire, je dois réaliser je mesure la vitesse de rotation du moteur, ainsi que la vitesse de rotation des roues. En soit cela fonction, mais les monté en régime sont trop rapide et le temps que l'arduino mesure a vitesse de rotation du moteur, la vitesse de rotation des roues a déjà trop évoluer. L'arduino se mélange les pédales au moment d'afficher le rapport engagé.

voila le programme, il est pas ultra optimiser :sweat_smile:

const byte PIN_SIGNAL = 2;
unsigned long ttotale;
float RPMM;
float RPMC;
float RCM;

void setup() {

  
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(10, INPUT);
  pinMode(11, INPUT);
  Serial.begin(9600);

    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(8, HIGH); 

  
}


void loop() {

  // Mesure la durée de l'impulsion haute et basse MOTEUR
  noInterrupts();
  unsigned long t1 = pulseIn(10, HIGH,500);
  unsigned long t2 = pulseIn(10, LOW,500);
  interrupts();



  // Mesure la durée de l'impulsion haute et basse CARDAN
  noInterrupts();
  unsigned long t3 = pulseIn(11, HIGH,500);
  unsigned long t4 = pulseIn(11, LOW,500);
  interrupts();

    //transformation de la periode en frequence MOTEUR
  ttotale=t1+t2;
  RPMM=1/(ttotale*0.000001);
  RPMM=RPMM/2;
  Serial.println(RPMM);
  Serial.println("Moteur");

  //transformation de la periode en frequence CARDAN
  ttotale=t3+t4;
  RPMC=1/(ttotale*0.000001);
  RPMC=RPMC/4;
  Serial.println(RPMC);
  Serial.println("cardan");

  
  //Calcul rapport transmission 
  RCM=RPMM/RPMC;
  Serial.println(RCM);
  //if (t3+t4>=1000)
  {
    //RCM=0;
  }
  //Afficage du rapport de boite
  //1ER
  if (RCM>15 && RCM<16)
  {
    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);  
  }
  
  //2EME 
  if (RCM>11.5 && RCM<13.5)
  {
    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(2, HIGH);
    digitalWrite(13, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(6, HIGH);  
  }

  //3EME
  if (RCM>9 && RCM<10)
  {
    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(13, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(6, HIGH);  
  }

  //4EME
  if (RCM>7.5 && RCM<8.5)
  {
    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(13, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(8, HIGH);
  }

  //5EME
  if (RCM>6.6 && RCM<7.4)
  {
    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(13, HIGH);
    digitalWrite(8, HIGH);
    digitalWrite(6, HIGH);  
  }

  //6EME
  if (RCM>5.7 && RCM<6.5)
  {
    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(13, HIGH);
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(8, HIGH);
    digitalWrite(6, HIGH);  
  }
  
 //Point mort
 if (RCM>16.1) 
 {
    digitalWrite(13, LOW);
    digitalWrite(8, LOW);
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(8, HIGH); 
 }
}

Si vous avez une solution, pour mesurer la fréquence des différents capteurs plus rapidement qu'avec la fonction pulseIn, je pense que cela devrait résoudre le problème

Merci d'avance
Alexis

Bonjour
C'est quoi les capteurs utilisés avec l'arduino pour acquérir les vitesses moteurs et roues ?

ce sont des capteurs a effet hall je crois

Ces capteurs à effet hall sont acquis comment par ton programme arduino ?

je ne vos rien qui les concerne dans ton programme

Il y a une grande probabilité que le problème vient d'une mauvaise gestion Periode/Frequence dans leur traitement.

J'utilise la fonction pulseIn pour mesurer le temps a l'état 1 puis a l'état 0 pour les deux capteurs. Je pense que le probleme viens de la car la fonction pulseIn prend du temps a s'exécuter.
Ils sont relier a l'entrée 11 et 12 de l'arduino.

met le code complet

const byte PIN_SIGNAL = 2;
unsigned long ttotale;
float RPMM;
float RPMC;
float RCM;

void setup() {

pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
Serial.begin(9600);

digitalWrite(13, LOW);
digitalWrite(8, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(8, HIGH); 

}

void loop() {

// Mesure la durée de l'impulsion haute et basse MOTEUR
noInterrupts();
unsigned long t1 = pulseIn(12, HIGH,500);
unsigned long t2 = pulseIn(12, LOW,500);
interrupts();

// Mesure la durée de l'impulsion haute et basse CARDAN
noInterrupts();
unsigned long t3 = pulseIn(11, HIGH,500);
unsigned long t4 = pulseIn(11, LOW,500);
interrupts();

//transformation de la periode en frequence MOTEUR

ttotale=t1+t2;
RPMM=1/(ttotale*0.000001);
RPMM=RPMM/2;
Serial.println(RPMM);
Serial.println("Moteur");

//transformation de la periode en frequence CARDAN
ttotale=t3+t4;
RPMC=1/(ttotale*0.000001);
RPMC=RPMC/4;
Serial.println(RPMC);
Serial.println("cardan");

//Calcul rapport transmission
RCM=RPMM/RPMC;
Serial.println(RCM);
//if (t3+t4>=1000)
{
//RCM=0;
}
//Afficage du rapport de boite
//1ER
if (RCM>15 && RCM<16)
{
digitalWrite(13, LOW);
digitalWrite(8, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
}

//2EME
if (RCM>11.5 && RCM<13.5)
{
digitalWrite(13, LOW);
digitalWrite(8, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(2, HIGH);
digitalWrite(13, HIGH);
digitalWrite(5, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
}

//3EME
if (RCM>9 && RCM<10)
{
digitalWrite(13, LOW);
digitalWrite(8, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(4, HIGH);
digitalWrite(13, HIGH);
digitalWrite(5, HIGH);
digitalWrite(3, HIGH);
digitalWrite(6, HIGH);
}

//4EME
if (RCM>7.5 && RCM<8.5)
{
digitalWrite(13, LOW);
digitalWrite(8, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(4, HIGH);
digitalWrite(13, HIGH);
digitalWrite(5, HIGH);
digitalWrite(8, HIGH);
}

//5EME
if (RCM>6.6 && RCM<7.4)
{
digitalWrite(13, LOW);
digitalWrite(8, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(13, HIGH);
digitalWrite(8, HIGH);
digitalWrite(6, HIGH);
}

//6EME
if (RCM>5.7 && RCM<6.5)
{
digitalWrite(13, LOW);
digitalWrite(8, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(4, HIGH);
digitalWrite(13, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(8, HIGH);
digitalWrite(6, HIGH);
}

//Point mort
if (RCM>16.1)
{
digitalWrite(13, LOW);
digitalWrite(8, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
digitalWrite(8, HIGH);
}
}

La partie juste après //Afficage du rapport de boite gère uniquement les sortie a activer pour le 7 segments.

pulsein n'est pas adapté là

a chaque tour de volant moteur et de cardan tu recupere un top (impulsion)

il te faut recuperer le temps mis entre 2 top de volant et 2 top de cardan pour obtenir leur vitesse en tours/mn (ou autre unité de temps)

regarde du coté de millis() et des interuptions :wink:

la fonction pulseIn me donne bien une durée, mais uniquement d'un état, se qui explique qui en faut 2 par capteur

pulseIn(12, HIGH,500);
pulseIn(12, LOW,500);

un pour l'état 1 et l'autre pour l'état 0

Je vais regardé du coté millis et des interruptions mais j'avoue pas avoir bien compris comment ca fonctionnait :sweat_smile: La programmation c'est pas encore mon fort :joy:

Tu n'a pas besoin de connaitre la durée de l'etat Haut ou bas du capteur hall
Tu a besoin de de connaitre la durée entre chaque front montant de chaque capteur hall Motor et Cardan

Si à chaque nouveau front montant tu soustrait à la valeur millis() (le temps actuel) la variable OLDMotor qui etait la valeur de millis() au tour precedent , tu aura le temps en ms mis pour faire le tour :nerd_face:

Tu a la methode , à toi d'avancer dans la prog

Je vois une maladresse et un défaut dans le code. La maladresse est que passer par les fréquences pour faire leur rapport est bien compliqué, car il suffit de faire le rapport des temps mesurés par ces capteurs : prendre bien entendu l'inverse du rapport des temps pour avoir le rapport des vitesses de rotation. Le défaut est que l'utilisation des variables t1/t2/t3/t4 pour faire les additions et la division en vue d'obtenir le rapport doit être fait en se protégeant des interruptions. Donc les masquer avant la première addition, démasquer après la division. En l'état actuel, compte tenu des rapports bizarres qu'il peut y avoir entre les fréquences des pulses en entrée, il est probable qu'on va avoir un changement pendant une phase de calcul, et cela ne me surprend pas du tout que le problème soit constaté pendant des phases d'accélération ou décélération.

Bonsoir
Sur les conseils d'Artouste, j'ai repris un programme trouvé sur le net et j'y ai apporté quelque modification.

volatile unsigned int freq;
volatile unsigned int rpm;
unsigned long start;
unsigned long elapsed;

void setup() {

attachInterrupt(1, rpm_pulse, FALLING);
Serial.begin(9600);

}

void loop() {

Serial.println(rpm);
//delay(200);

}

void rpm_pulse() {

static int cpt=0;
if (++cpt>=10){
  unsigned long end = micros();
  elapsed = end - start;
  start=end;
  freq = 10000000/elapsed;
  rpm=freq*30;
  cpt=0;
}

Pour le moment je me suis contenté de mesurer le régime de rotation d'un seul capteur. Le programme a l'air de fonctionné (en tout cas il me donne bien le bon régime moteur a quelque chose près). Il mesure le temps pour 10 impulsions. La vitesse d'éxecution de l'ancien programme était d'environ 6~7 seconde, la le regime est calculer en moins d'une seconde pour le regime moteur.
J'aurais quand même voulu savoir ce que vous en pensiez. Pour information, je reçois 2 impulsions par tour moteur.

Il faudrait juste que je rajoute une fonction avec une autre mesure mais puis je le faire en rajoutant un la même chose avec d'autres variables dans une autre fonction ?

JiPe38 J'ai pas très bien compris l'erreur que j'ai commise, les valeurs de t1 t2 t3 et t4 peuvent changer même après avoir dépassé la ligne ou on les mesurent ?

Merci pour votre aide :wink:

bonjour
quel etat a le capteur hall sur la majorité d'un tour , haut ou bas ?

Les valeurs de t1/t2/t3/t4 sont modifiées par les routines d'interruption (ISR). Donc lorsque j'écris a = b+c, il se peut qu'une interruption arrive entre la lecture de b dans un registre et l'addition de c, ou encore avec z = x / y. Donc il faut se protéger des interruptions pendant toute la séquence de calcul du ratio (t1+t2) / (t3+t4), car une modification d'une des variables en cours de calcul peut produire des effets bizarres. Le masquage / démasquage des interruptions dans les routines ISR n'est pas forcément utile, sauf si vous utilisez d'autres interruptions que celles de vos compteurs. Mais il faut encadrer la séquence de calcul par un masquage / démasquage des interruptions données par vos compteurs. J'ai même vu une appli en langage évolué ou un calcul sur 32 bits était fait par une suite d'instructions sur 16 bits, et une interruption avec changement d'une des variables pendant le calcul produisait un plantage monumental !

hello
un test ?
il te faut modifier le cablage de l'afficheur ( voir la zone commentée en début de prg
, et la vitesse du moniteur ( en bas à droite dans le moniteur )

nota: je n'ai pas vraiment testé le prg

 
 /*
 il faudra supprimer les serial print dans la loop
 interrupt cardan sur D2
 interrupt moteur sur D3
 Segment A sur D4
 Segment B sur D5
 Segment C sur D6
 Segment D sur D7
 Segment E sur D8
 Segment F sur D9
 Segment G sur D10
 */
float rpm;
float rpc;
volatile unsigned long periodem;
volatile unsigned long periodec;
unsigned long startm;
unsigned long startc;
int nb_cames_m=1;                    //mettre le nombre de cames
int nb_cames_c=2;                    //mettre le nombre de cames
float rapport_engage=0.0;
int rapport=0;
const byte segment=4;                //segment A sur D4. init pour affichage
void setup() {
  Serial.begin(115200);
    for (byte f=4;f<=10;f++)
    {
      pinMode(f, OUTPUT);digitalWrite(f, LOW);
    }
    pinMode(2, INPUT);               // voir si besoin INPUT_PULLUP
    pinMode(3, INPUT);               // voir si besoin INPUT_PULLUP
    pinMode(11, INPUT);
    pinMode(12, INPUT);
//            4 5 6 7 8 9 10
//            A,b,C,D,E,F,G
    affichage(1,1,1,1,1,1,0);//zéro
    
  attachInterrupt(0, isr_cardan_pulse, FALLING);
  attachInterrupt(1, isr_moteur_pulse, FALLING);
  Serial.begin(1000000);
}


void loop() {
  cli();
  rpc = float((1000000 / periodec)/nb_cames_c);
  rpm = float((1000000 / periodem)/nb_cames_m);
  sei();
  rapport_engage=rpm/rpc;
  Serial.print(rpc);
  Serial.print("  ");
  Serial.print(rpm);
  Serial.print("  ");
  Serial.println(rapport_engage);
  controle_rapport();
}
void controle_rapport()
{
if ((rapport_engage >15)&&(rapport_engage <16)){rapport=1;}
  else {if ((rapport_engage >11.5)&&(rapport_engage <13.5)){rapport=2;}
  else {if ((rapport_engage >   9)&&(rapport_engage <  10)){rapport=3;}
  else {if ((rapport_engage > 7.5)&&(rapport_engage < 8.5)){rapport=4;}
  else {if ((rapport_engage > 6.6)&&(rapport_engage < 7.4)){rapport=5;}
  else {if ((rapport_engage > 5.7)&&(rapport_engage < 6.5)){rapport=6;}
  else {if  (rapport_engage >16.1){rapport=0;}
  }}}}}}
  switch(rapport)
  {
    case 0:{//A,b,C,D,E,F,G
    affichage(1,1,1,1,1,1,0);//zéro
      }
      case 1:{//A,b,C,D,E,F,G
    affichage(0,1,1,0,0,0,0);//un
      }
    case 2:{//A,b,C,D,E,F,G
    affichage(1,1,0,1,1,0,1);//deux
      }
      case 3:{//A,b,C,D,E,F,G
    affichage(1,1,1,1,0,0,1);//trois
      }
      case 4:{//A,b,C,D,E,F,G
    affichage(0,1,1,0,0,1,1);//quatre
      }
     case 5:{//A,b,C,D,E,F,G
    affichage(1,1,1,1,0,1,1);//cinq
      }
      case 6:{//A,b,C,D,E,F,G
    affichage(1,0,1,1,1,1,1);//six
      }break;
     default:{}break;
  }
}
//                                    A         B           C           D           E        F        G
void affichage( byte un, byte deux, byte trois, byte quatre, byte cinq, byte six, byte sept)
{ 
  digitalWrite(segment    , un);         //Segment A
  digitalWrite(segment + 1, deux);       //Segment B
  digitalWrite(segment + 2, trois);      //Segment C
  digitalWrite(segment + 3, quatre);     //Segment D
  digitalWrite(segment + 4, cinq);       //Segment E
  digitalWrite(segment + 5, six);        //Segment F
  digitalWrite(segment + 6, sept);       //Segment G
}
void isr_moteur_pulse() { periodem=micros()-startm; startm = micros();}
void isr_cardan_pulse() { periodec=micros()-startc; startc = micros();}

Dans le premier programme, il n'y a comme fonction d'interruption que l'horloge système. Les variables t1, t2.. ne sont pas modifiées en isr... Pas de soucis je pense.

Si ce sont des constantes, mettre "const. Ainsi on économise une division. En tout cas si on fait

rpc = float((1000000/nb_cames_c) / periodec);

Le calcul ci dessus est composé uniquement d'entiers. L'opération se fera avec des entiers. Soit on veut rpc avec une valeur entière, et autant la déclarer entière, soit on veut une valeur float, et il faut faire le calcul en float:

rpc = float((1000000.0/nb_cames_c) / periodec);

Ce qui d'ailleurs peut s'écrire

rpc = 1000000.0 / nb_cames_c / periodec;

Ce n'est pas faux, mais pour moi toutes les accolades sont inutiles.

A été perdu la moyenne (ou la somme) de 10 mesures. C'est mieux de faire le moins possible de calculs surtout avec des réels dans l'interruption pour être sûr de ne pas retarder l prise en compte d'une impulsion. Si on veut garder les 10 impulsions, ce pourrait faire quelque chose comme:

Cela me semble une évidence, la fréquence n'a aucun intérêt, il n'y a que le rapport qui importe!
Au lieu de:

faire

  cli();
  rapport_engage = (nb_cames_c / nb_cames_m) * periodec / periodem;
  sei();

Et rajouter un float quelquepart pour que l'opération se fasse en réels, genre définir la valeur de gauche en float, ou pourquoi pas:
const float rapportDeCame = nb_cames_c/nb_cames_m;
Si l'on fait:

  cli();
  rapport_engage = rapportDeCame * periodec / periodem;
  sei();

On passe de 3 divisions à une multiplication et une division (c'est surtout les divisions qui sont longues)

Encore mieux au vu des if pour les tests, on peut multiplier par 10 les rapport, et ains les valeurs limites deviennent entières, et on évite les float:

const int nb_cames_m=1;                    //mettre le nombre de cames
const int nb_cames_c=2;                    //mettre le nombre de cames
const float rapportDeCame = 10 * nb_cames_c/nb_cames_m;
...
uint16_t rapport_engage;               // ou sur 32 bits, cela dépend des valeurs maxi de periodec / periodem

...

  cli();
  rapport_engage = rapportDeCame * periodec / periodem;
  sei();

...

if        (rapport_engage > 150 && rapport_engage < 160) rapport=1;
  else if (rapport_engage > 115 && rapport_engage < 135) rapport=2;
  else if (rapport_engage >  90 && rapport_engage < 100) rapport=3;
  else if (rapport_engage >  75 && rapport_engage <  85) rapport=4;
  else if (rapport_engage >  66 && rapport_engage <  74) rapport=5;
  else if (rapport_engage >  57 && rapport_engage <  65) rapport=6;
  else if (rapport_engage > 161) rapport=0;

D"ailleurs pour la dernière ligne , je mettrais

else  rapport=0;

pour avoir 0 si le rapport est supérieur à 160 ou inférieur à 57

Je note aussi que l'on peut faire encore moins de calculs si au lieu de:
rapport_engage = rapportDeCame * periodec / periodem;
on fait
rapport_brut = periodec / periodem;
et que l'on fait en compensation:

if        (rapport_brut > 150*rapportDeCame && rapport_engage < 160*rapportDeCame) rapport=1;

en inversant rapportDeCame:
const float rapportDeCame = 10 * nb_cames_m/nb_cames_c;
Du coup, on n'a plus le calcul que d'une division.

Si on veut aussi économiser dans les tests, on peut au lieu de :

if        (rapport_engage > 150 && rapport_engage < 160) rapport=1;
  else if (rapport_engage > 115 && rapport_engage < 135) rapport=2;
  else if (rapport_engage >  90 && rapport_engage < 100) rapport=3;
  else if (rapport_engage >  75 && rapport_engage <  85) rapport=4;
  else if (rapport_engage >  66 && rapport_engage <  74) rapport=5;
  else if (rapport_engage >  57 && rapport_engage <  65) rapport=6;
  else if (rapport_engage > 161) rapport=0;

faire:

if        (rapport_engage > 160) rapport=0;
  else if (rapport_engage > 142) rapport=1;
  else if (rapport_engage > 107) rapport=2;
  else if (rapport_engage >  87) rapport=3;
  else if (rapport_engage >  75) rapport=4;
  else if (rapport_engage >  66) rapport=5;
  else if (rapport_engage >  57) rapport=6;
  else rapport=0;

Voila, j'ai enlevé le haut, il ne reste plus que la moitié du preogrmme. La semaine prochaine, j'enlève le bas. :wink:

pour terminer, il manquait des "break"

case 0:{//A,b,C,D,E,F,G
    affichage(1,1,1,1,1,1,0);//zéro
      }break;
      case 1:{//A,b,C,D,E,F,G
    affichage(0,1,1,0,0,0,0);//un
      }break;
    case 2:{//A,b,C,D,E,F,G
    affichage(1,1,0,1,1,0,1);//deux
      }break;
      case 3:{//A,b,C,D,E,F,G
    affichage(1,1,1,1,0,0,1);//trois
      }break;
      case 4:{//A,b,C,D,E,F,G
    affichage(0,1,1,0,0,1,1);//quatre
      }break;
     case 5:{//A,b,C,D,E,F,G
    affichage(1,1,1,1,0,1,1);//cinq
      }break;

:joy:

Je vous remercie pour l'attention que vous portez a mon projet.

quel etat a le capteur hall sur la majorité d'un tour , haut ou bas ?
Si je me trompe pas la plus par du temps les capteurs sont a 0.

Merci Dfgh pour le programme, j'ai pas encore eu le temps de l'essayer, mais ca ne serait tarder.
Néanmoins il y a quelques petites chose que j'ai du mal a comprendre.

    pinMode(11, INPUT);
    pinMode(12, INPUT);

Je pense que tu as pris ca dans mon premier programme mais pour etre sur y a t'il quelque chose a brancher sur ces pins ?

int nb_cames_m=1;                    //mettre le nombre de cames
int nb_cames_c=2;                    //mettre le nombre de cames

Nb cames c'est le nombre de d'impulsion par tour ?

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

J'ai pas très bien compris comment fonctionnait cette partie. A quoi correspond les valeur segment, segment +1... ?

Merci aussi a Vileroi pour les modification. Je testerai le programme de base et j'apporterais les modification au fur et a mesure pour voir ce que ca change.

Merci a vous, je vous tiens informé de la suite du projet.
Alexis