Code only seems to work if it passes through while loop?

Hi Reader,
I am using a Nano, an IR remote/IR receiver (both work well), and a rgb LED. Hardware, circuit, etc is in order.
My problem is that when I go from ex. red to cyan ("passing" cyan and then reaching the end of the while loop), "myColOld" becomes "cyan" when I want it to be "red".
But if I go from cyan to red (reaching the end of the while loop without "passing" red) then "myColOld" becomes "cyan" like I want it to.

Help would be much appreciated.

Here is the complete code:

//brightness should be kept the same while switching between colors
//intensity ratio needs to reset as color is changed

#include <IRremote.h>

int IRPin=2;

int bluePin=A2;
int greenPin=A1;
int redPin=A0;
int blueStrength;
int greenStrength;
int redStrength;
int SPV=140;

float intensityRatio;

String myCom="OFF";
String myCol;
String myColOld;
String myColNew;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
IrReceiver.begin(IRPin, ENABLE_LED_FEEDBACK);
pinMode(bluePin,OUTPUT);
pinMode(greenPin,OUTPUT);
pinMode(redPin,OUTPUT);

Serial.println("Hi User, welcome to the IR-Remote RGB LED controller!");
Serial.println("These are the commands:");
Serial.println("Red button: On/OFF");
Serial.println("1 = Red");
Serial.println("2 = Green");
Serial.println("3 = Blue");
Serial.println("4 = Cyan");
Serial.println("5 = Magenta");
Serial.println("6 = Yellowish");
Serial.println("0 = White");
Serial.println("UP = Increase brighntess");
Serial.println("DOWN = Decrease brightness");
Serial.println("Remember, these commands will ONLY work after the LED has started. You can read which command you have selected on the LCD screen");
Serial.println();
}

