Problème mesure de temps courts entre micros et pulseIn

hello
générateur:


// Générateur signal carré simulation PMH et allumage

#define ALL 10             // Simulation Allumage cylindre Avant
#define PMHAvant 12        // Simulation Point Mort Haut cylindre Avant
#define pot_avance A0
void setup() {
  pinMode(ALL, OUTPUT);         // D10  SORTIE
  pinMode(PMHAvant, OUTPUT);    // D12  SORTIE  
}

void loop() {

  digitalWrite(ALL, HIGH);      // On met la sortie allumage D10 à 5V
  digitalWrite(PMHAvant, LOW);  // On met la sortie PMH Avant D12 à l'état 0  

  // digitalWrite(ALL, LOW);      // On met la sortie allumage D10 à 5V inversion
  // digitalWrite(PMHAvant, HIGH);  // On met la sortie PMH Avant D12 à l'état 0  inversion  

  digitalWrite(ALL, LOW);       // On met la sortie allumage D10 à 0 début charge bobine
  // digitalWrite(ALL, HIGH);       // On met la sortie allumage D10 à 0 début charge bobine inversion

   delayMicroseconds(50);    // temps de charge bobine allumage environ 2 ms 

  digitalWrite(ALL, HIGH);      // On met la sortie allumage D10 à 5V moment de l'allumage, coupure alim bobine
  // digitalWrite(ALL, LOW);      // On met la sortie allumage D10 à 5V moment de l'allumage, coupure alim bobine inversion
  //delayMicroseconds(100);
 // delayMicroseconds(map(analogRead(pot_avance),0,1023,0,1000));         // le PMH arrive peu de temps après

  digitalWrite(PMHAvant, HIGH);  // On met la sortie du PMH Avant D12 à 5V
  // digitalWrite(PMHAvant, LOW);  // On met la sortie du PMH Avant D12 à 5V inversion

  delayMicroseconds(2000);        // le PMH dure peu de temps à l'état 1

  digitalWrite(PMHAvant, LOW);  // On met la sortie PMH Avant D12 à l'état 0
  // digitalWrite(PMHAvant, HIGH);  // On met la sortie PMH Avant D12 à l'état 0 inversion

  delay(5);      // temps du cycle bobine pas alimentée
 
}

prog de saisie du temps entre les deux flancs montants

unsigned long deb_allumage = 0;
unsigned long deb_pmh = 0;
unsigned long tps_par_tour = 0;
boolean debut_allumage = false;
boolean debut_pmh     = false;
boolean temps_tour      = false;

void isr_debut_allumage()
{
  if ((!debut_allumage) && (!debut_pmh)) {
    deb_allumage = micros();
    debut_allumage = true;
  }
}

void isr_debut_pmh()
{
  if ((debut_allumage) && (!debut_pmh)) {
    deb_pmh = micros();
    debut_pmh = true;
  }
  /*else {
    if ((debut_pmh) && (!temps_tour)) {
      tps_par_tour = micros();
      temps_tour = true;
    }
   
  }*/
}
void setup() {
  Serial.begin(115200);
  attachInterrupt(0, isr_debut_allumage, RISING);
  attachInterrupt(1, isr_debut_pmh, RISING);
}

void loop() {
  if ((debut_allumage) && (debut_pmh)){// && (temps_tour)) {
    cli();
    Serial.print(F("avance = ")); Serial.print(deb_pmh - deb_allumage); Serial.println(F(" µS"));
    //Serial.print(F("temps par tour = ")); Serial.print(tps_par_tour - deb_pmh); Serial.println(F(" µS"));
   // Serial.print(F("angle = ")); Serial.print(360 / ((tps_par_tour - deb_pmh) / (deb_pmh - deb_allumage))); Serial.println(F(" °"));
    debut_allumage = false; debut_pmh = false; temps_tour = false;
    sei(); delay(1000);
  }
}

à l'écran:

