[Résolu] Contrôler plusieurs relais en même temps.

Bonjour

Je suis débutant et je suis sur un projet assez simple : un “simulateur de présence”.
En gros, je vais intégrer dans une multiprise un arduino nano qui recevra des informations de lumière par une photo-résistance et s’il faut trop sombre (nuit qui s’approche) il activera 3 ou 4 relais sur des périodes aléatoires de temps pour éteindre et allumer des appareils comme une radio, une lampe, une télévision qui seront branchés sur la multiprise.

J’ai appris à me servir de la photo-résistance → OK
J’ai appris à me servir des relais → OK
J’ai appris à me servir de “If… else” → OK

Mon code pour le relais 1 est le suivant, il fonctionne comme espéré :slight_smile: :

if(valeurA0 < 800)                   // Si la valeur retournée en A0 par la photo-résistance descend en dessous de 800 (lumière faible)
{
  digitalWrite(PinRelais1, HIGH);    // Active le relais
  delay (1000+Hasard1);              // Attends 1s + la durée générée au hasard plus haut.
  digitalWrite(PinRelais1, LOW);     // Désactive le relais
  delay (Hasard1/3);                 // Attends 1/3 de la durée générée au hasard plus haut.
}

else                                 // Si non (valeurA0 > 800) = lumière forte.

{
  digitalWrite(PinRelais1, LOW);     // Désactive le relais
}

Mon relais 1 est activé par la “pinRelais1” (12 chez moi). J’ai généré un nombre aléatoire dans la valeur long “Hasard1”

Mais je ne voudrais pas que chaque relais doive attendre que le précédent ait suivi son cycle d’allumage et d’extinction pour faire le sien…
Je voudrais que chaque relais suive sa boucle indépendamment… en même temps… ::slight_smile:

Un peu à la façon du bloc de contrôle “Quand je reçois …” dans Scratch (pour ceux qui connaissent) qui peut être utilisé plusieurs fois et donc lancer plusieurs sous-programmes en même temps quand un signal “envoyé à tous…” est lancé. (ici, ce serait la condition (valeurA0 < 800) )

Est-ce possible de dupliquer ce code pour un relais 2 qui serait exécuté “en parallèle”, en même temps ?

Merci !

vous faites une attente active. donc vous ne pouvez qu'en controller qu'un

il faut donc traiter cela différement, allez voir les tutos eskimon sur introduire-le-temps avec millis() (à la fin du tuto, "Les limites de la fonction delay()")

il y a aussi l'exemple bien documenté BlinkWithoutDelay (en anglais)

Super, je vais aller voir ça...

Merci !

Super !
Merci beaucoup pour les infos !!! :slight_smile:

Ça marche parfaitement maintenant avec la fonction millis();
Elle va me rendre plein de services dans mes futurs projets !

Je donne mon code (fonctionnel, mais améliorable…) pour ceux que ça intéresse !

