Arrêter la fonction millis()

Bonjour à tous,
J'ai une petite quastion concernant la fonction millis().
Je fais l'équivalent d'un "sleep timer" TV pour mon système home cinéma (home-made avec Mega 2560)
Donc, j'ai créé 4 différentes fonctions millis(), pour 60, 90, 120, et 180 minutes.

Mais je me dit que si je veux arrêter ce sleep timer, comment puis-je arrêter la fonction millis() ?

J'ai déjà fait pas mal de recherches, mais je n'ai encore rien trouvé...

Voici une partie du code :

// Sleep 60'

boolean Sleep1On;
unsigned short currentSleep1time = 0;
unsigned short Sleep1_StartMillis;
#define SEUILSleep1 3600000


// Sleep 90'

boolean Sleep2On;
unsigned short currentSleep2time = 0;
unsigned short Sleep2_StartMillis;
#define SEUILSleep2 5400000


// Sleep 120'

boolean Sleep3On;
unsigned short currentSleep3time = 0;
unsigned short Sleep3_StartMillis;
#define SEUILSleep3 7200000


// Sleep 180'

boolean Sleep4On;
unsigned short currentSleep4time = 0;
unsigned short Sleep4_StartMillis;
#define SEUILSleep4 10800000

void setup() {

  Sleep1On = false;
  Sleep2On = false;
  Sleep3On = false;
  Sleep4On = false;
}

void loop(){

  if(inByte == '?') {
    Sleep1_StartMillis = millis();
    currentSleep1time = 0;
    Sleep1On = true;
  }else{
    if(Sleep1On){
      currentSleep1time = millis() - Sleep1_StartMillis;
        if(currentSleep1time > SEUILSleep1){
          Sleep1On = false;
          
          digitalWrite(Led1, HIGH);
          delay(100);
          digitalWrite(Led2, HIGH);
          delay(100);
          digitalWrite(Ampli, HIGH);
          delay(100);
          digitalWrite(Sub, HIGH);
          delay(100);
          digitalWrite(Box, HIGH);
          delay(100);
          digitalWrite(Decoder, HIGH);
          delay(100);
          digitalWrite(Hdmi, HIGH);
          delay(100);
          digitalWrite(VPC, HIGH);
          delay(100);
          digitalWrite(VAMP, HIGH);
          delay(100);
          digitalWrite(Hdd1, HIGH);
          delay(100);
          digitalWrite(Hdd2, HIGH);
          delay(100);
          digitalWrite(Hdd3, HIGH);
          delay(100);
          digitalWrite(Hdd4, HIGH);
          delay(100);
          digitalWrite(Hdd5, HIGH);
          delay(100);
          digitalWrite(Hdd6, HIGH);
          delay(100);
          digitalWrite(a12v, HIGH);
          delay(100);
          
        }
    }
  }


  if(inByte == '!') {
    Sleep2_StartMillis = millis();
    currentSleep2time = 0;
    Sleep2On = true;
  }else{
    if(Sleep2On){
      currentSleep2time = millis() - Sleep2_StartMillis;
        if(currentSleep2time > SEUILSleep2){
          Sleep2On = false;
          
          digitalWrite(Led1, HIGH);
          delay(100);
          digitalWrite(Led2, HIGH);
          delay(100);
          digitalWrite(Ampli, HIGH);
          delay(100);
          digitalWrite(Box, HIGH);
          delay(100);
          digitalWrite(Decoder, HIGH);
          delay(100);
          digitalWrite(Hdmi, HIGH);
          delay(100);
          digitalWrite(VPC, HIGH);
          delay(100);
          digitalWrite(VAMP, HIGH);
          delay(100);
          digitalWrite(Hdd1, HIGH);
          delay(100);
          digitalWrite(Hdd2, HIGH);
          delay(100);
          digitalWrite(Hdd3, HIGH);
          delay(100);
          digitalWrite(Hdd4, HIGH);
          delay(100);
          digitalWrite(Hdd5, HIGH);
          delay(100);
          digitalWrite(Hdd6, HIGH);
          delay(100);
          digitalWrite(a12v, HIGH);
          delay(100);
          
        }
    }
  }


  if(inByte == '*') {
    Sleep3_StartMillis = millis();
    currentSleep3time = 0;
    Sleep3On = true;
  }else{
    if(Sleep3On){
      currentSleep3time = millis() - Sleep3_StartMillis;
        if(currentSleep3time > SEUILSleep3){
          Sleep3On = false;
          
          digitalWrite(Led1, HIGH);
          delay(100);
          digitalWrite(Led2, HIGH);
          delay(100);
          digitalWrite(Ampli, HIGH);
          delay(100);
          digitalWrite(Box, HIGH);
          delay(100);
          digitalWrite(Decoder, HIGH);
          delay(100);
          digitalWrite(Hdmi, HIGH);
          delay(100);
          digitalWrite(VPC, HIGH);
          delay(100);
          digitalWrite(VAMP, HIGH);
          delay(100);
          digitalWrite(Hdd1, HIGH);
          delay(100);
          digitalWrite(Hdd2, HIGH);
          delay(100);
          digitalWrite(Hdd3, HIGH);
          delay(100);
          digitalWrite(Hdd4, HIGH);
          delay(100);
          digitalWrite(Hdd5, HIGH);
          delay(100);
          digitalWrite(Hdd6, HIGH);
          delay(100);
          digitalWrite(a12v, HIGH);
          delay(100);
          
        }
    }
  }


  if(inByte == '+') {
    Sleep4_StartMillis = millis();
    currentSleep4time = 0;
    Sleep4On = true;
  }else{
    if(Sleep4On){
      currentSleep4time = millis() - Sleep4_StartMillis;
        if(currentSleep4time > SEUILSleep4){
          Sleep4On = false;
          
          digitalWrite(Led1, HIGH);
          delay(100);
          digitalWrite(Led2, HIGH);
          delay(100);
          digitalWrite(Ampli, HIGH);
          delay(100);
          digitalWrite(Box, HIGH);
          delay(100);
          digitalWrite(Decoder, HIGH);
          delay(100);
          digitalWrite(Hdmi, HIGH);
          delay(100);
          digitalWrite(VPC, HIGH);
          delay(100);
          digitalWrite(VAMP, HIGH);
          delay(100);
          digitalWrite(Hdd1, HIGH);
          delay(100);
          digitalWrite(Hdd2, HIGH);
          delay(100);
          digitalWrite(Hdd3, HIGH);
          delay(100);
          digitalWrite(Hdd4, HIGH);
          delay(100);
          digitalWrite(Hdd5, HIGH);
          delay(100);
          digitalWrite(Hdd6, HIGH);
          delay(100);
          digitalWrite(a12v, HIGH);
          delay(100);
          
        }
    }
  }
}

Et j'aimerais rajouter un "SleepStop" pour annuler l'extinction des différents relais...

Grand merci d'avance pour votre aide !

Aegnor

Non vous ne voulez pas arrêter la fonction millis() vous voulez trouver un moyen de sortir de vos différents états d'attente.

Pour cela il suffit juste dans la boucle de rajouter la lecture d'un bouton et de modifier vos tests qui pilotent les Sleep[color=blue]x[/color]On

Bonjour J-M-L,
Grand merci pour votre réponse !
En effet, je me suis mal exprimé, c'est bien sortir des états d'attente...

Et ça prends tout de suite plus de sens en le disant ainsi...

est-ce que ce bout de code pourrait fonctionner ? :

if(inByte == ':'){ // Sort du Sleep Timer
  Sleep1ON = false; 
  Sleep2ON = false;
  Sleep3ON = false;
  Sleep4ON = false;
}

ça me paraît trop simple, mais il est vrai que j'ai un peu trop tendance à chercher la complication :slight_smile:

Merci d'avance,

Aegnor

est-ce que ce bout de code pourrait fonctionner ? :

avez vous essayé? :slight_smile: (je ne sais pas d'où vient inByte votre code est incomplet)

Re bonjour J-M-L,
J'ai essayé, mais ça ne fonctionne pas... les relais s'éteignent quand même

le "inByte" est un "Serial3.read()" qui vient du HC-05...

Ci dessous, voici le code complet pour les sleep timers :

// Sleep 60'

boolean Sleep1On;
unsigned short currentSleep1time = 0;
unsigned short Sleep1_StartMillis;
#define SEUILSleep1 30000


// Sleep 90'

boolean Sleep2On;
unsigned short currentSleep2time = 0;
unsigned short Sleep2_StartMillis;
#define SEUILSleep2 5400000


// Sleep 120'

boolean Sleep3On;
unsigned short currentSleep3time = 0;
unsigned short Sleep3_StartMillis;
#define SEUILSleep3 7200000


// Sleep 180'

boolean Sleep4On;
unsigned short currentSleep4time = 0;
unsigned short Sleep4_StartMillis;
#define SEUILSleep4 10800000




void setup() {
 
  
  Sleep1On = false;
  Sleep2On = false;
  Sleep3On = false;
  Sleep4On = false;
  
 
}


//------------------------------------------------------------------------------------------------------
//                                   LOOP
//------------------------------------------------------------------------------------------------------
void loop(){


  


//------------------------------------------------------------------------------------------------------
//                                   Lecture Message
//------------------------------------------------------------------------------------------------------
    
    int inByte = Serial3.read();
    if(Serial3.available()){
    //Serial.println(inByte);
    }


  if(inByte == '?') {
    Sleep1_StartMillis = millis();
    currentSleep1time = 0;
    Sleep1On = true;
  }else{
    if(Sleep1On){
      currentSleep1time = millis() - Sleep1_StartMillis;
        if(currentSleep1time > SEUILSleep1){          
          digitalWrite(Led1, HIGH);
          delay(100);
          digitalWrite(Led2, HIGH);
          delay(100);
          digitalWrite(Ampli, HIGH);
          delay(100);
          digitalWrite(Box, HIGH);
          delay(100);
          digitalWrite(Decoder, HIGH);
          delay(100);
          digitalWrite(Hdmi, HIGH);
          delay(100);
          digitalWrite(VPC, HIGH);
          delay(100);
          digitalWrite(VAMP, HIGH);
          delay(100);
          digitalWrite(Hdd1, HIGH);
          delay(100);
          digitalWrite(Hdd2, HIGH);
          delay(100);
          digitalWrite(Hdd3, HIGH);
          delay(100);
          digitalWrite(Hdd4, HIGH);
          delay(100);
          digitalWrite(Hdd5, HIGH);
          delay(100);
          digitalWrite(Hdd6, HIGH);
          delay(100);
          digitalWrite(a12v, HIGH);
          delay(100);
          Sleep1On = false;
        }
    }
  }


  if(inByte == '!') {
    Sleep2_StartMillis = millis();
    currentSleep2time = 0;
    Sleep2On = true;
  }else{
    if(Sleep2On){
      currentSleep2time = millis() - Sleep2_StartMillis;
        if(currentSleep2time > SEUILSleep2){          
          digitalWrite(Led1, HIGH);
          delay(100);
          digitalWrite(Led2, HIGH);
          delay(100);
          digitalWrite(Ampli, HIGH);
          delay(100);
          digitalWrite(Box, HIGH);
          delay(100);
          digitalWrite(Decoder, HIGH);
          delay(100);
          digitalWrite(Hdmi, HIGH);
          delay(100);
          digitalWrite(VPC, HIGH);
          delay(100);
          digitalWrite(VAMP, HIGH);
          delay(100);
          digitalWrite(Hdd1, HIGH);
          delay(100);
          digitalWrite(Hdd2, HIGH);
          delay(100);
          digitalWrite(Hdd3, HIGH);
          delay(100);
          digitalWrite(Hdd4, HIGH);
          delay(100);
          digitalWrite(Hdd5, HIGH);
          delay(100);
          digitalWrite(Hdd6, HIGH);
          delay(100);
          digitalWrite(a12v, HIGH);
          delay(100);
          Sleep2On = false;
        }
    }
  }


  if(inByte == '*') {
    Sleep3_StartMillis = millis();
    currentSleep3time = 0;
    Sleep3On = true;
  }else{
    if(Sleep3On){
      currentSleep3time = millis() - Sleep3_StartMillis;
        if(currentSleep3time > SEUILSleep3){          
          digitalWrite(Led1, HIGH);
          delay(100);
          digitalWrite(Led2, HIGH);
          delay(100);
          digitalWrite(Ampli, HIGH);
          delay(100);
          digitalWrite(Box, HIGH);
          delay(100);
          digitalWrite(Decoder, HIGH);
          delay(100);
          digitalWrite(Hdmi, HIGH);
          delay(100);
          digitalWrite(VPC, HIGH);
          delay(100);
          digitalWrite(VAMP, HIGH);
          delay(100);
          digitalWrite(Hdd1, HIGH);
          delay(100);
          digitalWrite(Hdd2, HIGH);
          delay(100);
          digitalWrite(Hdd3, HIGH);
          delay(100);
          digitalWrite(Hdd4, HIGH);
          delay(100);
          digitalWrite(Hdd5, HIGH);
          delay(100);
          digitalWrite(Hdd6, HIGH);
          delay(100);
          digitalWrite(a12v, HIGH);
          delay(100);
          Sleep3On = false;
        }
    }
  }


  if(inByte == '+') {
    Sleep4_StartMillis = millis();
    currentSleep4time = 0;
    Sleep4On = true;
  }else{
    if(Sleep4On){
      currentSleep4time = millis() - Sleep4_StartMillis;
        if(currentSleep4time > SEUILSleep4){
          digitalWrite(Box, HIGH);
          delay(500);
          digitalWrite(Led1, HIGH);
          delay(500);
          digitalWrite(Led2, HIGH);
          delay(500);
          digitalWrite(Ampli, HIGH);
          delay(500);
          digitalWrite(Sub, HIGH);
          delay(500);
          digitalWrite(Decoder, HIGH);
          delay(500);
          digitalWrite(Hdmi, HIGH);
          delay(500);
          digitalWrite(VPC, HIGH);
          delay(500);
          digitalWrite(VAMP, HIGH);
          delay(500);
          digitalWrite(Hdd1, HIGH);
          delay(500);
          digitalWrite(Hdd2, HIGH);
          delay(500);
          digitalWrite(Hdd3, HIGH);
          delay(500);
          digitalWrite(Hdd4, HIGH);
          delay(500);
          digitalWrite(Hdd5, HIGH);
          delay(500);
          digitalWrite(Hdd6, HIGH);
          delay(500);
          digitalWrite(a12v, HIGH);
          delay(500);
          Sleep4On = false;
        }
    }
  }
  if(inByte == '£'){
    Sleep1On = false;
    Sleep2On = false;
    Sleep3On = false;
    Sleep4On = false;
  }




}

unsigned [color=red]short[/color].... ??

faut aussi penser à rajouter des ul à la fin de vos grands constantes - genre

#define SEUILSleep4 10800000[color=blue][b]ul[/b][/color]

pour éviter des misères dans les calculs si d'aventure vous veniez à faire des maths avec ces valeurs


ou est le begin pour Serial3 ? quel bauds ?


  int inByte = Serial3.read();
  if (Serial3.available()) {
    //Serial.println(inByte);
  }

donc vous lisez puis ensuite vous allez voir s'il y a quelque chose de dispo et si oui vous ne faites rien ?


pourquoi attendre 100ms entre les fermetures de relay?

En fait, je n'ai mis qu'une toute petite partie du code, au total il fait près de 3000 lignes,
Pour le serial3, il est à 38400

pour le

int inByte = Serial3.read();
  if (Serial3.available()) {
    //Serial.println(inByte);
  }

C'était pour le debug, et vérifier qu'il prenait bien tous les caractères reçu par le HC-05
je l'ai laissé au cas où, mais en commentant la ligne "Serial.println"

pour le "unsigned short", il vaut mieux mettre un "unsigned long" ?

Je n'arrive pas à poster tout le code car il fait près de 3000 lignes
et pour le matériel utilisé :

Mega 2560
NEXTION 3.5"
DS18B20 (x4 dont 2 étanches)
DHT11
RTC3231
TEA5767
HC-05
Relais (x26)
Alim à découpage 12v 30A
Alim à découpage 5v 10A
Alim stabilisée 9v 2A
Décodeur Optique vers 5.1
Switch HDMI
Extracteur Optique HDMI
Android TV Box
PT2322 pour le volume et tonalité
PT2323 Sélecteur d'entrées audio 5.1 + 4 stéréo
Préampli TL072 et TL074
amplis 2 x 100w classe D TDA7498 (x3)
Disques durs (x6)
Gestion de 4 pompes aquarium + 1 pompe à air + 2 chauffages + éclairage
Gestion éclairage led (type ambilight)

Le tout fonctionne merveilleusement bien, sauf pour sortir des états d'attente...

Tout fonctionne super

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

Moi je ferai un truc du genre (ici sur le port Série standard et juste avec la LED de base à piloter)

j'ai tapé au kilomètre donc à vérifier...

// '?' = sleepIn60min
// '!' = sleepIn90min
// '*' = sleepIn120min
// '+' = sleepIn180min
// '£' = pas de sleep
// '#' = allumer ou éteindre le système (éteint à l'allumage de la carte)


// je sépare tous les états mais ne fait rien de particulier en fait dans les états sleepInXXmin
// on pourrait n'avoir que un seul état sleepActivated par exemple
enum {doesNotSleep, sleepIn60min, sleepIn90min, sleepIn120min, sleepIn180min, systemOff} etat;

const unsigned int petitePause = 100;

unsigned long startChrono;
unsigned long duration;


void toutAllumer()
{
  digitalWrite(LED_BUILTIN, HIGH);
  delay(petitePause);
  etat = doesNotSleep;
}


void toutEteindre()
{
  digitalWrite(LED_BUILTIN, LOW);
  delay(petitePause);
  etat = systemOff;
}


void noSleep()
{
  etat = doesNotSleep;
}

// -----------------------------------------------------------------------------
// dans ces fonctions il faudrait décider si on doit remettre
// le compteur de temps à 0 ou pas si le mode était déjà
// un des sleep mode. à vous de voir. ici je redonne tout 
// Le temps à nouveau 
// on pourrait n'avoir qu'un état sleepActivated et qu'une fonction 
// prenant en paramètre la durée restante dans le cas simple que vous avez
// où la durée d'attente n'influence  aucun comportement particulier
// ça permettait par exemple de régler plus finement la durée à des valeurs
// arbitraires avec un potentiomètre 
// -----------------------------------------------------------------------------

void sleep60()
{
  etat = sleepIn60min;
  duration = 60 * 60000ul;
  startChrono = millis();
}

void sleep90()
{
  etat = sleepIn90min;
  duration = 90 * 60000ul;
  startChrono = millis();
}

void sleep120()
{
  etat = sleepIn120min;
  duration = 120 * 60000ul;
  startChrono = millis();
}

void sleep180()
{
  etat = sleepIn180min;
  duration = 180 * 60000ul;
  startChrono = millis();
}


// -----------------------------------------------------------

void commande()
{
  if (Serial.available()) {
    int commande = Serial.read();
    if (commande != -1) {
      switch ((char) commande) {
        case '?':
          sleep60();
          break;

        case '!':
          sleep90();
          break;

        case '*':
          sleep120();
          break;

        case '+':
          sleep180();
          break;

        case '£':
          noSleep();
          break;


        case '#':
          if (etat != systemOff) toutEteindre();
          else toutAllumer();
          break;

        default:
          break;
      }
    }
  }
}

// -----------------------------------------------------------

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  toutEteindre();
}


void loop() {
  commande();
  if ((etat != doesNotSleep) && (etat != systemOff)) {
    if (millis() - startChrono >= duration) {
      toutEteindre();
    }
  }
}

J-M-L, Super TUTO !!! vraiment !

Merci pour le code, je vais tester ça ! top du top !

Je reviens vers vous pour le résultat :wink:

Cordialement,
Aegnor