Gestion du temps de débutant

Bonjour a tous, et merci a ceux qui me liront jusqu'au bout !

J'ai un probleme electronique que j'aimerais contourner par une solution de code.
Le problème vient d'un retour de courant d'un petit circuit qui commande un relais.
Elle prend la forme d'une trés breve impulsion regulière envoyée dans une pin qui controle l'état d'un bouton.

J'aimerais faire quelque chose comme : "vérifie l'état, puis verifie le 500ms plus tard : si ce n'est pas le même état alors rien,
si c'est le même état alors declenche..."

Le problème c'est que j'utilise la methode millis() pour debouncer les boutons et je n'arrive pas a faire ça avec millis().
J'ai essayé quelque chose comme ça, mais je pressens que ça fout le bordel dans le code

if (button_time2 - last_button_time2 > debounce2)
  {
    if (resetState1 != lastResetState1) 
    {
      button_time2 = millis();
      lastResetState1 = resetState1;
      if (millis() - last_button_time2 > debounce2)
      {
        if (resetState1 != lastResetState1) 
        {
// le reste du code

Alors je pense que ça doit être extremement simple mais là je sèche !

Salut,

On ne peut pas comprendre ton code car incomplet.

Rien que la première condition :

Si quelque chose que je supose contenir la valeur de milli() moins un inconnu est plus grand qu'un inconnu alors ...

Je peux juste te conseiller d'enlever tout ce code, de vérifier que tu as activé la résistance de pullup sur ton entrée en cherchant pinMode dans la doc puis tu ajoutes un condensateur 100nF entre ton entrée et la masse

jeremixogg:
Elle prend la forme d'une trés breve impulsion regulière envoyée dans une pin qui controle l'état d'un bouton.

Si l'impulsion est très brève, il y a peu de chance que ton code soit juste au bon moment en train de surveiller cette pin.
Il vaut mieux mettre une interruption sur cette broche
explications en français ici attachInterrupt() - Arduino Reference

Faudrait peut-être savoir qui c'est qui génère cette impulsion. Non ?
C'est peut-être tout connement le relais qui n'a pas sa diode de roue libre.

Merci a tous de vos réponses tout d'abord.

J'ai utilisé ce schéma (en piece jointe) pour le bouton et le relais.

@koala

Mon code consiste à gérer deux boutons qui commandent deux relais, 2 autre bouton de type "reset" sont censés desactiver les relais pendant que le bouton est pressé.
Le voila en entier, j'ai introduit (peut être à tort) un deuxieme debounce pour gerer exclusivement les boutons reset.

//--- entete déclarative
// = déclarer ici variables et constantes globales
const int nombreDelais=4; // nombre de délais de comptage à utiliser
const int LED[nombreDelais]={
  8,9,10,11}; // tableau de constantes désignant la broche de la LED
long millis0[nombreDelais]={
  0,0,0,0}; // tableau de variables pour mémoriser dernier millis() pris en compte
int delai[nombreDelais]={
  2000, 2000, 2000, 2000}; // tableau d'intervalles à utiliser en millisecondes
boolean etatLED[nombreDelais]={
  LOW, LOW, LOW, LOW}; // LEDs allumées au départ
// remarque HIGH = true = 1 et LOW = false = 0

const int  reset1 = 3; // bouton reset 1
const int  reset2 = 4; // bouton reset 2
const int  buttonPin = 5; // bouton 1
const int  buttonPin2 = 6;  //bouton 2
boolean action = 0;
boolean action2 = 0;
int resetState1 = 0;
int resetState2 = 0;
int lastResetState1 = 0;
int lastResetState2 = 0;
int buttonState = 0;
int buttonState2 = 0;
int lastButtonState = 0;
int lastButtonState2 = 0;

// pour le debounce
volatile unsigned long button_time = 0;
volatile unsigned long last_button_time = 0;
int debounce = 400; // debounce latency in ms
volatile unsigned long button_time2 = 0;
volatile unsigned long last_button_time2 = 0;
int debounce2 = 100; // debounce latency in ms


void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(reset1, INPUT);
  pinMode(reset2, INPUT);
  Serial.begin(9600);
  for (int i=0; i<nombreDelais; i++) {
    pinMode(LED[i], OUTPUT); // met la broche en sortie
    Serial.begin(9600);
    digitalWrite(LED[i],etatLED[i]); // met la LED dans l'état voulu
    millis0[i]=millis(); // mémorise millis()
  }
} // fin de la fonction setup()


void loop() {
  unsigned long currentMillis = millis();
  buttonState = digitalRead(buttonPin);
  buttonState2 = digitalRead(buttonPin2);
  resetState1 = digitalRead(reset1);
  resetState2 = digitalRead(reset2);

  //*****************************************Bouton rouge

  button_time = millis();
  button_time2 = millis();

  if (button_time - last_button_time > debounce)
  {
    if (buttonState != lastButtonState) 
    {
      if (buttonState == HIGH) 
      {
        action = !action;
        Serial.print("bouton rouge :");
        Serial.println(action);
        last_button_time = button_time;
      }
    }
  }
  // *****************************************Bouton vert

  if (button_time - last_button_time > debounce)
  {
    if (buttonState2 != lastButtonState2) 
    {
      if (buttonState2 == HIGH) 
      {
        action2 = !action2;
        Serial.print("bouton vert :");
        Serial.println(action2);
        last_button_time = button_time;
      }
    }
  }

  //*******************************************Reset 1

  if (button_time2 - last_button_time2 > debounce2)
  {
    if (resetState1 != lastResetState1) 
    {
      button_time2 = millis();
      lastResetState1 = resetState1;
      if (millis() - last_button_time2 > debounce2)
      {
        if (resetState1 != lastResetState1) 
        {
          if (resetState1 == HIGH) 
          {
            Serial.print("pas glop");
            last_button_time2 = button_time2;
            action = 0;

          }
        }
      }
    }
  }

  //*******************************************Reset 2
  if (button_time2 - last_button_time2 > debounce2)
  {
    if (resetState2 != lastResetState2) 
    {
      button_time2 = millis();
      if (button_time2 - last_button_time2 > debounce2)
      {
        if (resetState2 == HIGH) 
        {
          digitalWrite(LED[1],LOW);
          Serial.print("reset 2 : ");
          Serial.println(resetState2);
          last_button_time2 = button_time2;
        }
      }
    }
  }

  //******************************************Sonnerie 1
  if (action == 1)
  {
    if (millis()-millis0[0]>=delai[0]) 
    { // si le délai est écoulé
      millis0[0]=millis(); // mémorise millis()
      etatLED[0]=!etatLED[0]; // inverse l'état de la variable
      digitalWrite(LED[0],etatLED[0]);
    } // fin si délai écoulé
  }

  else {
    digitalWrite(LED[0], LOW);
  }

  //******************************************Sonnerie 2


  if (action2 == 1)
  {
    //--- 0
    //Serial.println(action2);
    if (millis()-millis0[1]>=delai[1]) 
    { // si le délai est écoulé
      millis0[1]=millis(); // mémorise millis()
      etatLED[1]=!etatLED[1]; // inverse l'état de la variable
      digitalWrite(LED[1],etatLED[1]);
    }
  }

  else 
  {
    digitalWrite(LED[1], LOW);
  }

  lastButtonState = buttonState;
  lastButtonState2 = buttonState2;
  lastResetState1 = resetState1;
  lastResetState2 = resetState2;

  // les autres instructions ici
  // elles seront exécutées meme si le délai n'est pas écoulé
}

arduino-control-relay-schematic.png

  if (button_time2 - last_button_time2 > debounce2)
  {
    if (resetState1 != lastResetState1) 
    {
      button_time2 = millis();
      lastResetState1 = resetState1;
      if (millis() - last_button_time2 > debounce2)
      {

Ce morceau de code n'a pas de sens. Le troisième if ne doit jamais s'exécuter.
Lorsque tu passes les deux premières conditions, tu réinitialises button_time2 ce qui t'interdit de satisfaire le troisième if.
Je ne comprends pas bien la finalité de cette partie de code. Mais je crois qu'il faudrait la reposer sur le papier à tête reposée.
Lorsqu'on travaille avec millis() il faut penser que tout le code s'exécute en boucle et donc le concevoir en conséquence.
Au lieu d'empiler des if il est préférable d'utiliser une petite machine à état.

Ne pas oublier non plus que millis() repasse périodiquement par zéro et que les tests pour être valides doivent être écrits ainsi:

if (ancien_temps+delais_a_tenir>millis()){
}

ou bien si millis() est affectée à une variable

temps_courant = millis();
if (ancien_temps+delais_a_tenir>temps_courant{
}

@fdufnews
merci pour ces précisions, qu'apelle tu machine à état, des "switch case" par ex?

Pour le débordement, je calcule que la variable long déborde après 2 147 483 647, soit en ms, environ 24 jours 20 heures 31 minutes 23 secondes.
Est que j'ai bon ?
Dans ce cas je ne ferai jamais jouer ce code aussi longtemps.

Mais toutefois je m'interroge, quelle est est l'astuce pour effectuer deux mesures d'une valeur à un intervalle de temps donné, en utilisant millis() ?

J'aimerais faire ça car mon circuit electronique me déclenche une bréve impulsion et j'aimerais le contourner par du code.
J'ai besoin de déclencher l'action sur ce bouton en cas d'appui long.

J'avais bien oublié de mettre des condensateurs sur les boutons (comme sur le schéma en pièce jointe),
après ajout, c'est beaucoup mieux.
Mais j'ai toujours une impulse qui me revient quand le relais se coupe, des fois quand il se lance.
Je n'avais que des 2.2uF sous la main, est-ce que des 100nF seront vraiment plus efficaces ?

cap button.PNG