void loop() {
  // put your main code here, to run repeatedly:

digitalWrite(bluePin,LOW);
digitalWrite(greenPin,LOW);
digitalWrite(redPin,LOW);
intensityRatio=1.0;

while(IrReceiver.decode()==0){
  
}

IrReceiver.decodedIRData.decodedRawData, HEX;
delay(1000);
IrReceiver.resume();

if(IrReceiver.decodedIRData.decodedRawData == 0xBA45FF00 && myCom=="OFF") {
  myCom = "ON";
  myCol = "white";
  myColOld = "white";
  Serial.println("Command selected = ON");
  Serial.println();
  blueStrength=255;
  greenStrength=255;
  redStrength=255;
}

while(myCom!="OFF"){
  while(IrReceiver.decode()==0){
    analogWrite(bluePin,blueStrength);
    analogWrite(greenPin,greenStrength);
    analogWrite(redPin,redStrength);
  }
  
  IrReceiver.decodedIRData.decodedRawData, HEX;
  delay(1000);
  IrReceiver.resume();
  
  if(IrReceiver.decodedIRData.decodedRawData == 0xBA45FF00) {
    myCom="OFF";
    Serial.println("Command selected = OFF");
  }
  
  if(IrReceiver.decodedIRData.decodedRawData == 0xF30CFF00) {
    myCom = "red";
    myColNew = "red";
    Serial.println("Command selected = Red");
    blueStrength=0;
    greenStrength=0;
      if((255*intensityRatio)>=SPV){
        redStrength=255*intensityRatio;
      }
      else{
        redStrength=SPV;
      }
     if(myCol=="white" && myColNew=="red"){
      myCol="red";
      myColOld="white";      
     }
     if(myCol=="red" && myColNew=="red"){
      myCol="red";
      myColOld="red";      
     }
     if(myCol=="green" && myColNew=="red"){
      myCol="red";
      myColOld="green";      
     }
     if(myCol=="blue" && myColNew=="red"){
      myCol="red";
      myColOld="blue";      
     }
     if(myCol=="cyan" && myColNew=="red"){
      myCol="red";
      myColOld="cyan";      
     }
     if(myCol=="magenta" && myColNew=="red"){
      myCol="red";
      myColOld="magenta";      
     }
     if(myCol=="yellow" && myColNew=="red"){
      myCol="red";
      myColOld="yellow";      
     }
     Serial.print("myCol: ");
     Serial.println(myCol);
     Serial.print("myColOld: ");
     Serial.println(myColOld);     
  }
  
  if(IrReceiver.decodedIRData.decodedRawData == 0xE718FF00) {
    myCom = "green";
    myColNew = "green";
    Serial.println("Command selected = Green");
    blueStrength=0;
      if((255*intensityRatio)>=SPV){
        greenStrength=255*intensityRatio;
      }
      else{
        greenStrength=SPV;
      }
    redStrength=0;
    if(myCol=="white" && myColNew=="green"){
      myCol="green";
      myColOld="white";      
     }
     if(myCol=="red" && myColNew=="green"){
      myCol="green";
      myColOld="red";      
     }
     if(myCol=="green" && myColNew=="green"){
      myCol="green";
      myColOld="green";      
     }
     if(myCol=="blue" && myColNew=="green"){
      myCol="green";
      myColOld="blue";      
     }
     if(myCol=="cyan" && myColNew=="green"){
      myCol="green";
      myColOld="cyan";      
     }
     if(myCol=="magenta" && myColNew=="green"){
      myCol="green";
      myColOld="magenta";      
     }
     if(myCol=="yellow" && myColNew=="green"){
      myCol="green";
      myColOld="yellow";      
     }
     Serial.print("myCol: ");
     Serial.println(myCol);
     Serial.print("myColOld: ");
     Serial.println(myColOld); 
  }

  if(IrReceiver.decodedIRData.decodedRawData == 0xA15EFF00) {
   myCom = "blue";
   myColNew = "blue";
    Serial.println("Command selected = Blue");
      if((255*intensityRatio)>=SPV){
        blueStrength=255*intensityRatio;
      }
      else{
        blueStrength=SPV;
      }  
    greenStrength=0;
    redStrength=0;
    if(myCol=="white" && myColNew=="blue"){
      myCol="blue";
      myColOld="white";      
     }
     if(myCol=="red" && myColNew=="blue"){
      myCol="blue";
      myColOld="red";      
     }
     if(myCol=="green" && myColNew=="blue"){
      myCol="blue";
      myColOld="green";      
     }
     if(myCol=="blue" && myColNew=="blue"){
      myCol="blue";
      myColOld="blue";      
     }
     if(myCol=="cyan" && myColNew=="blue"){
      myCol="blue";
      myColOld="cyan";      
     }
     if(myCol=="magenta" && myColNew=="blue"){
      myCol="blue";
      myColOld="magenta";      
     }
     if(myCol=="yellow" && myColNew=="blue"){
      myCol="blue";
      myColOld="yellow";      
     }
     Serial.print("myCol: ");
     Serial.println(myCol);
     Serial.print("myColOld: ");
     Serial.println(myColOld);
  }
  
  if(IrReceiver.decodedIRData.decodedRawData == 0xF708FF00) {
    myCom = "cyan";
    myColNew = "cyan";
    Serial.println("Command selected = Cyan");
    blueStrength=255*intensityRatio; 
      if((155*intensityRatio)>=SPV){
        greenStrength=155*intensityRatio;
      }
      else{
        greenStrength=SPV;
      }
    redStrength=0;
    if(myCol=="white" && myColNew=="cyan"){
      myCol="cyan";
      myColOld="white";      
     }
     if(myCol=="red" && myColNew=="cyan"){
      myCol="cyan";
      myColOld="red";      
     }
     if(myCol=="green" && myColNew=="cyan"){
      myCol="cyan";
      myColOld="green";      
     }
     if(myCol=="blue" && myColNew=="cyan"){
      myCol="cyan";
      myColOld="blue";      
     }
     if(myCol=="cyan" && myColNew=="cyan"){
      myCol="cyan";
      myColOld="cyan";      
     }
     if(myCol=="magenta" && myColNew=="cyan"){
      myCol="cyan";
      myColOld="magenta";      
     }
     if(myCol=="yellow" && myColNew=="cyan"){
      myCol="cyan";
      myColOld="yellow";      
     }
     Serial.print("myCol: ");
     Serial.println(myCol);
     Serial.print("myColOld: ");
     Serial.println(myColOld);
  }
  
  if(IrReceiver.decodedIRData.decodedRawData == 0xE31CFF00) {
    myCom = "magenta";
    myColNew = "magenta";
    Serial.println("Command selected = Magenta");
    blueStrength=255*intensityRatio;
    greenStrength=0;
      if((155*intensityRatio)>=SPV){
        redStrength=155*intensityRatio;
      }
      else{
        redStrength=SPV;
      }
    if(myCol=="white" && myColNew=="magenta"){
      myCol="magenta";
      myColOld="white";      
     }
     if(myCol=="red" && myColNew=="magenta"){
      myCol="magenta";
      myColOld="red";      
     }
     if(myCol=="green" && myColNew=="magenta"){
      myCol="magenta";
      myColOld="green";      
     }
     if(myCol=="blue" && myColNew=="magenta"){
      myCol="magenta";
      myColOld="blue";      
     }
     if(myCol=="cyan" && myColNew=="magenta"){
      myCol="magenta";
      myColOld="cyan";      
     }
     if(myCol=="magenta" && myColNew=="magenta"){
      myCol="magenta";
      myColOld="magenta";      
     }
     if(myCol=="yellow" && myColNew=="magenta"){
      myCol="magenta";
      myColOld="yellow";      
     }
     Serial.print("myCol: ");
     Serial.println(myCol);
     Serial.print("myColOld: ");
     Serial.println(myColOld);     
  }
  
  if(IrReceiver.decodedIRData.decodedRawData == 0xA55AFF00) {
    myCom = "yellow";
    myColNew = "yellow";
    Serial.println("Command selected = Yellow");
    blueStrength=0;
    greenStrength=SPV;
    redStrength=255*intensityRatio;
    if(myCol=="white" && myColNew=="yellow"){
      myCol="yellow";
      myColOld="white";      
     }
     if(myCol=="red" && myColNew=="yellow"){
      myCol="yellow";
      myColOld="red";      
     }
     if(myCol=="green" && myColNew=="yellow"){
      myCol="yellow";
      myColOld="green";      
     }
     if(myCol=="blue" && myColNew=="yellow"){
      myCol="yellow";
      myColOld="blue";      
     }
     if(myCol=="cyan" && myColNew=="yellow"){
      myCol="yellow";
      myColOld="cyan";      
     }
     if(myCol=="magenta" && myColNew=="yellow"){
      myCol="yellow";
      myColOld="magenta";      
     }
     if(myCol=="yellow" && myColNew=="yellow"){
      myCol="yellow";
      myColOld="yellow";      
     }
     Serial.print("myCol: ");
     Serial.println(myCol);
     Serial.print("myColOld: ");
     Serial.println(myColOld);
  }
  
  if(IrReceiver.decodedIRData.decodedRawData == 0xE916FF00) {
    myCom = "white";
    myColNew = "white";
    Serial.println("Command selected = White");
    blueStrength=255*intensityRatio;
    greenStrength=255*intensityRatio;
    redStrength=255*intensityRatio;
    if(myCol=="white" && myColNew=="white"){
      myCol="white";
      myColOld="white";      
     }
     if(myCol=="red" && myColNew=="white"){
      myCol="white";
      myColOld="red";      
     }
     if(myCol=="green" && myColNew=="white"){
      myCol="white";
      myColOld="green";      
     }
     if(myCol=="blue" && myColNew=="white"){
      myCol="white";
      myColOld="blue";      
     }
     if(myCol=="cyan" && myColNew=="white"){
      myCol="white";
      myColOld="cyan";      
     }
     if(myCol=="magenta" && myColNew=="white"){
      myCol="white";
      myColOld="magenta";      
     }
     if(myCol=="yellow" && myColNew=="white"){
      myCol="white";
      myColOld="yellow";      
     }
     Serial.print("myCol: ");
     Serial.println(myCol);
     Serial.print("myColOld: ");
     Serial.println(myColOld); 
  }

  if(IrReceiver.decodedIRData.decodedRawData == 0xF807FF00) {
    myCom = "down";
    Serial.println("Command selected = Decrease LED intensity");
      if(blueStrength >= SPV){
        blueStrength=blueStrength-((blueStrength/100)*5);
        float NewBlueStrength=blueStrength-((blueStrength/100)*5);
        intensityRatio=NewBlueStrength/blueStrength;
        Serial.println(intensityRatio);
       }
      if(greenStrength >= SPV){
        greenStrength=greenStrength-((greenStrength/100)*5);
        float NewGreenStrength=blueStrength-((greenStrength/100)*5);
        intensityRatio=NewGreenStrength/greenStrength;
        Serial.println(intensityRatio);
      }
      if(redStrength >= SPV){
        redStrength=redStrength-((redStrength/100)*5);
        float NewRedStrength=redStrength-((redStrength/100)*5);
        intensityRatio=NewRedStrength/redStrength;
        Serial.println(intensityRatio);
      }
  }  

  if(IrReceiver.decodedIRData.decodedRawData == 0xF609FF00) {
    myCom = "up";
    Serial.println("Command selected = Increase LED intensity");
  }
  Serial.print("blueStrength: ");
  Serial.println(blueStrength);
  Serial.print("greenStrength: ");
  Serial.println(greenStrength);
  Serial.print("redStrength: ");
  Serial.println(redStrength);
  Serial.println();

  if(myColOld != myCol){
  intensityRatio=1.0;
  }        
}

}

