Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arc-en-ciel avec une led RGB et Arduino

Sujet résolu
    2 novembre 2018 à 20:39:05

    Bonsoir à tous,

    Je rencontre quelques difficultés dans mon projet arduino étant encore un débutant en la matière? J'ai à disposition une led RGB à cathode commune fourni avec le starter kit et j'aimerais réaliser un dégradé avec les différentes couleurs de l'arc-en-ciel.

    Malheureusement j'ai un soucis au niveau de mon code car il ne sort pas de ma fonction changeColor une fois que je suis rentrée dedans. J'ai essayé d'ajouter des breaks et des return mais cela ne change rien...

    Est-ce que le programme reste bloqué au niveau de la boucle for ou de la fonction je suis confus ?

    En attendant une aide quelconque voici mon code :

    /*
     * Code couleur :
     * Rouge : 255 0 0
     * Orange : 255 127 0
     * Jaune : 255 255 0
     * Vert : 0 210 0
     * Bleu clair : 0 200 200
     * Bleu foncé : 0 0 255
     * Violet : 127 0 255
     * Rose : 255 0 255
    */
    
    const int ledRed = 3;
    const int ledGreen = 6;
    const int ledBlue = 5;
    
    
    void setup() {
      Serial.begin(9600);
      pinMode(ledRed,OUTPUT);
      pinMode(ledGreen,OUTPUT);  
      pinMode(ledBlue,OUTPUT);
      
    }
    
    void loop() {
      analogWrite(ledRed,255);
      delay(1000);
      changeColor(255, 0, 0, 255, 127, 0);
      delay(50)
      Serial.println("lol");
      changeColor(255, 127, 0, 255, 255, 0);
      Serial.println("lola");
      changeColor(255, 255, 0, 0, 210, 0);
      Serial.println("lolaa");
      changeColor(0, 210, 0, 0, 200, 200);
      changeColor(0, 200, 200, 0, 0, 255);
      changeColor(0, 0, 255, 127, 0, 255);
      changeColor(127, 0, 255, 255, 0, 255);
      changeColor(255, 0, 255, 255, 0, 0);
    }
    
    void changeColor(byte red1, byte green1, byte blue1, byte red2, byte green2, byte blue2){
      
      byte valRed, valGreen, valBlue;
      boolean sensR, sensG, sensB;
    
      if (red1 < red2) {valRed = 0; sensR = 1;}
      else {valRed = 255; sensR = 0;}
      
      if (green1 < green2) {valGreen = 0; sensG = 1;}
      else {valGreen = 255; sensG = 0;} 
      
      if (blue1 < blue2) {valBlue = 0; sensB = 1;}
      else {valBlue = 255; sensB = 0;}
    
      for (byte i=0 ; i<256 ; i++)
      {
        if (sensR) valRed++;
        else valRed--;
    
        if (sensG) valGreen++;
        else valGreen--;
    
        if (sensB) valBlue++;
        else valBlue--;
    
        byte colorR = map(valRed,0,255,red1,red2);
        byte colorG = map(valGreen,0,255,green1,green2);
        byte colorB = map(valBlue,0,255,blue1,blue2);
    
        analogWrite(ledRed,colorR);
        analogWrite(ledGreen,colorG);
        analogWrite(ledBlue,colorB);
        Serial.println(colorR);
        Serial.println(colorG);
        Serial.println(colorB);
        Serial.println("########");
        delay(25);
      }
    }



    • Partager sur Facebook
    • Partager sur Twitter
      2 novembre 2018 à 21:22:43

      for (byte i=0 ; i<256 ; i++)

      La valeur d'une variable de type byte est entre 0 et 255, donc toujours inférieure à 256, donc la condition est toujours vraie.

      Tu peux remplacer le type par int.

      • Partager sur Facebook
      • Partager sur Twitter
        3 novembre 2018 à 13:58:58

        Merci beaucoup alexisdm pour cette réponse !

        J'ai donc modifié mon programme en conséquence mais j'ai maintenant un problème au niveau de mes couleurs qui se dégrade bien dans ma boucle for mais qui change brusquement lors d'un autre appel de ma fonction changeColor

        Voici mon code que j'ai modifié depuis hier soir mais j'ai toujours des problèmes :

        const int ledR = 3;
        const int ledG = 6;
        const int ledB = 5;
        
        #define TIME 4
        #define PAUSE 250
        #define maxLum 255
        
        void setup() {
          pinMode(ledR,OUTPUT);
          pinMode(ledG,OUTPUT);
          pinMode(ledB,OUTPUT);
        
          digitalWrite(ledR,HIGH);
          delay(500);
        }
        
        void loop() {
          changeColor(255, 0, 0, 0, -128, 0);
          changeColor(255, 127, 0, 255, 128, 0);
          changeColor(255, 255, 0, -255, -45, 0);
          changeColor(0, 210, 0, 0, -10, 200);
          changeColor(0, 200, 200, 0, -200, 55);
          changeColor(0, 0, 255, 127, 0, 0);
          changeColor(127, 0, 255, 128, 0, 0);
          changeColor(255, 0, 255, 0, 0, -255);
        }
        
        void changeColor(int red, int green, int blue, int ecartR, int ecartG, int ecartB){
          
          int startR, finishR, sensR, valR, colorR,
              startG, finishG, sensG, valG, colorG,
              startB, finishB, sensB, valB, colorB;
          
          if (ecartR > 0) {startR = 0; finishR = maxLum; sensR = 1;}
          else if (ecartR < 0) {startR = maxLum; finishR = 0; sensR = -1;}
          else sensR = 0;
        
          if (ecartG > 0) {startG = 0; finishG = maxLum; sensG = 1;}
          else if (ecartG < 0) {startG = maxLum; finishG = 0; sensG = -1;}
          else sensG = 0;
        
          if (ecartB > 0) {startB = 0; finishB = maxLum; sensB = 1;}
          else if (ecartB < 0) {startB = maxLum; finishB = 0; sensB = -1;}
          else sensB = 0;
          
          valR = startR;
          valB = startB;
          valG = startG;
          
          for (int i=0 ; i<(maxLum+1) ; i++)
          {
            if (sensR == 1) 
            {
              valR++;
              colorR = map(valR,startR,finishR,red,(red+ecartR));
            }
            
            else if (sensR == -1)
            {
              valR--;
              colorR = map(valR,startR,finishR,red,(red-ecartR));
            }
            
            else colorR = red;
        
        
            if (sensG == 1) 
            {
              valG++;
              colorG = map(valG,startG,finishG,green,(green+ecartG));
            }
            
            else if (sensG == -1)
            {
              valG--;
              colorG = map(valG,startG,finishG,green,(green-ecartG));
            }
            
            else colorG = green;
        
            if (sensB == 1) 
            {
              valB++;
              colorG = map(valB,startB,finishB,blue,(blue+ecartB));
            }
            
            else if (sensB == -1)
            {
              valB--;
              colorB = map(valB,startB,finishB,blue,(blue-ecartG));
            }
            
            else colorB = blue;
        
            
            analogWrite(ledR,colorR);
            analogWrite(ledG,colorG);
            analogWrite(ledB,colorB);
            delay(TIME);
          }
          delay(PAUSE);
        }

        Merci de votre aide !

        • Partager sur Facebook
        • Partager sur Twitter
          3 novembre 2018 à 17:06:24

          J'avoue ne pas trop comprendre ton code ni le fait que ta fonction changeColor prenne 3 paramètres...

          Pourquoi ne pas faire plus simple avec seulement 3 paramètres correspondant à la nouvelle couleur à afficher ?

          Quelque chose dans ce style, tout simplement :

          const int pinLedR = 3;
          const int pinLedG = 6;
          const int pinLedB = 5;
          
          byte colorR = 0;
          byte colorG = 0;
          byle colorB = 0;
           
          #define TIME 4
          
          void setup(void);
          void loop(void);
          void changeColor(byle r, byle g, byle b);
          
          void setup(void) {
          	pinMode(pinLedR,OUTPUT);
          	pinMode(pinLedG,OUTPUT);
          	pinMode(pinLedB,OUTPUT);
          	analogWrite(pinLedR,colorR);
          	analogWrite(pinLedG,colorG);
          	analogWrite(pinLedB,colorB);
          }
          
          void loop() {
          	changeColor(255,0,0);
          	changeColor(255,255,0);
          	changeColor(0,255,0);
          	changeColor(0,255,255);
          	changeColor(0,0,255);
          	changeColor(255,0,255);
          }
           
          void changeColor(byle r, byle g, byle b) {
          	
          	// Temps que la couleur actuelle n'est pas la couleur demandée
          	while ( ( r != colorR ) || ( g != colorG ) || ( b != colorB ) ) {
          	
          		// Alors on se rapproche d'une unité
          		if ( r > colorR ) colorR++;
          		if ( r < colorR ) colorR--;
          		if ( g > colorR ) colorG++;
          		if ( g < colorR ) colorG--;
          		if ( b > colorR ) colorB++;
          		if ( b < colorR ) colorB--;
          		
          		// Puis on affiche la couleur
          		analogWrite(pinLedR,colorR);
          		analogWrite(pinLedG,colorG);
          		analogWrite(pinLedB,colorB);
          		
          		// Et on attend un peu
          		delay(TIME);
          		
          	}
          	
          }



          -
          Edité par lorrio 3 novembre 2018 à 20:48:36

          • Partager sur Facebook
          • Partager sur Twitter
            3 novembre 2018 à 17:32:51

            Merci de ta réponse lorrio, il est vrai que je n'ai pas exprimé les conditions que devaient remplir mon programme donc je vais te les décrire rapidement :

            Je souhaite effectuer un fondu entre ces 8 couleurs différentes sans aucune coupure entre les transitions :

            /*
             * Code couleur :
             * Rouge : 255 0 0
             * Orange : 255 127 0
             * Jaune : 255 255 0
             * Vert : 0 210 0
             * Bleu clair : 0 200 200
             * Bleu foncé : 0 0 255
             * Violet : 127 0 255
             * Rose : 255 0 255
            */

            (J'ai noté les valeurs des différentes couleurs pour les réutiliser plus tard)

            Mon code n'est clairement pas optimisé car j'ai besoin d'avoir des leds qui varient d'intensité en même temps mais pas de valeurs différentes.

            Par exemple pour faire un fondu du jaune au vert j'ai besoin que ma led rouge s'éteigne tandis que ma led verte doit diminuer son intensité de 210-200 = 10 (ce sont les écarts que je définis plus bas).

              if (ecartR > 0) {startR = 0; finishR = maxLum; sensR = 1;}
              else if (ecartR < 0) {startR = maxLum; finishR = 0; sensR = -1;}
              else sensR = 0;



            J'utilise donc la fonction map pour avoir un diminution/augmentation de plages différentes mais sur un même temps.

            colorR = map(valR,startR,finishR,red,(red+ecartR));



            Là où mon programme fait défaut c'est de changer les intensités des leds d'un coup et je ne comprends pas trop d'où ça vient ;/

            Ton idée n'est pas mauvaise mais du coup chez toi aussi il y a des changements d'intensité entre les boucles.

            J'espère avoir été assez clair

            -
            Edité par GridexX 3 novembre 2018 à 17:40:57

            • Partager sur Facebook
            • Partager sur Twitter
              3 novembre 2018 à 20:52:29

              Dans ce cas, tu peux effectivement utiliser map avec ma technique tout en gardant que 3 paramètres ;)

              Par contre, pour map, mieux vaut utiliser int que byte, ce qui donne :

              int colorR = 0;
              int colorG = 0;
              int colorB = 0;
              
              void changeColor(int newR, int newG, int newB) {
              	
              	// On boucle de 0 à 255 inclus pour faire 256 transitions
              	for ( int i = 0 ; i < 256 ; i++ ) {
              		
              		// On map la couleur à afficher chaque étape de la transition
              		int r = map(i, 0, 255, colorR, newR);
              		int g = map(i, 0, 255, colorG, newG);
              		int b = map(i, 0, 255, colorB, newB);
              		
              		// On affiche la couleur
              		analogWrite(pinLedR, r);
              		analogWrite(pinLedG, g);
              		analogWrite(pinLedB, b);
              		 
              		// On attend un peu
              		delay(TIME);
              		
              	}
              	
              	// Et pour finir, on sauvegarde cette nouvelle couleur
              	colorR = newR;
              	colorG = newG;
              	colorB = newB;
              	
              }
              

              -
              Edité par lorrio 3 novembre 2018 à 20:53:45

              • Partager sur Facebook
              • Partager sur Twitter
                4 novembre 2018 à 12:32:23

                Ok je comprend mieux pourquoi mon code ne fonctionnait pas, je ne sauvegardais pas les couleurs à la fin de la boucle ce qui fait qu'elles se réinitialisaient.

                Merci beaucoup de ton aide c'est vrai que je me suis compliqué la chose avec mes variables de sens et de variables de mappage des données !

                Pour ceux que ça intéresse voici donc le code définitif avec quelques changements :

                • seulement 6 couleurs : rouge, jaune, vert, cyan, bleu et magenta ( j'ai enlevé mes couleurs intermédiaires comme le orange et le violet car le fondu parait ralentir avec)
                • simplification de la fonction changeColor (merci à lorrio) qui était beaucoup trop complexe
                • ajout de commentaires :)
                /*
                *  Arc-en-ciel avec led RVB
                *  Description : fondu entre les différentes couleurs primaires à l'aide d'une led RVB
                *  Auteur : GridexX avec l'aide de lorrio
                *  Date : 4/11/2018
                *  https://openclassrooms.com/forum/sujet/arc-en-ciel-avec-une-led-rgb-et-arduino?page=1#message-92734685
                */
                
                //Définition des pins de la led RVB
                const int pinLedR = 3;
                const int pinLedG = 6;
                const int pinLedB = 5;
                
                //Mise à 0 des premiers termes de chaque led pour le mappage 
                int colorR = 0;
                int colorG = 0;
                int colorB = 0;
                
                //temps de pause défini à chaque itération
                //Temps total pour la loop (en milliseconde) = 6*255*TIME = 1530*TIME
                //Pour une boucle de 1 minute : TIME = 60000/1530 = 39
                #define TIME 39
                
                void setup() {  
                  
                  pinMode(pinLedR,OUTPUT);
                  pinMode(pinLedG,OUTPUT);
                  pinMode(pinLedB,OUTPUT);
                  
                }
                
                void loop() {
                
                  //Appel de la fonction pour changer la couleur avec les différentes valeurs
                  changeColor(255,0,0);
                  changeColor(255,255,0);
                  changeColor(0,255,0);
                  changeColor(0,255,255);
                  changeColor(0,0,255);
                  changeColor(255,0,255);
                    
                }
                 
                void changeColor(int newR, int newG, int newB) {
                     
                  // On boucle de 0 à 255 inclus pour faire 256 transitions
                  for ( int i = 0 ; i < 256 ; i++ ) {
                         
                    // On map la couleur à afficher chaque étape de la transition
                    int r = map(i, 0, 255, colorR, newR);
                    int g = map(i, 0, 255, colorG, newG);
                    int b = map(i, 0, 255, colorB, newB);
                         
                    // On affiche la couleur
                    analogWrite(pinLedR, r);
                    analogWrite(pinLedG, g);
                    analogWrite(pinLedB, b);
                          
                    // On attend un peu
                    delay(TIME);
                         
                  }
                     
                  // Et pour finir, on sauvegarde cette nouvelle couleur
                  colorR = newR;
                  colorG = newG;
                  colorB = newB;
                     
                }


                • Partager sur Facebook
                • Partager sur Twitter

                Arc-en-ciel avec une led RGB et Arduino

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown