Allumer progressivement une led avec un boutton

Bonjour,

Je voudrait pouvoir allumer une led en appuyant sur un bouton mais qu'au moment ou on lâche le bouton, la valeur "actuelle" soit maintenue.

Par exemple je tiens le bouton appuyé jusqu'à 60% et quand je lâche cette valeur soit maintenue.

J'ai codé ceci :

const int led = 5;          //led sur sortie analog 5
const int button = 4;       //bouton compteur sur entrée 4

int buttonstate = 0;        // variable bouton initialisée à 0:



void setup() 
{ 
  // déclarer les entrées-sorties:
  pinMode(button, INPUT);
  pinMode(led, OUTPUT);
}

void loop() 
{
buttonstate = digitalRead(button);    // lire l'état du bouton:

  if (buttonstate == HIGH)
  {
    analogWrite(led, 0);            //Allume la led à 0%
    delay(400);                     //attente
    analogWrite(led, 50);           //Allume la led à ~20%
    delay(400);                     //attente    
    analogWrite(led, 100);          //Allume la led à ~40%
    delay(400);                     //attente
    analogWrite(led, 150);          //Allume la led à ~60%
    delay(400);                     //attente 
    analogWrite(led, 200);          //Allume la led à ~80%
    delay(400);                     //attente
    analogWrite(led, 255);          //Allume la led à 100%
    delay(400);                     //attente    
  }
}

Le problème que je rencontre est que quand je pousse sur le bouton il incrémente de 0 à 100% sans s'arrêter quand je lâche. :woozy_face:

Je tiens à préciser que je suis débutant. J'ai un arduino UNO.

Merci pour votre aide

une fois que vous rentrez dans le if vous avez aucun moyen de contrôle pendant 2.4 secondes...

n'utilisez pas delay mais testez le bouton à chaque tour de loop(). Au premier appui notez l'heure (millis()) et s'il est toujours enfoncé modifiez une variable qui représente la luminosité (la valeur du PWM) en fonction du temps écoulé (utilisez millis() pour cela)

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

La loop s'exécute très rapidement. Pour éviter que l'intensité passe à 100% en un très court instant, il faudra mettre en place une sorte de temporisation entre chaque incrémentation.
Par exemple, en utilisant millis(), vérifier qu'un délai (disons 100ms par exemple) s'est écoulé depuis la précédente incrémentation.
Pour cela, il faut stocker la valeur de millis() lors de chaque incrémentation, et vérifier que le délai s'est écoulé avant de passer à la suivante.

Bonjour,

Merci pour vos conseils, après de longues heures sur les forums à ramer pour comprendre millis() :sweat_smile:, j'ai réussi ce que je voulait faire avec ce code :

const int ledPin =  5;      //led sur sortie analog 5
const int button = 4;       //bouton sur entrée 4

int buttonstate = 0;        // variable état du bouton initialisée à 0
int ledState = 0;           // variable état de la led initialisée à 0

// Generally, you should use "unsigned long" for variables that hold time
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 300;           // interval (milliseconds)

void setup() 
{
  // déclarer les entrées-sorties:
  pinMode(ledPin, OUTPUT);
  pinMode(button, INPUT);
}

void loop() 
{
  
unsigned long currentMillis = millis();        // initialise le temps présent à "current"
buttonstate = digitalRead(button);    // lire l'état du bouton:

if (buttonstate == HIGH)
{

  if (currentMillis - previousMillis >= interval && ledState == 0) 
  {
  previousMillis = currentMillis;     // save the last time you blinked the LED
  ledState = 50 ;                     //Allume la led à ~20%
  }
  
  if (currentMillis - previousMillis >= interval && ledState == 50) 
  {
  previousMillis = currentMillis;     // save the last time you blinked the LED
  ledState = 100 ;                     //Allume la led à ~40%
  }

  if (currentMillis - previousMillis >= interval && ledState == 100) 
  {
  previousMillis = currentMillis;     // save the last time you blinked the LED
  ledState = 150 ;                     //Allume la led à ~60%
  }
  
  if (currentMillis - previousMillis >= interval && ledState == 150) 
  {
  previousMillis = currentMillis;     // save the last time you blinked the LED
  ledState = 200 ;                     //Allume la led à ~80%
  }
  
  if (currentMillis - previousMillis >= interval && ledState == 200) 
  {
  previousMillis = currentMillis;     // save the last time you blinked the LED
  ledState = 250 ;                     //Allume la led à ~100%
  }
  
  if (currentMillis - previousMillis >= interval && ledState == 250) 
  {
  previousMillis = currentMillis;     // save the last time you blinked the LED
  ledState = 0 ;                     //Allume la led à ~60%
  }
  
  analogWrite(ledPin, ledState);
  }
}

Je suis persuadé qu'on peut simplifier facilement cela mais comment ? :thinking:

Qu'en pensez-vous ?

Bonjour,

Tu aurais pu faire un seul if (currentMillis - previousMillis >= interval) et à l'intérieur une série de if (ledState == xx) ou mieux un switch ou ajouter 50 et si ça dépasse 250 revenir à 0


void loop()
{
  unsigned long currentMillis = millis();        // initialise le temps présent à "current"
  buttonstate = digitalRead(button);    // lire l'état du bouton:

  if (buttonstate == HIGH)
  {
    if (currentMillis - previousMillis >= interval)
    {
      previousMillis = currentMillis;
      ledState += 50;
      if (ledState > 250)
        ledState = 0;

      analogWrite(ledPin, ledState);
    }
  }
}

vous auriez pu utiliser le temps passé en appui pour calculer une luminosité

durée = 0 ➜ luminosité = 0
durée >= 5s ➜ luminosité = 255

en supposant que le bouton soit en INPUT PULLUP (HIGH quand pas appuyé)

un truc comme cela, non testé

const int ledPin =  5;      //led sur sortie analog 5
const int boutonPin = 4;       //bouton sur entrée 4
bool appuiEnCours = false;
unsigned long debutAppui;
byte luminosite = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(boutonPin, INPUT_PULLUP); // pin -- bouton -- GND
}

void loop() {
  if (digitalRead(boutonPin) == LOW) {
    if (!appuiEnCours) {
      appuiEnCours = true;
      debutAppui = millis();
    }
    luminosite = constrain(map(millis() - debutAppui, 0, 5000, 0, 255), 0, 255);
    analogWrite(ledPin, luminosite);
  } else {
    appuiEnCours = false;
    luminosite = 0;
    digitalWrite(ledPin, LOW); // on éteint
  }
}