Gestion d'un lampadaire

Bonjour,

je souhaite avoir un programme pour gérer le fonctionnement d'un lampadaire de la manière suivante :
si un mouvement est détecté alors une led s'allume selon le scénario suivant : LED à 100% de luminosité pendant 10 secondes, ensuite LED à 50% pendant 5 secondes, ensuite LED éteinte.

Dans un second temps, je souhaite que si il y a une nouvelle détection de mouvement on relance le cycle complet d'allumage de la LED. (que le système soit redéclenchable).

Je bloque sur deux points, l'utilisation d'une temporisation non bloquante et le fait qu'un nouveau mouvement relance le cycle d'allumage.

Quelqu'un peut-il m'apporter une solution et des explications ?
Merci d'avance.

Une bonne solution serai de programmer une machine à états, voir par ici:

Le plus rapide serait que tu nous montre sur quoi tu bloque.
pour faire une attente non bloquante dans la loop
il faut par exemple mémoriser le temps de référence dans une variable en appelant la fonction millis, cela peut être fait dans le setup ou sous condition dans la loop.
puis dans la loop tester si le temps courant(appel encore une fois à millis) est supérieur au temps de référence, plus le temps d'attente.
si le test est positif, tu fais ce que tu dois faire.
Pour relancer l'attente automatiquement, tu affectes ta variable de temps de référence avec le temps courant donné encore une fois par millis

Mon programme actuel avec la non gestion du redéclenchement et des temporisations bloquantes :

#define PIR 2
#define LED 3

void setup() 
{
pinMode(PIR, INPUT);
pinMode(LED, OUTPUT);
Serial.begin(9600);
}

void loop() 
{
  if (digitalRead(PIR) == HIGH) // si mouvement détecté
  {
    digitalWrite(LED, HIGH); // allumer LED 
    delay(10000);           // pendant 10 secondes
    analogWrite(LED, 50); // après 10 secondes, allume LED avec une luminosité plus faible
    delay(5000);        // pendant 5 secondes
  }
  else
  {
    digitalWrite(LED, LOW); // si pas de mouvement, LLED éteinte
  }
}

J'essaye avec la fonction millis() mais je n'arrive pas au résultat souhaité

je t'ai fait un truc à l'arrache en wokwi.
Cela va un peu plus loin que l'utilisation de millis, mais c'est compliqué de partir de ton exemple sans passer par une pseudo machine à état comme te l'a indiqué @Jambe.

Le but est que cela te mette le pied à l'étrier pour appliquer le tutoriel de @J-M-L

Merci de ton aide @terwal. J'ai modifié un peu ton programme car il ne réaliser pas la tempo de 5s.

#define PIR 2
#define LED 3

int stateLED = 0;
bool PIRDetect = false;
unsigned long startTimer100 = 0;
unsigned long startTimer50 = 0;
unsigned long time100 = 10000;
unsigned long time50 = 5000;

void setup() 
{
  pinMode(PIR, INPUT);
  pinMode(LED, OUTPUT);
  Serial.begin(115200);
}

void Oldloop() 
{
  // si mouvement détecté
  if (digitalRead(PIR) == HIGH) 
  {
    Serial.println("Mouvement détecté, LED allumée");
    digitalWrite(LED, HIGH);  // allumer LED
    Serial.println("attente 10s");
    delay(10000);  // pendant 10 secondes
    Serial.println("LED 50%, attente 5s");
    analogWrite(LED, 50);  // après 10 secondes, allume LED avec une luminosité plus faible
    delay(5000);           // pendant 5 secondes
  } else 
  {
    Serial.println("LED éteinte");
    digitalWrite(LED, LOW);  // si pas de mouvement, LLED éteinte
  }
}

//Avec un état pour le PIR
void loop() 
{
  PIRDetect = digitalRead(PIR);

  switch (stateLED) 
  {
    case 0:
      if (PIRDetect == HIGH) 
      {
        stateLED = 1;
        startTimer100 = millis();
        digitalWrite(LED, HIGH);  // allumer LED
        Serial.println("Mouvement détecté, LED allumée, attente 10s");
      }
      break;

    case 1:
      if (millis() - startTimer100 > time100) 
      {
        stateLED = 2;
        startTimer50 = millis();
        analogWrite(LED, 50);  // après 10 secondes, allume LED avec une luminosité plus faible
        Serial.println("LED 50%, attente 5s");
      }
      break;

    case 2:
      if (millis() - startTimer50 > time50) 
      {
        stateLED = 0;
        digitalWrite(LED, LOW);  // si pas de mouvement, LLED éteinte
        Serial.println("LED éteinte");
      }
      break;
  }
}

Le problème de l'utilisation d'une temporisation non bloquante est résolu, reste le redéclenchement du cycle à zéro lors d'un nouveau mouvement.

J'ai lu le tutoriel posté par @Jambe, je vais essayer de l'adapter à mon projet pour régler le souci qu'il me reste.

J'ai modifier le wokwi avec la ligne qui manquait et modifié la broche de la LED pour pouvoir utiliser le PWM

Le code que je t'ai fournis applique ton scénario de LED(100% sur 10s et 50% sur 5s) à chaque mouvement devant le PIR, si le scénario est fini.

Pour continuer, il serait bien d'utiliser un enum pour les états comme c'est indiqué dans le tutoriel

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