Problème mesure de temps courts entre micros et pulseIn

Bonsoir,

Je précise que je suis assez novice pour faire du code Arduino.

Mon projet qui fonctionne en partie, est d'enregistrer dans un tableau OpenOffice Calc des temps d'injection et les avances à l'allumage d'un calculateur d'injection allumage moto très peu utilisé, et sans logiciel de communication malheureusement (j'ai cherché longtemps). Je simule grace à un Nano et ArduStim les impulsions du volant moteur (capteur vilo) et de l'arbre à cames (capteur de Phase). J'arrive avec mon logiciel et un autre Nano, par pas de régime moteur et d'ouverture des gaz, à enregistrer les temps d'injection, ainsi que le temps de charge bobine d'allumage, la tension batterie, par contre les avances à l'allumage sont totalement erronées.
Après de nombreux essais je m’aperçois qu'en utilisant micros() entre le moment d'allumage (All) et le point mort haut du cylindre Avant (PMHAvant) (0° du moteur) j'ai toujours 8 us au lieu de 540 us (vérifié à l'oscilloscope) par exemple. J'ai du coup utilisé pulseIn sur l'info et j'ai bien 540 us. L'info Allumage et PMH sont pontés pour le moment pour essai sur table avec Ardustim sans le calculateur d'injection allumage. Mais après ça sera bien 2 infos séparées indépendantes.

Donc actuellement une impulsion arrive qui dure 540 us, PulseIN la mesure bien, mais si j'utilise micros j'ai 8 us. (digitalRead(ALL) == HIGH etc.).
Très étrange pour moi !
Merci d'avance pour votre aide.

une partie du code

