Activation d'un relai après un appuis long sur un bouton poussoir

Bonjour à tous.

J'utilise un Arduino MEGA, un bouton poussoir standard et un relai standard. (dites moi si il manque des informations sur le montage)
J'ai comme projet d'activer un relai après un appuis long sur un bouton poussoir.

Quoi que je fasse dans mon programme, je n'arrive pas à activer le relai via le bouton poussoir qu'après 3 secondes de maintient du bouton.

En effet, le relai s'active directement après l'appui du bouton et ce pendant 3 secondes alors que je souhaite qu'il s'active seulement après 3 secondes de maintient de ce bouton.

Quelqu'un d'entre vous à déjà essayé ce fonctionnement ?

En plus, le relai s'active dès le démarrage du système alors que je le souhaite pas forcément.

Voici le programme:

const int boutonPin = 12;      // Pin du bouton
const int relaiPin = 8;       // Pin du relai
const int seuilTemps = 3000;  // Seuil de temps en millisecondes (3 secondes)

int boutonEtat = 0;            // Variable pour stocker l'état du bouton
unsigned long tempsAppui = 0;  // Variable pour stocker le temps d'appui sur le bouton
bool relaiActive = false;      // Variable pour suivre l'état du relai

void setup() {
  pinMode(boutonPin, INPUT);   // Configure le bouton en tant qu'entrée
  pinMode(relaiPin, OUTPUT);   // Configure le relai en tant que sortie
}

void loop() {
  boutonEtat = digitalRead(boutonPin);  // Lit l'état du bouton

  // Vérifie si le bouton est enfoncé
  if (boutonEtat == HIGH) {
    // Si c'est la première fois que le bouton est enfoncé, enregistre le temps actuel
    if (tempsAppui == 0) {
      tempsAppui = millis();
    }
    // Si le bouton est enfoncé depuis plus de seuilTemps et que le relai n'est pas déjà activé
    if (millis() - tempsAppui > seuilTemps && !relaiActive) {
      digitalWrite(relaiPin, HIGH);  // Active le relai
      relaiActive = true;
    }
  } else {
    // Réinitialise le temps d'appui si le bouton est relâché
    tempsAppui = 0;
    if (relaiActive) {
      digitalWrite(relaiPin, LOW);  // Désactive le relai
      relaiActive = false;
    }
  }
}

Merci pour votre aide.

Pour simplifier votre gestion des boutons, éventuellement utilisez la bibliothèque Button dans easyRun de @bricoleau ou OneButton de Matthias Hertel ou encore Toggle de @dlloyd.

vous avez la gestion de l'appui long directement disponible dans les APIs

Bonjour scorius

Le relais retombe au relâchement du bouton?

Un petit truc, à l'initialisation de la pin du relais, la mettre à LOW immédiatement (si c'est HIGH qui l'active):

	pinMode(relaiPin, OUTPUT);   // Configure le relai en tant que sortie
	digitalWrite(relaiPin, LOW);

Cordialement
jpbbricole

un exemple avec la bibliothèque OneButton

#include <OneButton.h>          // https://github.com/mathertel/OneButton
const byte brocheRelai = 8;     // notre relai est sur la pin 8
const byte brocheBouton = 2;    // notre bouton est sur la pin 2
OneButton bouton(brocheBouton); // se charge de régler le INPUT_PULLUP

// la fonction appelée en cas d'appui long
void appuiLong() {
  // on inverse l'état du relai 
  digitalWrite(brocheRelai, digitalRead(brocheRelai) == HIGH ? LOW : HIGH);
}

void setup() {
  pinMode(brocheRelai, OUTPUT);
  bouton.setPressMs(3000);                 // on dit qu'un appui long c'est 3 secondes
  bouton.attachLongPressStart(appuiLong);  // on enregistre le callback
}

void loop() {
  bouton.tick();                           // on surveille ce qu'il se passe sur le bouton
}

à tester ici

