Problème d'inversion sur la durée d'allumage de mon capteur !

Bonjour à tous,

En ce temps de confinement, j'espère trouver une âme charitable pour résoudre mon problème.
Jeune encore dans la programmation, cela fait un après midi que je bloque sur cette équation !

Mon projet final est un détecteur de présence et récupérer les données via un émetteur récepteur 433.
Les données que je veux récupérer sont le nombre de détections / jour ainsi que les différentes durées.

Je suis au stade de vouloir récupérer la durée de la détection.
Et mon problème est que je récupère uniquement la durée entre 2 détections !!!
j'ai beau me creuser la tête mais là, ca commence à fumer sérieusement...!

Ci-joint, le programme.
Merci de m'aiguiller et de me corriger !

Vous en remerciant par avance.

Sylvain,

const int capteur = 8;
const int ledPin = 4;
unsigned long dureeAllumage = 0;
unsigned long deb = 0;
int nombreDeDetection = 0;
byte etatCapteur = 1;
byte dernierEtatCapteur = 0;

void setup() {
  pinMode(capteur, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  deb = millis();
}

void loop() {

  etatCapteur = digitalRead(capteur);
  if (etatCapteur != dernierEtatCapteur) {
    if (etatCapteur == HIGH) {
      dureeAllumage = (millis() - deb);
      deb = millis();
      nombreDeDetection++;
      Serial.print("Nombre de detection: ");
      Serial.println(nombreDeDetection, DEC);
      Serial.println();
      Serial.print ("durée: ");
      Serial.print(dureeAllumage / 1000);
      Serial.println (" secondes");
      digitalWrite(ledPin, HIGH);
    }
    else {
      digitalWrite(ledPin, LOW);
      Serial.println();
      Serial.println("_______________");
      Serial.println();
    }
    dernierEtatCapteur = etatCapteur;
  }
}

Bonjour Sylvain,

Si tu veux savoir combien de temps tu dors, tu ne peux pas le savoir quand tu te couches, mais tu ne le saura que quand tu te lèves le matin. Ici c'est pareil. Au moment ou le capteur change d'état et si il est haut (le moment ou tu te met au lit) il faut bien déclencher le chronomètre par
deb = millis();
mais tant qu'il est haut, tu ne peut rien dire. C'est quand il passe à l'état bas que tu as ce temps (quand tu te réveilles), cela donne quelque chose comme:

const int capteur = 8;
const int ledPin = 4;
unsigned long dureeAllumage = 0;
unsigned long deb = 0;
int nombreDeDetection = 0;
byte etatCapteur = 1;
byte dernierEtatCapteur = 0;

void setup() {
  pinMode(capteur, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  deb = millis();
}

void loop() {

  etatCapteur = digitalRead(capteur);
  if (etatCapteur != dernierEtatCapteur) {
    if (etatCapteur == HIGH) {
      dureeAllumage = (millis() - deb);
      deb = millis();
      digitalWrite(ledPin, HIGH);
    }
    else {
      digitalWrite(ledPin, LOW);
      dureeAllumage = (millis() - deb);
      nombreDeDetection++;
      Serial.print("Nombre de detection: ");
      Serial.println(nombreDeDetection, DEC);
      Serial.println();
      Serial.print ("durée: ");
      Serial.print(dureeAllumage / 1000);
      Serial.println (" secondes");
      Serial.println();
      Serial.println("_______________");
      Serial.println();
    }
    dernierEtatCapteur = etatCapteur;
  }
}

Après il faut que tu ajustes...

Olivier (vileroi est un anagramme)

Un grand merci Olivier

Il faut que j'affine mon raisonnement à l'avenir !

Maintenant, je vais à cela essayer d'ajouter une temporisation à l'état éteint.
Cela afin de limiter le nombre de déclenchements si la personne reste en l'état statique.

A suivre... et merci encore :slight_smile:

ibanezmarshall:
Un grand merci Olivier

Il faut que j'affine mon raisonnement à l'avenir !

Maintenant, je vais à cela essayer d'ajouter une temporisation à l'état éteint.
Cela afin de limiter le nombre de déclenchements si la personne reste en l'état statique.

A suivre... et merci encore :slight_smile:

Teste juste le changement d'état (détection) de ton capteur en mémorisant son état precedent et en le comparant au nouveau :
Si tu te détectes qqch, et encore qqch le tour de loop suivant , c'est vraisemblablement la même chose (sauf si ta loop dure "longtemps" ) :wink:

Bonjour,

De nouveau, je m'en remet à vous ...
J'ai besoin de votre savoir car ma logique n'appartient qu'à moi !

j'ai voulu tester l'idée de Bruno à ma programmation mais échec sur échec...
Je suis encore trop novice pour y arriver...

En reprenant la solution d'olivier sur le calcul de la durée.
j'essai d'ajouter cette durée à ma temporisation mais sans vain...

Je tiens réellement partir de cette temporisation qui me convient et donc arriver à ajouter la durée du capteur en action avec cette temporisation.

Je vous joins mon code pour analyse

Par avance, merci pour votre soutien

Sylvain,

avec le code c'est mieux ! :o
voilà à quoi cela ressemble

int capteur = 8; // Input for HC-S501
int etatCapteur = 1; // Place to store Valeur du capteur
int dernierEtatCapteur = 0;
int nombreDeDetection = 0 ;

int tempoActive = 0; // État d'activation de la tempo
unsigned long tempoDepart = 0; // Temps à l'activation de la tempo

unsigned long dureeAllumage = 0;
unsigned long deb = 0;

void setup() {

  pinMode(4, OUTPUT); // 4 (Gestion de la LED sur carte)
  Serial.begin(9600);
  deb = millis();
}

void loop() {

  etatCapteur = digitalRead(capteur);
  digitalWrite(pinMode, etatCapteur);


  if (( etatCapteur == HIGH) && (dernierEtatCapteur == LOW))

    if ( digitalRead(capteur) == HIGH ) { // Si la détection est enclenchée
      tempoActive = 1; // Alors on active la temporisation
      tempoDepart = millis();
      digitalWrite(4, HIGH); // 4 (Gestion de la LED sur carte)

    }
  if ( tempoActive ) { // Si la temporisation est active,
    if ( ( millis() - tempoDepart ) >= 3000 ) { // Temps écoulé sans détection autorisé
      tempoActive = 0; // Et on désactive la temporisation pour ne pas afficher ce message une seconde fois
      digitalWrite(4, LOW); // 4 (Gestion de la LED sur carte)

      { nombreDeDetection++;
        Serial.println(nombreDeDetection);
        {
          etatCapteur = digitalRead(capteur);

          if (etatCapteur != dernierEtatCapteur) {
            if (etatCapteur == HIGH) {
              dureeAllumage = (millis() - deb);
              deb = millis();
            }
            else {
              dureeAllumage = (millis() - deb);
              Serial.println(dureeAllumage / 1000);
            }
            dernierEtatCapteur = etatCapteur;
          }
        }
      }
    }
  }
}

Bonjour,
Je n'ai toujours pas trouver la solution à mon projet.
Je tourne en boucle !
Quelqu'un peut-il se pencher sur mon problème.
Je l'en remercie par avance.
Sylvain

  if (( etatCapteur == HIGH) && (dernierEtatCapteur == LOW))

    if ( digitalRead(capteur) == HIGH ) { // Si la détection est enclenchée
      tempoActive = 1; // Alors on active la temporisation
      tempoDepart = millis();
      digitalWrite(4, HIGH); // 4 (Gestion de la LED sur carte)

    }

Il y a très peu de chances pour que le capteur n'était pas actif à la boucle précédente, soirt actif en début de boucle puis deux lignes plus loin ne le soit plus. Le if ( digitalRead(capteur) == HIGH ) est superflu. On peut écrire directement

if (( etatCapteur == HIGH) && (dernierEtatCapteur == LOW)) { // Si la détection est enclenchée
      tempoActive = 1; // Alors on active la temporisation
      tempoDepart = millis();
      digitalWrite(4, HIGH); // 4 (Gestion de la LED sur carte)

    }

Cela ne change rien au fonctionnement

Teste juste le changement d'état (détection) de ton capteur en mémorisant son état precedent et en le comparant au nouveau :

Mais c'était déjà fait:
if (etatCapteur != dernierEtatCapteur) {

  if ( tempoActive ) { // Si la temporisation est active,
    if ( ( millis() - tempoDepart ) >= 3000 ) { // Temps écoulé sans détection autorisé
      tempoActive = 0; // Et on désactive la temporisation pour ne pas afficher ce message une seconde fois
      digitalWrite(4, LOW); // 4 (Gestion de la LED sur carte)

      { nombreDeDetection++;

Pourquoi ce { devant nombreDeDetection++; on dirait qu'il manque in if.... il y en a un autre pareil un peu plus loin, en les supprimant (même effet pour la compilation:

  if ( tempoActive ) { // Si la temporisation est active,
    if ( ( millis() - tempoDepart ) >= 3000 ) { // Temps écoulé sans détection autorisé
      tempoActive = 0; // Et on désactive la temporisation pour ne pas afficher ce message une seconde fois
      digitalWrite(4, LOW); // 4 (Gestion de la LED sur carte)

      nombreDeDetection++;
      Serial.println(nombreDeDetection);

      etatCapteur = digitalRead(capteur);

      if (etatCapteur != dernierEtatCapteur) {
        if (etatCapteur == HIGH) {
          dureeAllumage = (millis() - deb);
          deb = millis();
        }
        else {
          dureeAllumage = (millis() - deb);
          Serial.println(dureeAllumage / 1000);
        }
        dernierEtatCapteur = etatCapteur;
      }
    }
  }

Avant d'aller plus loin, j'ai besoin de savoir le rôle de la temporisation. Elle sert si on détecte trop longtemps? Ellesert si il n'y a personne?...

Bonjour Olivier et merci encore pour ton1

Salut ,

si tu veux recuperer un temps d' activation , il faut declarer une variable qui s' incremente a chaque tour de boucle et qui ne se fige qu ' apres un retour a l ' etat non detecté du capteur .
Pour plus de clarté , j ' aurais besoin de quelques precisions sur la variable dureeAllumage , c ' est la valeur que tu cherches a recuperer ?

Je vais analyser ta réponse pour mieux comprendre le processus.

La temporisation doit permettre de relancer le capteur à l'état haut sans pour autant comptabiliser 1 passage supplémentaire si une détection est de nouveau active durant cette temporisation de 3 secondes.

Ainsi, je souhaite totaliser le nombre de passage et connaître la durée du capteur.

Si pas de détection de nouveau active durant 3 secondes
= 1 passage + durée du capteur 1

Si détection durant les 3 secondes de temporisation
= 1 passage + durée ( capteur 1+ temps de temporisation +capteur1, etc..)

Merci Olivier par avance,
Sylvain,

regarde le code , j ' ai simplifié car il y avait trop de redondance dans tes conditions , alors il compile , mais ne fera certainement pas ce que tu desires .
Au niveau de ton code , il y avait une erreur aussi : cette ligne n ' est pas bonne :digitalWrite(pinMode, etatCapteur);
si c' est pour eclairer la LED qui n' apparait pas dans ce programme , c' est : digitalWrite(4, etatCapteur);
si c' est pour le capteur , c ' est une entrée Tout Ou Rien , on lui dit pas de se mettre dans un etat , on lit juste l ' etat dans lequel il est .

Pär contre , j ' ai mis de commentaires qui t ' indique la structure de base de la boucle .

il suffit certainement de deplacer " les trucs " au " bon endroit " :

int capteur = 8; // Input for HC-S501
bool etatCapteur = 1; // Place to store Valeur du capteur
int dernierEtatCapteur = 0;
int nombreDeDetection = 0 ;

int tempoActive = 0; // État d'activation de la tempo
unsigned long tempoDepart = 0; // Temps à l'activation de la tempo

unsigned long dureeAllumage = 0;
unsigned long deb = 0;
unsigned long tempsTotalDetection = 0;


void setup() {
  pinMode(4, OUTPUT); // 4 (Gestion de la LED sur carte)
  Serial.begin(9600);
  deb = millis();
}

void loop() {
  etatCapteur = digitalRead(capteur);
  
	if (( etatCapteur ) && ( ! dernierEtatCapteur )) { // ici , on a detecté une presence
		tempoActive = 1; // Alors on active la temporisation
		tempoDepart = millis();
		digitalWrite(4, HIGH); // 4 (Gestion de la LED sur carte)  pas de LED declaré dans le programme ?

		if ( millis() - tempoDepart >= 3000 ) { // Temps écoulé sans détection autorisé
		
			if (etatCapteur != dernierEtatCapteur) { // ici ,  il y a un changement d' etat du capteur  , donc on a plus de presence
				tempoActive = 0; // Et on désactive la temporisation pour ne pas afficher ce message une seconde fois
				digitalWrite(4, LOW); // 4 (Gestion de la LED sur carte

				dureeAllumage = (millis() - tempoDepart);
				Serial.println(dureeAllumage / 1000);
				nombreDeDetection++;
				Serial.println(nombreDeDetection);
			}
			else { // ici ,  le capteur ne change pas d' etat , logiquement on n ' a pas grand chose a faire la presence est toujours detecte
				
			}
			 // ici , ce qu on fait a chaque tour de boucle dans tous les cas
			//relancé le chrono par exemple 
			tempsTotalDetection += dureeAllumage;
			Serial.println(tempsTotalDetection);
		}
	}
}

Bine vu pour digitalWrite(pinMode, etatCapteur);

Mais désolé @iznobe mais je ne suis pas du tout d’accord avec ton code.
Le code de la bocle loop est exécuté seulement si
(( etatCapteur ) && ( ! dernierEtatCapteur )) est vrai
On ne pourra pas compter si la personne est partie.


Sans la tempo, c’est “facile”:
Si (capteur vient de passer de 0 à 1) → démarrage du compteur
Si (capteur vient de passer de 1 à 0) → arrêt du compteur et mémorisation.

Si on met une temporisation, on ne peut plus compter quand le capteur passe à 0, il va falloir attendre les 3s…

Dans ce cas, la méthode de la machine à état doit donner une solution simple. On a quand même pas mal d’états différents:
→ rien ni personne depuis longtemps
→ une personne vient de passer, alors qu’on avait vu personne depuis longtemps
→ une personne vient de passer, mais on avait vu quelqu’un il y a moins de 3s
→ il n’y a personne depuis peu.

Merci messieurs pour ces synthèses.
Je méditerai demain sur celles-ci avec l'espoir d'arriver à mes fins...

J'ai deux programmes qui sont fonctionnels mais difficile pour moi de n'en faire qu'un.
Je pense donc que la solution est de mettre les lignes de commandes au bon endroit pour ainsi bien respecter les boucles mais je me trompe encore peut-etre...
Je vous tiens informé de mon avancé.

Merci encore à vous.
Sylvain,

La nuit et le jardinage portent conseils. Je change d'avis comme un membre de gouvernement.

De quoi a-t-on besoin?
Il faut deux compteurs de temps:

  • un pour comptabiliser le temps de passage
  • un pour la temporisation de 3s

Que faut-il mémoriser?

  • le temps du début de la présence deb, que je vais renommer en passageDebut, vu qu'avec les 2 compteurs de temps il y a 2 débuts
  • le temps de fin de passage passageFin
  • le temps de début des 3s tempoDebut
    Ce n'est pas la peine de de mémoriser la fin, on n'en a plus besoin quand c'est fini
  • Si on est pendant ou pas la temporisation tempoActive
    Les trois premières sont des long non signées, tempoActive est un booléen (vrai on est dans la temporisation, faux on attend)

Je m'étais polarisé sur la personne qui passe, vu que c'est ce qui a été fait au début sans le temporisateur des 3s: on arrête le tout quand le capteur ne détecte plus.

En mettant une temporisation de 3s, l'arrêt complet ne se fait plus par les infos du capteur, mais à la fin de la temporisation de 3s. Les évènements qui doivent nous intéresser c'est donc:

  • présence d'une personne
  • dans ou en dehors de la temporisation.

Voici les actions à réaliser:

  • initialisation tempoActive est initialisé à faux
  • lecture du bouton
  • si il y a une personne
  • si la temporisation n'est pas active, c'est qu'une personne vient de passer, on note l'heure de début (passageDebut)
  • dans tous les cas on démarre ou on redémarre la temporisation tempoActive et tempoDebut
  • on note aussi l'heure dans passageFin, c'est en fait le dernier instant ou on a vu quelqu'un.
  • si la temporisation est terminée, on mémorise

Cela peut donc faire en essayant de coller le plus à ce qui a été fait:

const int capteur = 8;
const int ledPin = 4;
unsigned long passageDebut;
unsigned long passageFin;
unsigned long tempoDebut;
bool tempoActive=false;
int nombreDeDetections = 0;
byte etatCapteur = 1;

void setup() {
  pinMode(capteur, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  etatCapteur = digitalRead(capteur);
  if (etatCapteur == HIGH) { // Il y a quelqu'un
    if (tempoActive == false) {
	  passageDebut = millis(); // Premier départ
	}
    tempoActive = true; // Démarrage de la temporisation
    tempoDebut = millis();
    passageFin = millis();
  }
  if ((millis() - tempoDebut) > 3000) && tempoActive) { // cela fait 3s que l'on n'a plus vu personne
    nombreDeDetection++;
      Serial.print("Nombre de detections: ");
      Serial.println(nombreDeDetections, DEC);
      Serial.println();
      Serial.print ("durée: ");
      Serial.print((passageFin - passageDebut) / 1000);
      Serial.println (" secondes");
      digitalWrite(ledPin, HIGH);
      Serial.println();
      Serial.println("_______________");
      Serial.println();
      digitalWrite(ledPin, LOW); // Mal placée, elle s'allumera moins d'une milliseconde et on ne le verra pas.  
    }
}

A vérifier...

Remarques:

  • capteur contient le numéro d'une entée -> un mot de 8 bits suffit
  • etatCapteur est en fait un booléen et je vois:
    byte etatCapteur = 1; et if (etatCapteur == HIGH)
    mieux: bool etatCapteur = HIGH; et if (etatCapteur == HIGH)
  • if (etatCapteur == HIGH) peut aussi s'écrire if (etatCapteur) car etatCapteur est un booléen
  • etatCapteur n'a pas besoin d'être initialisé, vu qu'avant de l'utiliser on a etatCapteur = digitalRead(capteur);
  • etatCapteur n'est utilisé qu'une seule fois, on peut s'en passer et le remplacer par digitalRead(capteur)
  • les deux lignes
    tempoDebut = millis();
    passageFin = millis();
    peuvent s'écrire en une seule:
    tempoDebut = passageFin = millis();
    et cela se lit je mets millis dans passageFin et ce que j'ai mis dans passageFin je le mets dans tempoDebut. Cela ne fait plus qu'un seul appel à millis(), mais il est possible que le compilateur fasse cette simplification tout seul.
  • Serial.println(nombreDeDetections, DEC);
    le DEC est par défaut, on peut l'ommettre
  • on peut concatener intellectuellent les trois chaînes affichées pour n'en faire qu'une seule:
    Serial.println();
    Serial.println("");
    Serial.println();
    peut devenir:
    Serial.println("\n
    \n");
    \n est le caractère retour à la ligne.
  • si on a qu'une chose à faire dans un if les {} ne srvent à rien et au lieu de
    if (tempoActive == false) {
    passageDebut = millis(); // Premier départ
    }
    on peut écrire:
    if (tempoActive == false)
    passageDebut = millis(); // Premier départ
    ou encore
    if (tempoActive == false) passageDebut = millis(); // Premier départ

Le code peut devenir:

const uint8_t capteur = 8,
              ledPin = 4;
uint16_t passageDebut,
         passageFin,
         tempoDebut,
         nombreDeDetections = 0;
bool tempoActive=false;

void setup() {
  pinMode(capteur, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(capteur)) { // Il y a quelqu'un
    if (tempoActive == false)  passageDebut = millis(); // Premier départ
    tempoActive = true; // Démarrage de la temporisation
    tempoDebut = passageFin = millis();
  }
  if ((millis() - tempoDebut) > 3000) && tempoActive) { // cela fait 3s que l'on n'a plus vu personne
    nombreDeDetection++;
      Serial.print("Nombre de detections: ");
      Serial.println(nombreDeDetections, DEC);
      Serial.print ("\ndurée: ");
      Serial.print((passageFin - passageDebut) / 1000);
      Serial.println (" secondes\n\n"_______________\n");
      digitalWrite(ledPin, HIGH);
      digitalWrite(ledPin, LOW); // Mal placée, elle s'allumera moins d'une milliseconde et on ne le verra pas.  
    }
}

Reste à voir ce que tu veux faire de la led (elle s'allume quand? Elle s'éteint quand?

Merci pour le temps passé à vouloir solutionner mon problème…

Malheureusement, le code n’abouti pas au résultat escompté.
Lors du premier passage sous le capteur, la durée se lance et ne s’arrête plus.
Et une incrémentation de 3 lors de chaque passage sous le capteur.

Idem pour le code Iznobe.

N’y a t’il pas un moyen plus simple à partir du code ci-dessous casi fonctionnel…?
car l’état, temporisation , led et compteur fonctionne parfaitement.

Quant à la durée que je recherche…
A ce stade et lors de chaque déclenchement du compteur, celui-ci calcul la durée du capteur actif + la totalité du temps inactif précédent le dernier état actif.
Il ne reste donc plus qu’à arriver à déduire ce temps d’inactivité pour connaitre cette fameuse durée !!!

Ne Pourrait-on pas dés que le processus est à l’état LOW arriver à déclencher un autre compteur pour connaitre la durée d’inactivité et ainsi et la déduire de mon résultat de l’heure actuelle ?

Ça parait si simple !!!

J’ai le sentiment que nous ne sommes pas loin du but mais que le chemin reste encore long !

Sylvain,

int capteur = 8; // Input for HC-S501
bool etatCapteur = 1; // Place to store Valeur du capteur
int dernierEtatCapteur = 0;
int compteur = 0 ;
unsigned long dureeAllumage = 0;
unsigned long deb = 0;


int tempoActive = 0; // État d'activation de la tempo
unsigned long tempoDepart = 0; // Temps à l'activation de la tempo

void setup() {

  pinMode(4, OUTPUT); // 4 (Gestion de la LED sur carte)
  Serial.begin(9600);
  deb = millis();
}

void loop() {

  etatCapteur = digitalRead(capteur);
  digitalWrite(pinMode, etatCapteur);

  if (( etatCapteur == HIGH) && (dernierEtatCapteur == LOW)) {

    tempoActive = 1; // Alors on active la temporisation
    tempoDepart = millis();
    digitalWrite(4, HIGH); // 4 (Gestion de la LED sur carte)

  }
  if ( tempoActive ) { // Si la temporisation est active,
    if ( ( millis() - tempoDepart ) >= 3000 ) { // Temps écoulé sans détection autorisé
      tempoActive = 0; // Et on désactive la temporisation pour ne pas afficher ce message une seconde fois
      digitalWrite(4, LOW); // 4 (Gestion de la LED sur carte)

      dureeAllumage = (millis() - deb);
      deb = millis();



      { compteur++;
        Serial.println(compteur);
        Serial.print(dureeAllumage / 1000);
        Serial.println (" secondes");
      }
      dernierEtatCapteur = etatCapteur;

    }
  }
}

Oups… j’ai oublié d’arrêter la temporisation, tempoActive ne revient jamais à false
Ca doit faire ça en corrigant aussi 2 fautes d’orthographes:

const int capteur = 8;
const int ledPin = 4;
unsigned long passageDebut;
unsigned long passageFin;
unsigned long tempoDebut;
bool tempoActive=false;
int nombreDeDetections = 0;
byte etatCapteur = 1;

void setup() {
  pinMode(capteur, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  etatCapteur = digitalRead(capteur);
  if (etatCapteur == HIGH) { // Il y a quelqu'un
    if (tempoActive == false) {
	  passageDebut = millis(); // Premier départ
	}
    tempoActive = true; // Démarrage de la temporisation
    tempoDebut = millis();
    passageFin = millis();
  }
  if (((millis() - tempoDebut) > 3000) && tempoActive) { // cela fait 3s que l'on n'a plus vu personne
    tempoActive = false; // <- Il faut arrêter la temporisation ############################
    nombreDeDetections++;
      Serial.print("Nombre de detections: ");
      Serial.println(nombreDeDetections, DEC);
      Serial.println();
      Serial.print ("durée: ");
      Serial.print((passageFin - passageDebut) / 1000);
      Serial.println (" secondes");
      digitalWrite(ledPin, HIGH);
      Serial.println();
      Serial.println("_______________");
      Serial.println();
      digitalWrite(ledPin, LOW); // Mal placée, elle s'allumera moins d'une milliseconde et on ne le verra pas. 
    }
}

Dans le code que tu donnes, si le capteur reste à 1, on va trouver 3s. La durée n’est pas réenclenchée.
Le temps sera toujours de 3s.

Le code a été testé (pour une fois), mais sans la led. La led ne devrait pas s’allumer, il faudra voir où on la met.

La durée mesurée est le temps entre le premier passage et le dernier passage.
Si j’ai un passage de 10h00mn00s à 10h00mn01s, à 10h00mn02s 10h00mn05s, j’aurais une durée de 5s correspondant à ce que j’ai compris de

Si détection durant les 3 secondes de temporisation
= 1 passage + durée ( capteur 1+ temps de temporisation +capteur1, etc…)

ibanezmarshall:
Quant à la durée que je recherche...
A ce stade et lors de chaque déclenchement du compteur, celui-ci calcul la durée du capteur actif + la totalité du temps inactif précédent le dernier état actif.
Il ne reste donc plus qu'à arriver à déduire ce temps d'inactivité pour connaitre cette fameuse durée !!!

Ne Pourrait-on pas dés que le processus est à l'état LOW arriver à déclencher un autre compteur pour connaitre la durée d'inactivité et ainsi et la déduire de mon résultat de l'heure actuelle ?

Ça parait si simple !!!

J'ai le sentiment que nous ne sommes pas loin du but mais que le chemin reste encore long !

si c' est le cas , surement qu ' avec une variable + une soustraction ca devrait le faire .

ton code est celui qui comporte une erreur , que j' ai deja signalé en post # 11 !

PS : un bolleen attendu valant false peut aussi s ' ecrire " ! " forme raccourci de == " false " pour villeroi et ses optimisations dans son message precedent :stuck_out_tongue:
par exemple :

if (tempoActive == false)

devient :

if ( ! tempoActive )

A ce stade et lors de chaque déclenchement du compteur, celui-ci calcul la durée du capteur actif + la totalité du temps inactif précédent le dernier état actif.
Il ne reste donc plus qu'à arriver à déduire ce temps d'inactivité pour connaitre cette fameuse durée !!!

quelle variable correspond a " la durée du capteur actif " ?
quelle variable correspond a "la totalité du temps inactif précédent le dernier état actif" ?

il suffit de faire une soustraction avec durée de ce que tu cherches comme resultat :

unsigned long tempsRecherche = dureeTotale - dureeCapteurActif;

Dans le dernier code que tu postes , tu as 2 conditions separées :

  if (( etatCapteur == HIGH) && (dernierEtatCapteur == LOW)) {
    tempoActive = 1; // Alors on active la temporisation
    tempoDepart = millis();
    digitalWrite(4, HIGH); // 4 (Gestion de la LED sur carte)
  }
  
  if ( tempoActive ) { // Si la temporisation est active,
  // plein de trucs 
  }

la 2eme condition , " if tempo active " , est vrai uniquement quand la premiere est vrai car dans la 1ere tu mets : tempoActive = 1;

du coup ca ne sert a rien du tout d' avoir 2 conditions !

on peut donc ne mettre qu ' une seule condition qui englobe tout , de plus la premiere condition : " if (( etatCapteur == HIGH) && (dernierEtatCapteur == LOW)) { " on peut l' ecrire plus simplement :
" if (( etatCapteur ) && ( ! dernierEtatCapteur )) { " .

les accolades seules , n ' ont aucun interet ici , car il n ' y a aucune limite de portee a induire , on peut donc simplement les supprimer .

ce qui nous donne :

int capteur = 8; // Input for HC-S501
bool etatCapteur = 1; // Place to store Valeur du capteur
int dernierEtatCapteur = 0;
int compteur = 0 ;
unsigned long dureeAllumage = 0;
unsigned long deb = 0;


int tempoActive = 0; // État d'activation de la tempo
unsigned long tempoDepart = 0; // Temps à l'activation de la tempo

void setup() {

  pinMode(4, OUTPUT); // 4 (Gestion de la LED sur carte)
  Serial.begin(9600);
  deb = millis();
}

void loop() {

  etatCapteur = digitalRead(capteur);
  digitalWrite(pinMode, etatCapteur);

  if (( etatCapteur) && ( ! dernierEtatCapteur )) {

    tempoActive = 1; // Alors on active la temporisation
    tempoDepart = millis();
    digitalWrite(4, HIGH); // 4 (Gestion de la LED sur carte)

    if ( ( millis() - tempoDepart ) >= 3000 ) { // Temps écoulé sans détection autorisé
      tempoActive = 0; // Et on désactive la temporisation pour ne pas afficher ce message une seconde fois
      digitalWrite(4, LOW); // 4 (Gestion de la LED sur carte)

      dureeAllumage = (millis() - deb);
      deb = millis();

        compteur++;
        Serial.println(compteur);
        Serial.print(dureeAllumage / 1000);
        Serial.println (" secondes");

      dernierEtatCapteur = etatCapteur;
    }
  }
}

ce code , plus simple et plus court , fait exactement la meme chose que ce que tu as posté , d' ailleurs avec la meme erreur a l ' interieur , deja signal" 2 fois .

le code que j' ai posté dans mon message precedent n ' etait pas censé marcher , il etait censé te faire cheminer pour que tu trouves la solution toi-meme .

j ' y ai mis les commentaires qui permettait de bien distinguer les differentes phase de ton programme pendant un tour de boucle afin que tu te rends compte de comment ca se passe et donc de voir distinctement ou placer les choses facilement pour arriver a ton but .

pas un truc tout pret ou tu n' aurais rien compris , et qui tombe tout cuit ...
Si tu relis mon code plusieurs fois et que tu te donnes la peine de comprendre ( et lire ) les commentaires , tu verras que la solution tu trouveras ! :wink:

Messieurs,
J'ai tout repris depuis le début...
Analysé les syntaxes et vos commentaires.
Et cela fonctionne très bien.
Un grand merci pour votre aide.
Sylvain,