void CalculAvanceAllumage() {                         // Calcul avance à l'allumage
  for (AvAllumage = 0, k = 0; k < NbBoucle ; k++)       // boucle de mesures
   {
  // TempsPhaseOn = pulseIn(CAPTPHASE, HIGH);           // Mesure la durée de l'impulsion haute du capteur de Phase
  // TempsPhaseOff = pulseIn(CAPTPHASE, LOW);           // Mesure la durée de l'impulsion basse du capteur de Phase
  // TempsParTour = ((TempsPhaseOn + TempsPhaseOff)/2); // Calcul temps par tour avec capteur de phase = (état haut + état bas) / 2
  TempsParTour = ((pulseIn(CAPTPHASE, HIGH) + pulseIn(CAPTPHASE, LOW))/2); // Calcul temps par tour avec capteur de phase = (état haut + état bas) / 2  

  // Serial.print(TempsParTour);           // Essai Envoyer Temps par tour
  // Serial.print(",");                    // Essai case suivante 

  // if (digitalRead(ALL) == LOW);                     // Si l'allumage passe à 0 V (début de charge bobine)
  // {Allumage = 1;   }                                // Allumage passe à 1
  // if (digitalRead(ALL) == HIGH && Allumage == 1);   // Si allumage est à 1 et que l'entrée ALL passe au niveau haut = moment de l'allumage
  // {TempsAll = micros();                             // Prise du temps écoulé au moment de l'allumage
  // Allumage = 0;  }                                  // Allumage repasse à 0

  // if (digitalReadFast(ALL) == HIGH);                   // Essai lecture rapide
  if (digitalRead(ALL) == HIGH);                      // Essai simulation Si l'entrée ALL passe au niveau haut = moment de l'allumage
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage
  // delayMicroseconds(10);                              // Essai délai pour avoir une mesure plus juste, pas correct

  // if (digitalRead(PMHAvant) == HIGH);               // Si l'info PMH cylindre avant passe à l'état 1 (cas normal)
  // if (digitalReadFast(PMHAvant) == LOW);            // Essai lecture rapide  
  if (digitalRead(PMHAvant) == LOW);                  // Essai simulation Si l'info PMH cylindre avant passe à l'état bas on a PMH cyl avant 
  {  TempsPMHAV = micros();  }                        // Prise du temps écoulé au moment du PMH

  Serial.print(TempsAll);                           // Essai Envoyer Temps allumage
  Serial.print(",");                                // Essai case suivante 

  Serial.print(TempsPMHAV);                         // Essai Envoyer Temps PMH
  Serial.print(",");                                // Essai case suivante   

  TempsAv = (TempsPMHAV - TempsAll);                  // Essai soustraction avant division
  // TempsAv = pulseIn(ALL, HIGH);                  // Essai 
  Serial.print(TempsAv);                            // Essai Envoyer Temps PMH
  Serial.print(",");                                // Essai case suivante  

  // AvAllumage += (float (TempsAv) / TempsParTour);  // Calculez l'angle en degrés en fonction du temps entre Allumage et PMH point mort haut
  AvAllumage += (float (TempsPMHAV - TempsAll) / TempsParTour);  // Calculez l'angle en degrés en fonction du temps entre Allumage et PMH point mort haut  
   }

  AvanceAllumage = float (AvAllumage * 360) / NbBoucle;   // Moyenne sur N boucle mesures de l'avance à l'allumage 1 tour 360°  
  // Serial.print("AvAll=");             // Pour essai Envoi texte
  Serial.print(AvanceAllumage);       // Envoyer l'angle d'avance à l'allumage
  Serial.print(",");                  // case suivante

  TempsPhaseOn = pulseIn(PMHAvant, HIGH);              // Essai mesure du temps PMH à l'état 1
  Serial.print(TempsPhaseOn);                          // Essai Envoyer Temps créneau PMH
  Serial.print(",");                                   // Essai case suivante  

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



  // TempsPhaseOn = pulseIn(CAPTPHASE, HIGH);       // Mesure la durée de l'impulsion haute du capteur de Phase
  // TempsPhaseOff = pulseIn(CAPTPHASE, LOW);       // Mesure la durée de l'impulsion basse du capteur de Phase
  // TempsParTour = ((TempsPhaseOn + TempsPhaseOff)/2);      // Calcul temps par tour avec capteur de phase = (état haut + état bas) / 2
  // Serial.print(TempsParTour);           // Essai Envoyer Temps par tour
  // Serial.print(",");                    // Essai case suivante 

  // if (digitalRead(ALL) == LOW);                     // Si l'allumage passe à 0 V (début de charge bobine)
  // {Allumage = 1;   }                                // Allumage passe à 1
  // if (digitalRead(ALL) == HIGH && Allumage == 1);   // Si allumage est à 1 et que l'entrée passe au niveau haut = moment de l'allumage
  // {TempsAll = micros();                             // Prise du temps écoulé au moment de l'allumage
  // Allumage = 0;  }                                  // Allumage repasse à 0

  // Serial.print("T_ALL=");             // Essai
  // Serial.print(TempsAll);             // Essai Envoyer temps allumage
  // Serial.print(",");                  // Essai case suivante  

  // if (digitalRead(PMHAvant) == HIGH);  {            // Si l'info PMH cylindre avant passe à l'état 1
  // TempsPMHAV = micros();  }                         // Prise du temps écoulé au moment du PMH

  // Serial.print("T_PMHAV=");           // Essai
  // Serial.print(TempsPMHAV);           // Essai Envoyer Temps du PMH
  // Serial.print(",");                  // Essai case suivante 

  // AvanceAllumage = (float (TempsPMHAV - TempsAll) / TempsParTour) * 36000;  // Calculez l'angle en degrés en fonction du temps entre Allumage et PMH point mort haut

  // // Serial.print("AvAll=");             // Pour essai Envoi texte
  // Serial.print(AvanceAllumage);       // Envoyer l'angle d'avance à l'allumage
  // Serial.print(",");                  // case suivante
  // delay(Attente);                     // Attendre avant de mesurer la prochaine série
} 

Oui, enfin, digitalRead() n'est pas réputé pour sa vélocité. Donc ça doit introduire pas mal d'erreur dans la mesure.
Il faudrait essayer avec la librairie digitalReadFast().

Merci pour l'info, alors j'ai essayé avec digitalReadFast pour All et PMHAvant mais ce n'est pas mieux apparemment.

Alors j'ai 4 us au lieu de 8 us c'est la différence entre Fast et normal, c'est comme si ça essayait de mesurer le front montant 2 fois, et pas le créneau.
Pourtant j'ai bien mis HIGH pour l'allumage qui se produit avant et LOW pour le PMHAvant qui arrive après (540 us).

  if (digitalReadFast(ALL) == HIGH);                   // Essai lecture rapide
  // if (digitalRead(ALL) == HIGH);                      // Essai simulation Si l'entrée ALL passe au niveau haut = moment de l'allumage
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage
  // delayMicroseconds(10);                              // Essai délai pour avoir une mesure plus juste, pas correct

  // if (digitalRead(PMHAvant) == HIGH);               // Si l'info PMH cylindre avant passe à l'état 1 (cas normal)
  if (digitalReadFast(PMHAvant) == LOW);            // Essai lecture rapide  
  // if (digitalRead(PMHAvant) == LOW);                  // Essai simulation Si l'info PMH cylindre avant passe à l'état bas on a PMH cyl avant 
  {  TempsPMHAV = micros();  }                        // Prise du temps écoulé au moment du PMH

