Comment prendre en compte un changement d'état après X millisecondes

Bonjour a tous,

Je suis vraiment pas un expert, mais j’arrive généralement a me débrouiller, parfois après des heures de recherches, mais la je bloque depuis des jours.

Dans mon projet j’utilise une LDR pour détecter le levé du jour, et la tombé de la nuit. Mon programme fonctionne avec des changement d’états fini. Je vous copie ci dessous un extrait du code ou je souhaiterais ajouter une fonction pour calculer un délais. Par exemple une fois le seuil couché du soleil atteint, je souhaiterais qu’un compteur démarre et qu’après 30minutes par exemple le changement d’état soit validé. car si des phares de voiture, ou des nuages assombrisse trop, le changement d’état change trop souvent…

Pouvez vous m’apporter de l’aide svp, et merci par avance…

void checkLDR()
{
// lire LDR
LdrReading = analogRead(INPUT_LDR);

// définir des seuils LDR

if (LdrReading < SeuilJour)
{
// Il fait jour = eteint la LED d’indication detection nuit
digitalWrite(OUTPUT_LED_LDR, LOW);
currentLightLevel = HIGH;
}

else if (LdrReading > SeuilNuit)
{
// Il faut nuit = allumer la LED d’indication detection nuit
digitalWrite(OUTPUT_LED_LDR HIGH);
currentLightLevel = LOW;
}
}

//==============================================================================================
void checkForDaylightCHange()
{
// check changement d’état LDR
if (previousLightLevel != currentLightLevel)
{
previousLightLevel = currentLightLevel;

if (currentLightLevel == HIGH)
{
stateTransition(LEVE_SOLEIL);
}
else if (currentLightLevel == LOW)
{
stateTransition(COUCHE_SOLEIL);
}
}
}

If you can’t post in English, when posting in the English section, why should anyone bother trying to help you?

seems that you want to make sure your LDR detects light for a minimum of 30 mins before fully recognizing daylight.

as long as the LDR doesn't detect light, reset a timestamp. When the LDR detects light, test if the 30 minutes has passed with the LDR always detecting light

call isDaylight() with the LDR output (lightLevel == HIGH when there is light)

#define MINS_30    (30*60*1000)
int
isDaylight (
int lightLevel )
{
    static unsigned long msecLst = 0;
           unsigned long msec    = millis ();

    if (LOW == lightLevel)
        msecLst = msec;

    else if (msec - msecLst >= MINS_30)
        return 1;

    return 0
}

Would be safer with #define MINS_30    (30UL*60UL*1000UL)or at least one UL on 30 to ensure there is no overflow on integer and the function would be better off returning true or false as Boolean and possibly a threshold test on light level rather than == LOW if (lightLevel > lowThreshold ) using > or < depending on how the level works is dark a low or high value

Édit ah le post est passé dans la section francophone

Hello, sorry with the automatic translation of google chrome, I did not realize that I posted on the English forum. With apologies...

And thank you for your help despite my error. I will look at the proposal in the afternoon.

Rebonjour,

J’ai essayé d’implémenter le code ci dessus, mais ça ne fonctionne toujours pas. Pourriez vous m’apporter un peux plus de précision.

J’ai oublié de préciser dans mon post initial, j’ai réussi a utiliser la fonction millis(), mais que partiellement.

Par exemple la nuit tombe, la tempo démarre, puis active la fonction et ferme la porte. si je force un changement d’état en approchant une source de lumière avant le délais de tempo ça fonctionne bien, cepenant une fois la tempo dépassé, dès que j’approche une source de lumière, l’ouverture est instantané… logique car la tempo est dépassé, mais comment forcer cette tempo a chaque changement d’état par rapport a mon code existant, ou dois je reprendre l’intégralité de mon code ?

en gros voila ce que j’ai fait :

void checkLightSensor()
{
  // read photocell level
  lightSensorReading = analogRead(INPUT_lightSensor);
  
  // envoyé des données lightSensor au port série pour vérifier les lectures
  // et ajustez les tenons clair / foncé si nécessaire.
  if(LightSensorAdjust == 1) Serial.println(lightSensorReading);
  
  
 // définir des seuils photocels
  if (lightSensorReading < daylightTreshold)
  {
   
    // Il fait jour
    // eteint la LED Sun_Up
    digitalWrite(OUTPUT_LED_lightSensor, LOW);

        currentLightLevel = HIGH;
            tempoDepart = millis();
  }
  else if (lightSensorReading > darknessTreshold)
  {
    
    // Il commence à faire sombre
    // allume la LED Sun_Up
    digitalWrite(OUTPUT_LED_lightSensor, HIGH);
          currentLightLevel = LOW;
              tempoDepart = millis();
  }
}

//==============================================================================================
void checkForDaylightCHange()
{
  // check for change in light level
  if (previousLightLevel != currentLightLevel)
  {
    previousLightLevel = currentLightLevel;

    if ((currentLightLevel == HIGH) && ((millis() - tempoDepart) >= Tempo_luminosite))
    {
     // delay(6000);
      stateTransition(SUN_UP);
      
    }
    else if (currentLightLevel == LOW) && ((millis() - tempoDepart) >= Tempo_luminosite))
    {
      //delay(900000);
      stateTransition(SUN_DOWN);
    }
  }
}

Merci beaucoup pour votre aide…

the code you posted seems to continually check for daylight and darkness. I assume detecting darkness is easier and not likely to be falsely triggered like car headlights.

so i suggested code for only recognizing daylight and when daylight is recognized there is a change in state and some other method used to recognize darkness.

if (Dark == state)
    state = isDaylight (DaylightThreshold < getLightLevel());
else
    state = ???    //  (DaylightThreshold > getLightLevel())

the code i posted simply return a binary. It resets a timestamp whenever the lightLevel is LOW. your code needs to pass it a boolean. of course you can use a similar approach for recognizing darkness

c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

voici à quoi pourrait ressembler votre machine:


il y a deux évènements

  • changement de luminosité
  • 15 minutes écoulées

Vous devriez écrire une fonction qui retourne si la luminosité est faible ou forte (avec un écart entre les deux seuils)

Lors de certaines transitions il faut noter l'heure ou piloter le moteur.

L'ouverture et la fermeture de porte peuvent être elles mêmes des machines à état si vous avez des fin de course et que vous souhaitez que le code fasse autre chose pendant le mouvement du moteur.

la loop ne fait que gérer la machine et les transitions d'états.