LED RGB avec interrupteur

Bonjour, j'ai un projet dans lequel j'ai besoin d'allumer un bandeau LED RGB (un pin +, R, G, B) et une autre LED avec un bouton poussoir transformé en interrupteur grâce au code que j'ai déjà fait.
Mais je n'arrive pas à faire un effet arc en ciel et à l'inclure dans le code et si ça marche je n'arrive pas à stopper l'arc en ciel quand j'appuie sur le bouton.
Voici mon code :

const int pin_INTERRUPTEUR = 2;
const int pin_LED = 3;
boolean ledAllumer = 0;
boolean boutonAppuyer = 0;
const byte PIN_LED_R = 9;
const byte PIN_LED_G = 10;
const byte PIN_LED_B = 11;

void setup() {

  pinMode(pin_INTERRUPTEUR, INPUT_PULLUP);
  pinMode(pin_LED, OUTPUT);
  Serial.begin(9600);
  pinMode(PIN_LED_R, OUTPUT);
  pinMode(PIN_LED_G, OUTPUT);
  pinMode(PIN_LED_B, OUTPUT);
  displayColor(0, 0, 0);
}


void loop() 
{
    boolean etatBouton = digitalRead(pin_INTERRUPTEUR) ; // Récupère l’état du bouton
    if(etatBouton == 0 and boutonAppuyer == 0) { // On appuie sur le bouton
        boutonAppuyer = 1;
        if(ledAllumer == 0) { // Si la led est éteinte on l’allume
            ledAllumer = 1;
            digitalWrite(pin_LED, HIGH);
            //La où doit se situer le code arc en ciel
            Serial.println('allume') ;
        }
        else { // Si la led est allumée on l’éteint
            digitalWrite(pin_LED, LOW);
            displayColor(0, 0, 0);
            delay(1000);
            ledAllumer = 0;
            Serial.println('eteint');
        }
    }
    if(etatBouton == 1 and boutonAppuyer == 1) { //On arrête d’appuyer sur le bouton
        boutonAppuyer = 0;
    }
    delay(10) ; // Attente de 10 ms
}


/** Affiche une couleur */
void displayColor(byte r, byte g, byte b) {

  // Assigne l'état des broches
  // Version cathode commune
  //analogWrite(PIN_LED_R, r);
  //analogWrite(PIN_LED_G, g);
  //analogWrite(PIN_LED_B, b);
  // Version anode commune
  analogWrite(PIN_LED_R, ~r);
  analogWrite(PIN_LED_G, ~g);
  analogWrite(PIN_LED_B, ~b);
}

Merci d'avance pour vos réponses !!!

montrez le code avec l'effet arc en ciel dont vous parlez

Ce code là marche tout seul mais je ne sais pas comment l'inclure (j'ai essayé de certaines façon mais erreur dans le compilateur) :

int redPin = 9;
int greenPin = 10;
int bluePin = 11;

int r = 0;
int g = 0;
int b = 0;

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop() { 
  setColor(255, 0, 0);    // red
  setColor(0, 255, 0);    // green
  setColor(0, 0, 255);    // blue
  setColor(255, 255, 0);  // yellow
  setColor(80, 0, 80);    // purple
  setColor(0, 255, 255);  // aqua
}

void setColor(int red, int green, int blue) {
  while ( r != red || g != green || b != blue ) {
    if ( r < red ) r += 1;
    if ( r > red ) r -= 1;

    if ( g < green ) g += 1;
    if ( g > green ) g -= 1;

    if ( b < blue ) b += 1;
    if ( b > blue ) b -= 1;

    _setColor();
    delay(10);
  }
}

void _setColor() {
  analogWrite(redPin, r);
  analogWrite(greenPin, g);
  analogWrite(bluePin, b); 
}

ce code allume succesivement la LED avec les couleur rouge, vert, bleu, jaune, violet et "aqua" et fait un petit blocage entre 2 affichage