void loop()
{
// On peut choisir, pour chaque fonction "random", une fourchette différente selon l'appareil à brancher... Pour une lumière : entre 3 et 5 min, pour une TV : entre 15 et 30 min...

  long Hasard1 = random(3000, 12000);  // Initialiser une variable "Hasard1" pour le relais 1 et lui donner une valeur générée au hasard entre 3 et 12s...
                                       // Doc : http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.Random
                                       // "int" doit être compris entre -32 768 à +32 767 alors en ms, "Hasard1" sera vite au dela...
                                       // "long" doit être compris entre-2 147 483 648 à +2 147 483 647 -> et là, ça loge !
  long Hasard2 = random(6000, 24000);  // Initialiser une variable "Hasard2" pour le relais 2 et lui donner une valeur générée au hasard entre 6 et 24s...
                             
  long Hasard3 = random(18000, 36000);  // Initialiser une variable "Hasard3" pour le relais 3 et lui donner une valeur générée au hasard entre 18 et 36s...
  
                                        // Pas de hasard pour le relais 4 --> l'appareil restera toujours allumé quand il fait nuit.
                                       
   valeurA0 = analogRead(A0);           // Mesure la tension de la broche A0



  if(valeurA0 < 800)                        // Si la valeur retournée en A0 par la photo résistance descend en dessous de 800 (lumière faible)
  {
    unsigned long curMil = millis();        // Mettre le temps actuel du chrono interne dans la variable "curMil"
    
 // Commande du relais 1 :

    
      if (curMil - prevMil1 >= Hasard1)      // Si cette valeur est surpérieure de la valeur "Hasard1" à la valeur précédente (s'il s'est écouplé une seconde...)
      {
      
      prevMil1 = curMil;                     // Alors mets dans prevMil la nouvelle valeur du chrono (pour préparer la prochaine boucle.)

        if (rel1State == LOW)             // Si le relais 2 était désactivé
        {
        rel1State = HIGH;                 // Tu l'activeras
        }

        else                              // Sinon (s'il était activé...)
        {
        rel1State = LOW;                  // Tu le désactiveras
        }
      }
      
      
 // Commande du relais 2 :

      
      if (curMil - prevMil2 >= Hasard2)      // Si cette valeur est surpérieure de la valeur "Hasard2" à la valeur précédente (s'il s'est écouplé une seconde...)
      {
      
      prevMil2 = curMil;                     // Alors mets dans prevMil la nouvelle valeur du chrono (pour préparer la prochaine boucle.)

        if (rel2State == LOW)             // Si le relais 2 était désactivé
        {
        rel2State = HIGH;                 // Tu l'activeras
        }

        else                              // Sinon (s'il était activé...)
        {
        rel2State = LOW;                  // Tu le désactiveras
        }
      }

// Commande du relais 3 :

      if (curMil - prevMil3 >= Hasard3)      // Si cette valeur est surpérieure de la valeur "Hasard2" à la valeur précédente (s'il s'est écouplé une seconde...)
      {
      
      prevMil3 = curMil;                     // Alors mets dans prevMil la nouvelle valeur du chrono (pour préparer la prochaine boucle.)

        if (rel3State == LOW)             // Si le relais 2 était désactivé
        {
        rel3State = HIGH;                 // Tu l'activeras
        }

        else                              // Sinon (s'il était activé...)
        {
        rel3State = LOW;                  // Tu le désactiveras
        }
      }

// Pas de condition d'activation pour le relais 4 : il s'active quand il fait nuit et se désactive quand il fait jour.
// Il y a des moments où le hasard fait que tout s'éteint et ce n'est pas naturel... Il faut laisser une "présence".
        
// Activer ou désactiver les pin de sortie qui commandent les relais selon les valeurs actuelles de "relXState"

      digitalWrite(pinRelais1, rel1State);
      digitalWrite(pinRelais2, rel2State);
      digitalWrite(pinRelais3, rel3State);
      
      delay(1000);                          // Pour éviter un clignotement en cas de nuages en fin et début de journée (lumière qui s'allume et s'éteint toutes les 3s...
      digitalWrite(pinRelais4, HIGH);       // L'appareil restera toujours allumé quand il fait nuit.
      
  }

  else                                  // Si non (valeurA0 > 800) = lumière forte.
  {
    
// Désactive tous les relais :
    digitalWrite(pinRelais1, LOW);      // Désactive le relais 1
    digitalWrite(pinRelais2, LOW);      // Désactive le relais 2
    digitalWrite(pinRelais3, LOW);      // Désactive le relais 3
    
    delay(1000);                        // Pour éviter un clignotement en cas de nuages en fin et début de journée. (Lumière qui s'allume et s'éteint toutes les 3s...)
                                        // À mettre devant les 4 activations/désactivations de relais. Utiliser l'une des variables "HasardX" à la place d'un temps fixe ?
    digitalWrite(pinRelais4, LOW);      // Désactive le relais 4
  }

→ Code complet en pièce jointe.

Photo-rési+LCDi2C+4Relais+millis-V1.txt (10.7 KB)

bravo - reste plus qu'à presser ctrl-T dans l'IDE pour que le texte soit bien indenté histoire que ce soit sympa à lire.

Je ne connaissais pas le formatage automatique... Crtl + T

C'est très pratique :-)

Merci encore !!!