0

I was creating an RGB LED System with one 1 RGB LED controlled by an IR Remote. I wanted to assign a button to trigger a mood-light which cycles through the rainbow, and that works fine. But when I try to make a mode where you can change RGB Values directly, it doesn't work properly. I assigned numbers on the remote to switch the colour that you are changing (e.g 1 is red, 2 is green etc.), and the volume controls how much light is coming but when I have two colors with positive values it only displays one. I have no idea why because the moodlight works fine and even transitions smoothly.

//www.elegoo.com
//2016.12.9

#include "IRremote.h"

// Define Pins
int BLUE = 3;
int GREEN = 5;
int RED = 6;

int addValue = 10;

int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11

int blueValue = 0;
int greenValue = 0;
int redValue = 0;

bool isMoodLightOn = false;
bool isBlueModeOn = false;
bool isGreenModeOn = false;
bool isRedModeOn = true;

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'

/*-----( Function )-----*/
void translateIR() // takes action based on IR code received

// describing Remote IR codes 

{

  switch(results.value)

  {
  case 0xFFA25D: Serial.println("POWER"); break;
  case 0xFFE21D: Serial.println("FUNC/STOP"); break;
  case 0xFF629D: Serial.println("VOL+"); break;
  case 0xFF22DD: Serial.println("FAST BACK"); break;
  case 0xFF02FD: Serial.println("PLAY/PAUSE"); 
                 isMoodLightOn = !isMoodLightOn; 
                 if (isMoodLightOn == false) {
                  isBlueModeOn = true;
                  isGreenModeOn = false;
                  isRedModeOn = false;

                  setColor(redValue, greenValue, blueValue);
                 } else {
                  isBlueModeOn = false;
                  isGreenModeOn = false;
                  isRedModeOn = false;
                 }
                 break;
  case 0xFFC23D: Serial.println("FAST FORWARD"); break;
  case 0xFFE01F: Serial.println("DOWN"); 
                 if (isBlueModeOn) {
                  if (blueValue > 0) {
                    blueValue = blueValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isGreenModeOn) {
                  if (greenValue > 0) {
                    greenValue = greenValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isRedModeOn) {
                  if (redValue > 0) {
                    redValue = redValue - addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 break;
  case 0xFFA857: Serial.println("VOL-"); break;
  case 0xFF906F: Serial.println("UP"); 
                 if (isBlueModeOn) {
                  if (blueValue < 100) {
                    blueValue = blueValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isGreenModeOn) {
                  if (greenValue < 100) {
                    greenValue = greenValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 if (isRedModeOn) {
                  if (redValue < 100) {
                    redValue = redValue + addValue;
                    Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                    setColor(redValue, greenValue, blueValue);
                  }
                 }
                 break;
  case 0xFF9867: Serial.println("EQ"); break;
  case 0xFFB04F: Serial.println("ST/REPT"); break;
  case 0xFF6897: Serial.println("0"); break;
  case 0xFF30CF: Serial.println("1"); isRedModeOn = true; isGreenModeOn = false; isBlueModeOn = false; break;
  case 0xFF18E7: Serial.println("2"); isRedModeOn = false; isGreenModeOn = true; isBlueModeOn = false; break;
  case 0xFF7A85: Serial.println("3"); isRedModeOn = false; isGreenModeOn = false; isBlueModeOn = true; break;
  case 0xFF10EF: Serial.println("4"); break;
  case 0xFF38C7: Serial.println("5"); break;
  case 0xFF5AA5: Serial.println("6"); break;
  case 0xFF42BD: Serial.println("7"); break;
  case 0xFF4AB5: Serial.println("8"); break;
  case 0xFF52AD: Serial.println("9"); break;
  case 0xFFFFFFFF: Serial.println("REPEAT"); break;  

  default: 
    Serial.println(" other button   ");

  }// End Case

  delay(500); // Do not get immediate repeat


} //END translateIR
void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("IR Receiver Button Decode");

  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);

  setColor(redValue, greenValue, blueValue);

  isBlueModeOn = true;
  isGreenModeOn = false;
  isRedModeOn = false;

  irrecv.enableIRIn(); // Start the receiver

}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{ 
  setColor(redValue, greenValue, blueValue);

  if (irrecv.decode(&results)) // have we received an IR signal?

  {
    translateIR(); 
    irrecv.resume(); // receive the next value
  }

  setColor(redValue, greenValue, blueValue);

  if (isMoodLightOn == true) {
      int delayTime = 10; // fading time between colors

      redValue = 255; // choose a value between 1 and 255 to change the color.
      greenValue = 0;
      blueValue = 0;

      // this is unnecessary as we've either turned on RED in SETUP
      // or in the previous loop ... regardless, this turns RED off
      // analogWrite(RED, 0);
      // delay(1000);

      for(int i = 0; i < 255; i += 1) // fades out red bring green full when i=255
      {
        redValue -= 1;
        greenValue += 1;
        // The following was reversed, counting in the wrong directions
        // analogWrite(RED, 255 - redValue);
        // analogWrite(GREEN, 255 - greenValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }

      redValue = 0;
      greenValue = 255;
      blueValue = 0;

      for(int i = 0; i < 255; i += 1) // fades out green bring blue full when i=255
      {
        greenValue -= 1;
        blueValue += 1;
        // The following was reversed, counting in the wrong directions
        // analogWrite(GREEN, 255 - greenValue);
        // analogWrite(BLUE, 255 - blueValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }

      redValue = 0;
      greenValue = 0;
      blueValue = 255;

      for(int i = 0; i < 255; i += 1) // fades out blue bring red full when i=255
      {
        // The following code has been rearranged to match the other two similar sections
        blueValue -= 1;
        redValue += 1;
        // The following was reversed, counting in the wrong directions
        // analogWrite(BLUE, 255 - blueValue);
        // analogWrite(RED, 255 - redValue);
        setColor(redValue, greenValue, blueValue);
        delay(delayTime);
      }
  }
  setColor(redValue, greenValue, blueValue);
}/* --(end main loop )-- */

void setColor(int red, int green, int blue) {
  analogWrite(BLUE, blue);
  analogWrite(GREEN, green);
  analogWrite(RED, red);
}
1
  • You are using setColor() twice inside your loop function outside of the moodlight code. When not in moodlight mode, this functions repeats rapidly, doing many analogWrites in a short time. This resets the PWM hardware everytime, effectively distorting the signal. Try to remove those 2 lines (you don't need them, since you are already setting the colors within translateIR() ). And you may want the code to be more responsive when in moodlight mode. Then you should restructure your code to be non-blocking, like in the BlinkWithoutDelay example of the Arduino IDE.
    – chrisl
    Commented Dec 9, 2018 at 22:39

1 Answer 1

0

I will formulate my comment as a longer answer.

Inside your loop() function, you use setColor() twice, directly in the lowest level. When you are not in the moodlight mode, the whole if statement after it will not be executed, so there isn't much happening inside one iteration of the function and it will cycle through very fast, setting the colors again and again.

THe setColor() function only consists of calls to analogWrite(). It configures the Atmegas hardware, so that a PWM signal will be generated at the pin. For doing so, the corresponding hardware registers (for one of the timers). This also let's the PWM wave start again. If you are doing this very fast (meaning in the range of the PWM signal itself or faster), you will destroy the complete PWM waveform by starting over and over again. Image it as if you wait press the replay button on your music player again and again very fast. You would be able to recognize the music, as it is chopped up due to the replaying.

The aforementioned two lines are not necessary either, since the output of the PWM wave is done by hardware and does not require any code after it has been turned on by analogWrite(). So you can simply delete those two lines.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.