si vous utilisez ce code en boucle dans votre code, vous ne testez plus le bouton et donc ça ne peut pas marcher

il faut gérer cela différement en gérant le temps qui passe (la bonne approche c'est la programmation par machine à états (cf mon tuto éventuellement)) ou alors vous y allez mode bourrin et vous affichez rouge, puis pendant l'attente au lieu de faire delay() vous faites une petite boucle qui écoute ce qui se passe sur le bouton pour pouvoir réagir si besoin, puis vous affichez vert et refaites l'attente en vérifiant le bouton etc...

Donc dans la version bourrine il faut faire un code qui vérifie à chaque couleurs l'état du bouton ?

Oui au lieu du délai et ça devrait interrompre l’arc en ciel si le bouton change d’état

Dans ce style là ?

const int pin_INTERRUPTEUR = 2;
const int pin_LED = 3;
boolean ledAllumer = 0;
boolean boutonAppuyer = 0;
int redPin = 9;
int greenPin = 10;
int bluePin = 11;

int r = 0;
int g = 0;
int b = 0;

void setup() {
  pinMode(pin_INTERRUPTEUR, INPUT_PULLUP);
  pinMode(pin_LED, OUTPUT);
  Serial.begin(9600);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop() { 
  setColor(255, 0, 0);    // red
  setColor(0, 255, 0);    // green
  setColor(0, 0, 255);    // blue
  setColor(255, 255, 0);  // yellow
  setColor(80, 0, 80);    // purple
  setColor(0, 255, 255);  // aqua
}

void setColor(int red, int green, int blue) {
  while ( r != red || g != green || b != blue ) {
    if ( r < red ) r += 1;
    if ( r > red ) r -= 1;

    if ( g < green ) g += 1;
    if ( g > green ) g -= 1;

    if ( b < blue ) b += 1;
    if ( b > blue ) b -= 1;

    _setColor();
    delay(10);
    if (digitalRead(pin_INTERRUPTEUR) == LOW) {
      digitalWrite(pin_LED, LOW);
      setColor(0, 0,0);
      return;
  }
}

void _setColor() {
  analogWrite(redPin, r);
  analogWrite(greenPin, g);
  analogWrite(bluePin, b); 
}

Il y a toujours un delay mais il est court et vous avez l’option de sortir avant la fin - la question est plus est-ce que ça vous convient ?

Je changerai le délais plus tard mais je voudrais que le code se relance lorsque je rappuie sur le bouton et également j'ai cette erreur dans mon code et je ne sais pas comment la résoudre :

'_setColor' was not declared in this scope

Bonjour,

Formate ton code avec ctrl t et tu verras qu'il manque } à la fin de la fonction setColor

Ça ne marche pas il me met : "Aucun changements nécessaires pour le formatage automatique"

Tu as mis le } qui manque?

C'est tout bon premier problème réglé (je n'avais pas mis le } :sweat_smile:)
Mais maintenant autre problèmes, le bandeau ne change pas de couleurs et reste bleu et le bouton ne marche pas (quand j'appuie, l'intensité lumineuse baisse légèrement et se met à clignoter très vite lorsque que le maintien) Voici une vidéo (lorsque que j'appuie, les leds restent bleu il ne change pas de couleurs)

Sur la vidéo, pourtant cela change de couleur ?

Il ne marche pas ou cela ne fait pas à ce que tu t'attends?
dans ton code quand tu appuis sur ton bouton, tu demandes à ton programme en boucle d'allumer de toute les couleurs(les différents setColor), mets remet immediatement(10ms) la couleur à 0:0:0, puis tu passe à la couleur suivante.

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

Et 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.

faut que je retrouve un petit exemple de rotation de couleurs avec un bandeau que j'avais fait pour un autre post

Bonjour, donc oui il change peut-être de couleurs mais extrêmement rapidement (impossible d'y distinguer) et oui il ne fait pas ce que j'attends.

Super merci je vais regarder ça :+1:

tenez voici un exemple avec une petite machine à état comme avec mon tuto.

Tant que le bouton est appuyé la LED reste allumée et la LED RGB augmente toutes les 10ms d'abord la composante rouge de 0 à 255, puis la verte, puis la bleue et recommence

le code

/* ============================================
  code is placed under the MIT license
  Copyright (c) 2023 J-M-L
  For the Arduino Forum : https://forum.arduino.cc/u/j-m-l

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  ===============================================
*/



#include <Toggle.h> // https://github.com/Dlloydev/Toggle/

const byte brocheBouton = 2;
const byte brocheLed = 3;
const byte brocheLedRouge = 9;
const byte brocheLedVerte = 10;
const byte brocheLedBleue = 11;

const unsigned long periodeAnimation = 20; // on change le RGB toutes les 20ms

Toggle bouton;

enum {REPOS, APPUYE} etat = REPOS;
byte intensiteRouge, intensiteVert, intensiteBleu;

void allumerLed() {
  digitalWrite(brocheLed, HIGH);
}
void eteindreLed() {
  digitalWrite(brocheLed, LOW);
}

void miseAJourRGB() {
  analogWrite(brocheLedRouge, intensiteRouge);
  analogWrite(brocheLedVerte, intensiteVert);
  analogWrite(brocheLedBleue, intensiteBleu);
}

void gestionBouton() {
  static unsigned long chrono;
  bouton.poll();

  switch (etat) {
    case REPOS:
      if (bouton.onPress()) { // on était au repos, on appuie sur le bouton
        intensiteRouge = 0;
        intensiteVert = 0;
        intensiteBleu = 0;
        miseAJourRGB();
        allumerLed();
        chrono = millis(); // on note le moment du dernier changement des LEDs
        etat = APPUYE;
      }
      break;

    case APPUYE:
      if (bouton.onRelease()) { // on vient de relâcher le boutonn
        intensiteRouge = 0;
        intensiteVert = 0;
        intensiteBleu = 0;
        miseAJourRGB();
        eteindreLed();
        etat = REPOS;
      } else { // on était appuyé et ça n'a pas changé, donc on tient le bouton appuyé
        if (millis() - chrono >= periodeAnimation) {
          // on est resté assez longtems allumé, on change les RGB
          // on monte d'abord le rouge à fond, puis le vert, puis le bleu et on recommence
          if (intensiteRouge == 255) {
            if (intensiteVert == 255) {
              if (intensiteBleu == 255) {
                intensiteRouge = 0;
                intensiteVert = 0;
                intensiteBleu = 0;
              } else intensiteBleu++;
            } else intensiteVert++;
          } else intensiteRouge++;

          miseAJourRGB();
          chrono = millis(); // on note le moment du dernier changement des LEDs
        }
      }
      break;
  }
}

void setup() {
  pinMode(brocheLed,  OUTPUT);
  pinMode(brocheLedRouge, OUTPUT);
  pinMode(brocheLedVerte, OUTPUT);
  pinMode(brocheLedBleue, OUTPUT);
  bouton.begin(brocheBouton);
}

void loop() {
  gestionBouton();
}

La LED RGB est à cathode commune.

J'ai testé le code mais tout d'abord je veux que mon bouton soit comme un interrupteur et non comme un bouton que l'on presse et que l'on relâche et enfin le code fait l'inverse de ce qu'il y a dans la simulation (j'ai essayé d'échanger deux morceaux mais ça ne fait pas ce que je veux)

c'est juste une machine à états... il suffit de ne pas attendre le onRelease() mais le prochain onPress()...

➜ je vous laisse proposer le changement

PS/ mettez vos liens youTube directement dans le post comme ça un lecteur est dispo directement sur le forum et on n'a pas à cliquer et aller voir les pubs google.