(il existe un call back pour le relâchement du bouton (attachLongPressStop() )qui permettrait aussi de gérer le relâchement pour arrêter le relai si c'est le souhait)

Bonjour scorius

J'ai essayé ton programme, il fonctionne selon tes désirs.
Seule modification, celle indiquée au post #3 Un petit truc...

As-tu une résistance de PULLDOWN sur la pin boutonPin? Pour mon essai, j'ai mis 10k.

Cordialement
jpbbricole

Merci pour ta réponse.
oui j'ai essayé ca aussi mais sans succés

Merci pour ta réponse.
j'ai pu mettre en place tout ce que tu m'a conseillé sauf : void loop() {
bouton.tick();
}

Le programme dis qu'il ne connais pas cette ligne. J'ai bien remplacé bouton par mon nom de bouton à moi pourtant.

Merci pour ta réponse.
Ouhahou !! Ha oui il fonctionne chez toi ?
Oui j'ai bien mis une résistance 10K comme toi.
EN plus, j'ai 4 relais et j'ai essayé sur les 4 ca ne fonctionne pas. Il y a quelque chose d'incompréhensible.

je ne sais pas trop ce que vous voulez dire... avez vous utilisé la bibliothèque OneButton?

hum... là il est temps de nous montrer un schéma électrique du montage...

oui la bibliothèque OneButton est installée.

le code modifié donne ca. Est-ce exact ?:

#include <OneButton.h>
const int boutonPin = 12;      // Pin du bouton
const int relaiPin = 8;       // Pin du relai
const int seuilTemps = 3000;  // Seuil de temps en millisecondes (3 secondes)
OneButton bouton(12); // se charge de régler le INPUT_PULLUP



int boutonEtat = 0;            // Variable pour stocker l'état du bouton
bool relaiActive = false;      // Variable pour suivre l'état du relai
unsigned long tempsDebutAppui = 0; // Variable pour stocker le moment du début d'appui

void setup() {
  digitalWrite(relaiPin, LOW);
  pinMode(boutonPin, INPUT);   // Configure le bouton en tant qu'entrée
  pinMode(relaiPin, OUTPUT);   // Configure le relai en tant que sortie
  OneButton boutonPin(12);
   pinMode(8, OUTPUT);
  boutonPin.setPressMs(3000);                 // on dit qu'un appui long c'est 3 secondes
  boutonPin.attachLongPressStart(appuiLong);  // on enregistre le callback

}
void appuiLong() {
  // on inverse l'état du relai 
  digitalWrite(8, digitalRead(8) == HIGH ? LOW : HIGH);
}

void loop() 

{
  bouton.tick();  
  boutonEtat = digitalRead(boutonPin);  // Lit l'état du bouton

  // Vérifie si le bouton est enfoncé
  if (boutonEtat == HIGH) {
    // Si le relai n'est pas encore activé et que le temps d'appui n'a pas encore été enregistré
    if (!relaiActive && tempsDebutAppui == 0) {
      tempsDebutAppui = millis();
    }
    // Si le relai n'est pas encore activé et que le temps d'appui atteint le seuil
    if (!relaiActive && millis() - tempsDebutAppui >= seuilTemps) {
      digitalWrite(relaiPin, HIGH);  // Active le relai
      relaiActive = true;
    }
  } else {
    // Réinitialise le temps d'appui et l'état du relai si le bouton est relâché
    tempsDebutAppui = 0;
    if (relaiActive) {
      digitalWrite(relaiPin, LOW);  // Désactive le relai
      relaiActive = false;
    }
  }
}

ben non.... ça ne ressemble absolument pas au code que je vous ai donné...

le code c'est juste cela:

#include <OneButton.h>
const byte boutonPin = 12;                // Pin du bouton
const byte relaiPin = 8;                  // Pin du relai
const unsigned long seuilTemps = 3000;    // Seuil de temps en millisecondes (3 secondes)
OneButton bouton(boutonPin);              // se charge de régler le INPUT_PULLUP

void debutAppuiLong() {
  digitalWrite(relaiPin, HIGH);
}

void finAppuiLong() {
  digitalWrite(relaiPin, LOW);
}

void setup() {
  digitalWrite(relaiPin, LOW);
  pinMode(relaiPin, OUTPUT);                    // Configure le relai en tant que sortie
  bouton.setPressMs(seuilTemps);                // on dit qu'un appui long c'est 3 secondes
  bouton.attachLongPressStart(debutAppuiLong);  // on enregistre le callback
  bouton.attachLongPressStop(finAppuiLong);     // on enregistre le callback
}


void loop() {
  bouton.tick();  
}

au début de l'appui long, le relai s'active et retourne à LOW quand vous relâchez le bouton

Oui entendu mais le câblage fonctionne on dirait et il est simple

le bouton doit être câblé

PIN 12 --- BOUTON ---- GND

pas de résistance

Ok merci j'ai envoyé votre code pour essai

Ce qui se passe: A l'allumage le relai s'active et reste activé tout le temps.
le bouton ne fonctionne plus .

cf post 14

et pour être sur de prendre les bonnes pin du bouton, câblez en diagonale pas les pins du même côté car vous risquez de prendre 2 pins identiques du bouton

image

Si je ne met pas de résistance le relai s'active et se désactive très vite tout le temps. Ca va le faire péter.

Entendu, c'est fait. mais le montage fonctionne bien j'ai l'impression

ça doit être comme cela

idéalement le relai ne reçoit pas ses 5V depuis l'arduino car ça peut tirer beaucoup (70 à 100mA pour coller la bobine) surtout si vous en avez 4 à piloter mais directement de la source 5V et on joint les GND

vous pouvez tester ici

vous verrez que la LED du relai s'allume si vous tenez appuyé plus de 3s et s'éteint quand vous relâchez

avez vous des relais actifs à LOW ou à HIGH ?

au début du code je fais

  digitalWrite(relaiPin, LOW);
  pinMode(relaiPin, OUTPUT);                    // Configure le relai en tant que sortie

c'est pour désactiver le relai. S'il est actif à LOW il faut mettre à HIGH et inverser dans les 2 fonctions d'allumage / extinction