Merci.
Oui ça fonctionne je l'avais essayé, un peu différent
(les parties mis en commentaires // && (temps_tour)) { )
ça ne pose pas de problème, c'est une fois intégré au reste du programme que ça ne va plus malheureusement.

unsigned long deb_allumage = 0;
unsigned long deb_pmh      = 0;
unsigned long tps_par_tour = 0;
boolean debut_allumage = false;
boolean debut_pmh      = false;
boolean temps_tour     = false;

const int UMOT                 =  6; // Numéro du pin U tension 0 à 5V pour simuler N régime moteur PWM
unsigned int Umot              = 0;  // Tension régime moteur de 0 à 5 V
const unsigned int Attente     = 100;  // Pour essai rapide le temps d'attente est limité entre mesures

void isr_debut_allumage()
{
  if ((!debut_allumage) && (!debut_pmh)) {
    deb_allumage = micros();
    debut_allumage = true;
  }
}

void isr_debut_pmh()
{
  if ((debut_allumage) && (!debut_pmh)) {
    deb_pmh = micros();
    debut_pmh = true;
  } else {
    if ((debut_pmh) && (!temps_tour)) {
      tps_par_tour = micros();
      temps_tour = true;
    }
  }
}
void setup() {
  Serial.begin(115200);
  attachInterrupt(0, isr_debut_allumage, RISING);
  attachInterrupt(1, isr_debut_pmh, RISING);

  pinMode(UMOT, OUTPUT);     // Sortie D6 PWM U tension 0 à 5V pour simuler N régime moteur
}

void loop() {
  // Umot = 50;                 // Essai régime intermédiare
  // Umot = 100;                // Essai régime intermédiare
  // Umot = 200;                // Essai régime intermédiare
  Umot = 250;                   // Essai régime maxi
  analogWrite(UMOT,Umot);       // Envoi du signal PWM en sortie

  delay(Attente);            // Attendre avant de mesurer la prochaine série

  if ((debut_allumage) && (debut_pmh) && (temps_tour)) {
    cli();

    Serial.print (720 / ((tps_par_tour - deb_pmh) / (deb_pmh - deb_allumage))); // temps par tour = 2 tours moteur
    Serial.print(",");

    Serial.println();            
    Serial.print("DATA,"); 

    debut_allumage = false; debut_pmh = false; temps_tour = false;
    sei(); delay(Attente);

   }
}

hello
moto_michel_m_V2.zip (8,9 Ko)
dans la version 1, je n'avais pas mis les attachInterrupt dans le setup

cette version V2 réagit sur les flancs montants.
si tu veux que ce soit sur un flanc descendant, il faudra changer le "RISING" par "FALLING" dans les attachInterrupt qui sont dans le setup

Super je vais essayer, c'est bien des fronts montants.

Après avoir mis mes paramètres et adapter les serialPrint pour envoi dans le tableau j'obtiens des valeurs dans quelques colonnes, sinon des 0 dans les autres.

Le code de la mesure de l'avance seule donne toujours 36 à 37°, conforme à la réalité.

Ma version un peu corrigée, attente plus courte, et les serialPrint, correction de N
moto_michel_m_V2bis.zip (9.6 KB)

J'essaye de "bricoler" un peu, en comparant avec le code qui fait les bonnes mesures
et j'arrive à trouver le bon angle mais pas au début, c'est un peu instable

void CalculAvanceAllumage() {                         // Calcul avance à l'allumage

  for (AvAllumage = 0, k = 0; k < NbBoucle ; k++)       // boucle de mesures
  { isr = true;
    

    delay(Attente);            // Attendre avant de mesurer la prochaine série

    if ((debut_allumage) && (debut_pmh) && (temps_tour)) {
      isr = false;
      cli();

      Serial.print (720 / ((tps_par_tour - deb_pmh) / (deb_pmh - deb_allumage))); // temps par tour = 2 tours moteur
      Serial.print(",");

      // Serial.println();
      // Serial.print("DATA,");

      debut_allumage = false; debut_pmh = false; temps_tour = false;
      sei();
      delay(Attente);
      angle_ALL += (720 / (((tps_par_tour - deb_pmh) / (deb_pmh - deb_allumage))*2));
    }
  }
  angle_ALL = (angle_ALL / NbBoucle);   // ici c'est la moyenne des mesures successives
  // Serial.print(F("angle = "));
  // Serial.print(angle_ALL, 2);
  // Serial.print(",");                  // case suivante
  // Serial.print(F(" °"));
  angle_ALL= 0;
  /*
    Serial.print(F("tps_par_tour = "));
    Serial.print(tps_par_tour);
    Serial.print(F("  "));
    Serial.print(F("avance = "));
    Serial.print(AvanceAllumage);       // Envoyer l'angle d'avance à l'allumage
    Serial.print(F("  "));
    Serial.print(F("angle = "));
    Serial.print(angle_ALL, 2);
    Serial.print(F(" °"));
    Serial.println(",");                  // case suivante
  */

hello
dans les fonctons isr, j'ai fait afficher 1 , 2, 3 pour voir si tu passes dans les isr.
il faudra supprimer ces lignes car elles font perdre du temps

pour ne pas dérouler tout le prg, j'ai commenté des lignes d'appels de fonctions dans la loop

moto_michel_m_V3.zip (8,7 Ko)

image

les calculs ne veulent pas dire grand chose, mais on voit que le prg s'exécute et que les interruptions sont bien appelées ( 1 , 2 , 3 )

Bonjour dfgh,
C'est de mieux en mieux, je suis rassuré c'est possible !
Alors effectivement j'ai vu les 123 à chaque pas de U Pap, ensuite j'ai commenté ces lignes, et j'avais la moitié de la valeur attendue, j'ai simplement enlevé le *2 qui n'y était pas avant dans le serialPrint,
et là j'ai bien 36 à 37°, sauf la première colonne du régime N le plus bas, mais après c'est bon jusqu'au régime maxi.
Super !

angle_ALL += (720 / (((tps_par_tour - deb_pmh) / (deb_pmh - deb_allumage))*2));
void UPapillonGazAvAll() {          // Simuler la tension du potentiomètre des gaz par pas pour cacul avance allumage  ***** Vérifié : Bon ******
  while (Upap < UpapMaxi) {         // Tant que la tension maxi papillon des gaz n'est pas atteinte
    analogWrite(UPAP, Upap);          // Envoi du signal PWM en sortie
    delay(Attente);                   // Attendre avant de mesurer la prochaine série
    Serial.println();                 // ligne suivante utile ici pour envoi openoffice calc sinon pas d'envoi
    Serial.print("DATA,");            // utile ici sinon pas d'envoi vers le tableau openoffice calc
    // Serial.println();
    // Serial.print("U Pap = ");       // pour essai envoi du texte
    Serial.print(float (Upap) / 51);  // Envoyer U papillon / 51 pour avoir en V
    // Serial.println();
    InitVarUregimeMoteur();       // intialiser les variables U et N régime moteur pour recommencer un cycle de mesures
    delay(Attente);              // Attendre avant de mesurer la prochaine série

    UregimeMoteurAvAll();        // U pour simuler régime moteur

    Upap += DuPap;              // Augmenter U papillon da la valeur du pas déterminée par DUPAP
    if (Upap >= UpapMaxi) {     // Si Upap dépasse le maxi alors il doit être au maxi
      Upap = UpapMaxi;
    }
  }
}

void UregimeMoteurAvAll() {      // Simuler la tension, qui va créer le régime moteur, par pas pour calcul avance allumage
  Serial.print(",");             // envoi à la case suivante openoffice calc à la place de ligne suivante
  Umot = UmotMini;
  while (Umot < UmotMaxi) {      // Tant que la tension maxi régime moteur n'est pas atteinte :
    analogWrite(UMOT, Umot);       // Envoi du signal PWM en sortie
    delay(Attente);                // Attendre avant de mesurer la prochaine série
    // Serial.print(Umot);         // Seulement pour essai Envoyer U papillon openoffice calc
    // Serial.print(",");          // Seulement pour essai envoi à la case suivante sur la ligne openoffice calc

    CalculAvanceAllumage();        // après simulation du régime moteur mesurer les avances à l'allumage

    Umot += DuMot;                 // Augmenter U régime moteur de la valeur du pas déterminée par DuMot
    if (Umot >= UmotMaxi) {        // Si Umot dépasse le maxi alors il doit être au maxi
      Umot = UmotMaxi;
    }
  }
}

void CalculAvanceAllumage() {                         // Calcul avance à l'allumage
sei();
 // for (AvAllumage = 0, k = 0; k < NbBoucle ; k++)       // boucle de mesures
  k=0;debut_allumage = false; debut_pmh = false; temps_tour = false;
  while (k<NbBoucle)
  { isr = true;
  
 

    delay(Attente);            // Attendre avant de mesurer la prochaine série

    if ((debut_allumage) && (debut_pmh) && (temps_tour)) {
      isr = false;k++;
      debut_allumage = false; debut_pmh = false; temps_tour = false;
      delay(Attente);
      // angle_ALL += (720 / (((tps_par_tour - deb_pmh) / (deb_pmh - deb_allumage))*2));
      angle_ALL += (720 / (((tps_par_tour - deb_pmh) / (deb_pmh - deb_allumage))));
    }
  }
  angle_ALL = (angle_ALL / NbBoucle);   // ici c'est la moyenne des mesures successives
 
  // Serial.print(F("angle = "));
  Serial.print(angle_ALL, 2);
  Serial.print(",");                  // case suivante
  // Serial.print(F(" °"));
  angle_ALL= 0;
  /*
    Serial.print(F("tps_par_tour = "));
    Serial.print(tps_par_tour);
  
    Serial.print(F("  "));
    Serial.print(F("avance = "));
    Serial.print(AvanceAllumage);       // Envoyer l'angle d'avance à l'allumage
    Serial.print(F("  "));
    Serial.print(F("angle = "));
    Serial.print(angle_ALL, 2);
    Serial.print(F(" °"));
    Serial.println(",");                  // case suivante
  */
  delay(Attente);                     // Attendre avant de mesurer la prochaine série

}

void isr_debut_allumage()
{
  if (isr) { //1  si flanc montant sur début allumage
    if ((!debut_allumage) && (!debut_pmh)&&(!temps_tour)) {
      deb_allumage = micros();
      //deb_allumage= 400000;
      debut_allumage = true;
      // Serial.print("1");
    }
  }
}
void isr_debut_pmh()
{ if (isr) {// 2 si flanc montant sur debut pmh
    if ((debut_allumage) && (!debut_pmh)&&(!temps_tour)) {
      deb_pmh = micros();
      //deb_pmh =500000;
      debut_pmh = true;
      // Serial.print("2");
    } else {// 3 si flanc montant sur fin pmh soit  un tour complet
      if ((debut_pmh) && (!temps_tour)) {
        tps_par_tour = micros();
        //tps_par_tour = 1000000;
        temps_tour = true;
        // Serial.println("3");
      }
    }
  }
}

Tableau des résultats
Donc juste la première colonne pour N = 367 tr/mn, peut-être augmenter le délai "attente" qui est court pour les essais, ou commencer N plus bas à 0 et ne pas tenir compte de cette colonne

Temps "attente" à 100 ms entre mesures, 4 boucles de mesures c'est parfait cette fois

hello
c'est cool, bonne suite :grinning:

Un grand MERCI ! Bravo pour ton travail !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.