Ah mais micro() ne mesure pas avec un pas 1 µs, de mémoire je dirai que micro à un pas de 4 µs, à vérifier.

Oui merci pour l'info, je comprends, mais je ne suis pas à 4 us, là je mesure 4 ou 8 us pour un créneau mesuré avec pulseIn et à l'oscilloscope d'environ 540 us, c'est ça que je ne comprends pas.
Si je regarde les temps avec des serialPrint effectivement la différence est bien de 4 ou 8 us.

J'ai mis le signal PMH sur A5, j'ai cru que ça pouvait poser problème je l'ai mis sur D2, et c'est pareil.
J'ai mis un petit condo sur le signal, ça ne change rien, j'ai mis des fils les plus courts possible, j'ai regardé à l'oscillo : il n'y a pas de rebonds, c'est un peu instable en durée, c'est ce qui sort de l'autre Nano avec ArduStim, mais bon pulseIn le mesure sans problème.
540 us c'est quand même très différent de 4 ou 8 us.

Alors pour m'amuser ( ! ) j'ai mis HIGH au lieu de LOW pour PMHAvant et bien ça me donne la même chose 4 us, je trouve ça très étrange, il y a vraiment quelque chose qui m'échappe !!

  if (digitalReadFast(ALL) == HIGH);                   // Essai lecture rapide
  // if (digitalRead(ALL) == HIGH);                      // Essai simulation Si l'entrée ALL passe au niveau haut = moment de l'allumage
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage
  // delayMicroseconds(10);                              // Essai délai pour avoir une mesure plus juste, pas correct

  // if (digitalRead(PMHAvant) == HIGH);               // Si l'info PMH cylindre avant passe à l'état 1 (cas normal)
  // if (digitalReadFast(PMHAvant) == LOW);               // Essai lecture rapide  
  if (digitalReadFast(PMHAvant) == HIGH);               // Essai lecture rapide avec HIGH au lieu de LOW 
  // if (digitalRead(PMHAvant) == LOW);                  // Essai simulation Si l'info PMH cylindre avant passe à l'état bas on a PMH cyl avant 
  {  TempsPMHAV = micros();  }                        // Prise du temps écoulé au moment du PMH

Mais à la limite je pense que c'est normal les 2 voient le front montant et il n'y a que 4 us de décalage.

Ca me donne l'impression que bien que je mette LOW pour mesurer le temps de PMHAvant, il fait HIGH et donc je n'ai que le temps entre les 2 mesures dans le programme soit 4 us !?
Ce Nano est envoûté ! (ou mon code !)

J'ai essayé avec un autre Nano c'est pareil évidemment.

Par moment j'ai même 0 us au lieu de 4 us, donc il mesure le même événement qui arrive au même moment sur les 2 pins qui sont reliées, alors que je demande le temps au moment du front montant HIGH d'abord et le front descendant LOW, le front descendant du cycle d'après est à 32 ms ce n'est pas celui là qui est mesuré, à aucun moment je peux avoir un LOW en même temps que HIGH normalement, j'avoue que je ne comprends pas comment c'est possible.
Peut-être le fait que les deux entrées soient reliées pour les essais sur table, il faudra que j'essaye en "réel" avec les 2 signaux différents sur les 2 entrées séparées...

La nuit porte conseil !

Bonjour,

Il y a un ; après ton if(), donc si la condition est vraie, le if va exécuiter une instruction vide. L'instruction suivante sera toujours exécutée.
Enlève le ; après les if()

  if (digitalRead(ALL) == HIGH)                      // Essai simulation Si l'entrée ALL passe au niveau haut = moment de l'allumage
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage

@kamill oeil de lynx :grinning:

Bonjour et un grand merci kamill !