Whatever the problem is if I were you I would not be using Strings for the colour values. It is totally inappropriate

Instead, consider using a enum to declare the colour names like this

enum colours
{
  RED,
  BLUE,
  GREEN,
};

You can then use these values like this

myColOld = RED;
myColNew = GREEN;

and test values like this

if (myColOld == RED && myColNew == BLUE)
{
  //do something
}

The same goes for the myCom variable

    if (IrReceiver.decodedIRData.decodedRawData == 0xE718FF00)
    {
      myCom = GREEN;
      myColNew = GREEN;

I also suspect that there is an easier way to do what you are trying to do but as I haven't got the foggiest what that is I cannot be sure

Please explain what the sketch should do

1 Like

Hi UKHeliBob,

why is it "totally inappropriate" to use strings in this situation (Noob here)? :thinking:

the code is meant to accomplish the following:

  1. turn the LED on and off (white).
  2. be able to change between different colors while ON.
  3. be able to dim or increase the brightness of x light.
  4. keep the same level of brightness while going from x to y color (hence the "intensity ratio").

I am trying to do this homework:

hope this helps :slight_smile:

because it's a multibyte string comparison instead of a single byte comparison

Because String is just not the correct data type for the job. The named variables can each be held in a single byte so why use multiple bytes to do the job. There is also the fact that using Strings tends to fragment memory to the point where it can be a problem. Probably not in your sketch but it is best practice to use the most appropriate data type in each circumstance and not to get into bad habits

As to your sketch, having looked at the video, you seem to be making things more complicated than they need to be. The requirements seem simple. Read the IR input and take actions based on which command is received and the current state of the system at the time

These statements (there are multiple) do nothing. What do you think they are doing?

You do not need to continuously write the same value to the LED pins...
In general, you should get rid of all those while() statements and loop() do what it is designed to do... loop.

ok, that makes sense. Thanks :slight_smile:

You are mistaken, this statement does do something which can be proven by the fact that when I remove this statement in the while loop, the loop gets stuck in ON and I cannot do anything (turn it off, change colors, etc).

Which statement? This statement is what I said does nothing

IrReceiver.decodedIRData.decodedRawData, HEX;

The while() loop, does do something, but I just pointed out you don't have to repeatedly do analogWrite() with the same value

Yes, I disagree due to the above reason I gave.
What I think it does is to receive the IR signal and convert it into a hex format...

Also those values are different (redStrength, blueStrength, etc) and they need to be different in order to change the color to example cyan, magenta, etc.

What it actually does is not the same as what you think it does. Hint: the statement IrReceiver.decodedIRData.decodedRawData, HEX; does nothing.

If you turn on all compiler warnings in the IDE, I'm fairly certain that you'll get a warning on that line like "statement has no effect", which tells you that you very likely (certainly in this case) made a mistake.

Then you are wrong. If you were to wrap that entire line in a Serial.print() call, then it would take the value stored in IrReceiver.decodedIRData.decodedRawData and send it out as a hexadecimal representation.

But, since you have it all by itself, you are basically taking a number, then a comma followed by another number, the same as

123454, 1;

which also does nothing

As for the while loop(), you are writing 3 different values, but each time through the loop, those 3 values remain constant. Once .decode() is non-zero, the code moves on and possibly changes those values. Your loop

while(IrReceiver.decode()==0){
    analogWrite(bluePin,blueStrength);
    analogWrite(greenPin,greenStrength);
    analogWrite(redPin,redStrength);
  }

is the same as

analogWrite(bluePin,blueStrength);
analogWrite(greenPin,greenStrength);
analogWrite(redPin,redStrength);
while(IrReceiver.decode()==0){
  }

That was my point.

Ok, you were right. I double checked and the program runs fine without that line.

"As for the while loop(), you are writing 3 different values, but each time through the loop, those 3 values remain constant."
Although that's what I want to do; keep them the same until a new input from the IR remote arrives (and then those values change).