Tellement l'habitude de mettre des ; en fin de ligne que je n'ai pas fait attention à ça.
Ce matin j'y pensais qu'il pouvait y avoir un problème avec mes if() mais je n'avais absolument pas vu le ; .
C'est un peu vicieux comme erreur, une leçon de plus à retenir.
Encore merci.

Alors après essai le problème est différent !?

 if (digitalRead(ALL) == HIGH)                      // Essai simulation Si l'entrée ALL passe au niveau haut = moment de l'allumage
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage

ça donne TempsAll = 0 à chaque fois, alors que PMHAv évolue normalement par ex 1382716 etc,
avant les 2 étaient quasiment égaux et la différence était égale à 0 ou 4 us, et maintenant c'est presque le contraire...
A l'oscillo bien sûr j'ai toujours un créneau à l'état 1 de 540 us tous les 32 ms.
TempsAll est en A1 et PMHAv en A5

  if (digitalReadFast(ALL) == HIGH)                   // Essai lecture rapide
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage

  if (digitalReadFast(PMHAvant) == LOW)               // Essai lecture rapide  avec un créneau pour simulation
  {  TempsPMHAV = micros();  }                        // Prise du temps écoulé au moment du PMH

  Serial.print(TempsAll);                           // Essai Envoyer Temps allumage
  Serial.print(",");                                // Essai case suivante 

  Serial.print(TempsPMHAV);                         // Essai Envoyer Temps PMH
  Serial.print(",");                                // Essai case suivante  

salut
j'avais fait un petit programme pour jouer avec le chrono entre deux évènements.

il tourne sur uno. je viens de le retester avec un générateur de fréquences en signal carré à 2000hz
le signal ne peut être entré que par D8.
il donne le temps entre deux flancs montants ( soit la période du signal ) . pour 2000Hz, la période est de 500µS. sur le moniteur on voit quelques loupés, (il affiche 2 périodes cumulées).
j'ai laissé (en commentaire) des serial.print qui m'ont permis de suivre et corriger.
tu téléverses le prog tel quel, tu constates comment il fonctionne et après tu joues avec.

#define LED 13
#define poussoir 8
volatile long compteur = 0;
volatile unsigned long nombreCycles = 0;
//unsigned long dureeTotale = 0;
volatile float datePrecedente = 0;
volatile float dateEvent = 0.0;
void setup() {
  pinMode(LED, OUTPUT);
  pinMode(poussoir, INPUT_PULLUP);
  Serial.begin(115200);
  cli();
  TCCR1A = 0;
  TCCR1B = 0b00000101;
  TIMSK1 = 0b00100001;
  TCNT1 = 0;
  ICR1 = 0;
  sei();
}

ISR(TIMER1_OVF_vect)
{
  //digitalWrite(LED, !digitalRead(LED));
  nombreCycles++;//Serial.print(nombreCycles);Serial.print('\t');
}
ISR(TIMER1_CAPT_vect)
{ //cli();
  // date evenement= nbcycles *(65536*0.0625µ)+ICRN*0.0625µ
  dateEvent = nombreCycles * 4096 + ICR1 * 0.0625;
  //Serial.print(datePrecedente);Serial.print('\t');
  Serial.println(dateEvent - datePrecedente, 3); //Serial.print('\t');
  //Serial.println((1000/(dateEvent-datePrecedente)));//Serial.println(F(" Hz"));//);//*60);
  compteur = ICR1;
  datePrecedente = dateEvent; nombreCycles = 0; //TCNT1=0;
  //sei();

  //Serial.println(nombreCycles);
  //Serial.println(dureeTotale);
  //Serial.println(dateEvent);
}
void loop() {
  //
  // Serial.print((dateEvent-datePrecedente),8);Serial.println(" µ Secondes");Serial.flush();

}


Salut dfgh et merci.

Il faudrait que je remplace mon calcul de temps par ton programme.
J'avoue que ça me paraît compliqué, enfin pour moi.

Je dois mesurer le temps entre 2 infos sur 2 entrées différentes, ce temps entre Allumage et PMH je le divise par le temps d'un tour moteur, le tout multiplié par 360° pour avoir l'angle d'avance.

J'aimerais comprendre pourquoi cette partie avec les digitalRead et Temps == micros pose problème.

Ce qui est faux, c'est TempsAll qui est toujours à 0, je cherche où est mon erreur...
(bien vu le ; en trop !)

void CalculAvanceAllumage() {                         // Calcul avance à l'allumage
  for (AvAllumage = 0, k = 0; k < NbBoucle ; k++)       // boucle de mesures
   {

  TempsParTour = ((pulseIn(CAPTPHASE, HIGH) + pulseIn(CAPTPHASE, LOW))/2); // Calcul temps par tour avec capteur de phase = (état haut + état bas) / 2  

  if (digitalReadFast(ALL) == HIGH)                   // Essai lecture rapide
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage

  if (digitalReadFast(PMHAvant) == LOW)               // Essai lecture rapide  avec un créneau pour simulation
  {  TempsPMHAV = micros();  }                        // Prise du temps écoulé au moment du PMH

  Serial.print(TempsAll);                           // Essai Envoyer Temps allumage
  Serial.print(",");                                // Essai case suivante 

  Serial.print(TempsPMHAV);                         // Essai Envoyer Temps PMH
  Serial.print(",");                                // Essai case suivante   

  AvAllumage += (float (TempsPMHAV - TempsAll) / TempsParTour);  // Calculez l'angle en degrés en fonction du temps entre Allumage et PMH point mort haut  
   }

  AvanceAllumage = float (AvAllumage * 360) / NbBoucle;   // Moyenne sur N boucle mesures de l'avance à l'allumage 1 tour 360°  

  Serial.print(AvanceAllumage);       // Envoyer l'angle d'avance à l'allumage
  Serial.print(",");                  // case suivante

Après quelques essais avec mon programme dès que je mets digitalRead == HIGH (et avec digitalReadFast) c'est 0,
si c'est LOW c'est le temps écoulé.
Je peux faire LOW et après HIGH, HIGH après LOW, HIGH après HIGH,
j'ai systématiquement 0 avec HIGH,
j'ai inversé A1 (All) et A5 (PMHAv) pareil
du moment qu'il y a HIGH c'est 0, et pas le temps de micros, ou millis
j'ai fait une erreur mais où ???

Quand j'utilise HIGH ailleurs ça fonctionne comme pulseIn(PMHAvant, HIGH);
c'est bien le bon terme normalement,

le bout de programme

  if (digitalReadFast(ALL) == HIGH)                   // Essai lecture rapide
  // if (digitalReadFast(ALL) == LOW)                    // Essai lecture rapide
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage

  // if (digitalReadFast(PMHAvant) == HIGH)               // Si l'info PMH cylindre avant passe à l'état 1 (cas normal)
  if (digitalReadFast(PMHAvant) == LOW)               // Essai lecture rapide  avec un créneau pour simulation
  {  TempsPMHAV = micros();  }                        // Prise du temps écoulé au moment du PMH

  Serial.print(TempsAll);                           // Essai Envoyer Temps allumage
  Serial.print(",");                                // Essai case suivante 

  Serial.print(TempsPMHAV);                         // Essai Envoyer Temps PMH
  Serial.print(",");                                // Essai case suivante   

J'ai cru avoir trouvé l'erreur j'avais oublié pinMode(PMHAvant,INPUT);
et bien non ça ne change rien.

J'ai mis seulement cette partie dans un programme plus court pour voir ce que ça donne et c'est pareil, HIGH donne 0 à chaque fois


```cpp

```cpp
#include <digitalWriteFast.h> // DigitalWriteFast Library pour utiliser digitalReadFast
// Ne pas modifier Définir les broches pour les entrées et sorties 

const int ALL = A1;        // Numéro du pin où est connectée l'entrée Allumage
const int PMHAvant = A5;   // Numéro du pin pour le top PMH cylindre Avant Essai D2 au lieu de A5 pas de changement

unsigned long TempsPMHAV  = 0;  // Temps au moment du Point Mort Haut du cylindre Avant
unsigned long TempsAll = 0;     // Temps au moment de l'allumage

const unsigned int NombreProg = 4;  // Nombre de fois pour l'éxécution du programme
const unsigned int Attente = 100;   // Pour essai rapide le temps d'attente est limité entre mesures

byte P = 0;           // Compteur pour le nombre de fois que le programme doit être exécuté

void setup() {
  Serial.begin(115200);     // Démarre la communication série à 115200 bauds
  // Serial.begin(9600);        // Démarre la communication série à 9600 bauds

  pinMode(ALL,INPUT);        // Entrée sur A1 bobine allumage
  pinMode(PMHAvant,INPUT);   // Entrée sur A5 PMH cylindre avant

  Serial.println("CLEARDATA");          // On efface les données déjà présentes (donne un beep openoffice calc) parfois est affiché en texte dans le tableau
  delay(Attente);                       // Attendre un peu pour ne pas avoir CLEARDATA dans le tableau, ne fonctionne pas toujours
  // Serial.println("LABEL,U Pap (V),N (tr/mn),T inj (ms),Av all (°)"); // Titre des colonnes dans tableau LibreOffice Calc avec LABEL
  Serial.println("LABEL,T All (us),T PMH (us),T (us),Av all (°)"); // Pour Essai Titre des colonnes dans tableau LibreOffice Calc avec LABEL  
  delay(Attente);             // Attendre un peu pour ne pas avoir 2 fois Label
  Serial.print("DATA,");      // envoi donnée seulement, sans le temps TIME
  delay(Attente);             // Attendre un peu
}

void loop() {

  while (P < NombreProg) {         // les instructions ne seront exécutées que x fois (voir le nombre avec NombreProg)

  if (digitalReadFast(ALL) == HIGH)                   // Essai lecture rapide
  // if (digitalReadFast(ALL) == LOW)                    // Essai lecture rapide
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage

  // if (digitalReadFast(PMHAvant) == HIGH)               // Si l'info PMH cylindre avant passe à l'état 1 (cas normal)
  if (digitalReadFast(PMHAvant) == LOW)               // Essai lecture rapide  avec un créneau pour simulation
  {  TempsPMHAV = micros();  }                        // Prise du temps écoulé au moment du PMH

  Serial.print(TempsAll);                           // Essai Envoyer Temps allumage
  Serial.print(",");                                // Essai case suivante 

  Serial.print(TempsPMHAV);                         // Essai Envoyer Temps PMH
  Serial.print(",");                                // Essai case suivante   

  Serial.println();             // ligne suivante utile ici sinon pas d'envoi
  Serial.print("DATA,");        // utile ici sinon pas d'envoi vers le tableau openoffice calc 

 P++;                        // Augmenter P pour executer que NombreProg fois 
}
}

hello

pour t'aider, il faut l'ensemble de ton prg.

sinon, nous devons le ré-écrire en partie (déclarations...etc)

donc pas possible de tester ton code.

autrement, je t'en ai préparé un autre,

Uno, l'impulsion sur D2 et D3

test à 2000Hz, c'est bien la durée du pulse qui est affichée

saunsigned long deb = 0;
unsigned long fin = 0;

void isr_debut_pulse()
{
  if (!fin) {
    deb = micros(); //si fin ==0
  }
}

void isr_fin_pulse()
{
  if (deb) {
    fin = micros(); //si deb !=0
  }
}
void setup() {
  Serial.begin(115200);
  attachInterrupt(0, isr_debut_pulse, RISING);
  attachInterrupt(1, isr_fin_pulse, FALLING);
}

void loop() {
  cli();
  if (fin) {
    Serial.println(fin - deb);
    fin = 0;
    deb = 0;
  }
  sei();
}

est ce que ca réponds à ce que tu veux faire?
ce n'est que le pulse, mais tu veux aussi le temps entre deux pulses ?

si oui, même montage: UNO, pulse sur D2 et D3 et moniteur sur 2000000
ce programme mesure la durée du pulse et la durée entre deux pulses

unsigned long deb = 0;
unsigned long fin = 0;
unsigned long deb_entre_2 = 0;
unsigned long fin_entre_2 = 0;
void isr_debut_pulse()
{
  if (!fin) {
    deb = micros(); //si fin ==0
  }
  if (deb_entre_2) {
    fin_entre_2 = micros();
  }
}

void isr_fin_pulse()
{
  if (deb) {
    fin = micros(); //si deb !=0
  }
  if (!fin_entre_2) {
    deb_entre_2 = micros();
  }
}
void setup() {
  Serial.begin(2000000);
  attachInterrupt(0, isr_debut_pulse, RISING);
  attachInterrupt(1, isr_fin_pulse, FALLING);
}

void loop() {
  cli();
  if (fin) {
    Serial.print(F("Pulse "));; Serial.println(fin - deb);
    fin = 0;
    deb = 0;
  }
  if (fin_entre_2) {
    Serial.print(F("avance ")); Serial.println(fin_entre_2 - deb_entre_2);
    fin_entre_2 = 0;
    deb_entre_2 = 0;
  }
  sei();
}

j'ai appelé "avance" le temps entre deux impulsions, mais ce n'est peut être pas ça
moniteur en 2000000 car sinon, l'affichage pertube les performances du programme.

si ce n'est toujours as ce que tu veux, repose le problème clairement.

Merci pour ton aide, je ne comprends pas bien comment ça fonctionne avec des interruptions, je n'ai pas le niveau. :woozy_face:
Si je n'arrive pas à le faire avec les digitalRead (ça me paraissait simple au début) je le ferai avec ton programme, j'espère au mieux.

Mon programme, que la partie qui pose problème c'est ce que j'avais mis avant. Il y a tout pour programmer un Nano.

Pour le moment j'essaye avec un signal carré, 100 us à l'état 1 etc soit 5 kHz, et comme avant j'ai digitalRead PMHAvant HIGH à 0 donc des temps complètement erronés, bizarre.

#include <digitalWriteFast.h> // DigitalWriteFast Library pour utiliser digitalReadFast
// Ne pas modifier Définir les broches pour les entrées et sorties 

const int ALL = A1;        // Numéro du pin où est connectée l'entrée Allumage
const int PMHAvant = A5;   // Numéro du pin pour le top PMH cylindre Avant Essai D2 au lieu de A5 pas de changement

unsigned long TempsPMHAV  = 0;  // Temps au moment du Point Mort Haut du cylindre Avant
unsigned long TempsAll = 0;     // Temps au moment de l'allumage

const unsigned int NombreProg = 4;  // Nombre de fois pour l'éxécution du programme
const unsigned int Attente = 100;   // Pour essai rapide le temps d'attente est limité entre mesures

byte P = 0;           // Compteur pour le nombre de fois que le programme doit être exécuté

void setup() {
  Serial.begin(115200);     // Démarre la communication série à 115200 bauds
  // Serial.begin(9600);        // Démarre la communication série à 9600 bauds

  pinMode(ALL,INPUT);        // Entrée sur A1 bobine allumage
  pinMode(PMHAvant,INPUT);   // Entrée sur A5 PMH cylindre avant

  Serial.println("CLEARDATA");          // On efface les données déjà présentes (donne un beep openoffice calc) parfois est affiché en texte dans le tableau
  delay(Attente);                       // Attendre un peu pour ne pas avoir CLEARDATA dans le tableau, ne fonctionne pas toujours
  // Serial.println("LABEL,U Pap (V),N (tr/mn),T inj (ms),Av all (°)"); // Titre des colonnes dans tableau LibreOffice Calc avec LABEL
  Serial.println("LABEL,T All (us),T PMH (us),T (us),Av all (°)"); // Pour Essai Titre des colonnes dans tableau LibreOffice Calc avec LABEL  
  delay(Attente);             // Attendre un peu pour ne pas avoir 2 fois Label
  Serial.print("DATA,");      // envoi donnée seulement, sans le temps TIME
  delay(Attente);             // Attendre un peu
}

void loop() {

  while (P < NombreProg) {         // les instructions ne seront exécutées que x fois (voir le nombre avec NombreProg)

  if (digitalReadFast(ALL) == HIGH)                   // Essai lecture rapide
  // if (digitalReadFast(ALL) == LOW)                    // Essai lecture rapide
  {  TempsAll = micros();  }                          // Prise du temps écoulé au moment de l'allumage

  // if (digitalReadFast(PMHAvant) == HIGH)               // Si l'info PMH cylindre avant passe à l'état 1 (cas normal)
  if (digitalReadFast(PMHAvant) == LOW)               // Essai lecture rapide  avec un créneau pour simulation
  {  TempsPMHAV = micros();  }                        // Prise du temps écoulé au moment du PMH

  Serial.print(TempsAll);                           // Essai Envoyer Temps allumage
  Serial.print(",");                                // Essai case suivante 

  Serial.print(TempsPMHAV);                         // Essai Envoyer Temps PMH
  Serial.print(",");                                // Essai case suivante   

  Serial.println();             // ligne suivante utile ici sinon pas d'envoi
  Serial.print("DATA,");        // utile ici sinon pas d'envoi vers le tableau openoffice calc 

 P++;                        // Augmenter P pour executer que NombreProg fois 
}
}