Arduino Freezes For Unidentifiable Reason

I'm trying to hook up an IR remote with an RGB led. It works for the most part. I can use the power key to turn it white, the stop/func key to turn it off. I can also increment the red and green values up and down by selecting the mode and using the up and down key. I can confirm that blue can go down but when it goes up it prints up to the Serial monitor and then freezes, doing nothing and not responding to my button presses. I am using the 2.2.3 version of the IR remote library for reference.

#include <IRremote.h>

int IRpin=3;
IRrecv IR(IRpin);
decode_results cmd;
String myCom;

int rPin = 9;
int gPin = 10;
int bPin = 11;

int rVal = 0;
int gVal = 0;
int bVal = 0;

String mode = "red";

void setup() {
  pinMode(rPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(bPin, OUTPUT);
  Serial.begin(9600);
  IR.enableIRIn();
}
 
void loop() {
  myCom = "";
  while (IR.decode(&cmd) == 0){}

  if (cmd.value==0xFF6897) {
    myCom = "zero";
    mode = "red";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF30CF) {
    myCom = "one";
    mode = "green";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF18E7) {
    myCom = "two";
    mode = "blue";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF7A85) {
    myCom="three";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF10EF) {
    myCom="four";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF38C7) {
    myCom="five";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF5AA5){
    myCom="six";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF42BD) {
    myCom="seven";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF4AB5) {
    myCom="eight";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF52AD) {
    myCom="nine";
    Serial.println(myCom); 
  }
   
  if (cmd.value==0xFFA25D) {
    myCom="pwr";
    Serial.println(myCom); 
  }
  if (cmd.value==0xFF629D) {
    myCom="v+";
    Serial.println(myCom);
  }
  if (cmd.value==0xFFE21D) {
    myCom="fun";
    Serial.println(myCom);
  }
  if (cmd.value==0xFF22DD) {
    myCom="rew";
    Serial.println(myCom);
  }
  if (cmd.value==0xFF02FD) {
    myCom="play";
    Serial.println(myCom);
  }
  if (cmd.value==0xFFC23D) {
    myCom="ff";
    Serial.println(myCom);
  }
  if (cmd.value==0xFFE01F) {
    myCom="dn";
    Serial.println(myCom);
  }
  if (cmd.value==0xFFA857) {
    myCom="v-";
    Serial.println(myCom);
  }
  if (cmd.value==0xFF906F) {
    myCom="up";
    Serial.println(myCom);
  }
  if (cmd.value==0xFF9867) {
    myCom="eq";
    Serial.println(myCom);
  }
  if (cmd.value==0xFFB04F) {
    myCom="st";
    Serial.println(myCom);
  }

//Commenting the 6 lines below this makes it work, but it doesn't let me increment the blue up which is frustrating

  if (myCom == "up") {
    if (mode == "blue") {
       if (bVal < 255) {
         bVal += 15;
       }
     }
// THESE LINES ARE THE PROBLEM ^^^^
    if (mode == "red") {
      if (rVal < 255) {
        rVal += 15;
      }
    }
    if (mode == "green") {
      if (gVal < 255) {
        gVal += 15;
      }
    }
  }
  if (myCom == "dn") {
    if (mode == "red") {
      if (rVal > 0) {
        rVal -= 15;
      }
    }
    if (mode == "blue") {
      if (bVal > 0) {
        bVal -= 15;
      }
    }
    if (mode == "green") {
      if (gVal > 0) {
        gVal -= 15;
      }
    }
  }
  if (myCom == "pwr") {
    rVal = 255;
    gVal = 255;
    bVal = 255;
  }
  if (myCom == "fun") {
    rVal = 0;
    gVal = 0;
    bVal = 0;
  }

  Serial.println(rVal);
  Serial.println(gVal);
  Serial.println(bVal);
  analogWrite(rPin, rVal);
  analogWrite(gPin, gVal);
  analogWrite(bPin, bVal);

  delay(500);
  IR.resume();
}

what board are you using? You are using a lot of Strings which take up a ton of space. Something that is very limited. It would be far better to use C strings [null terminated char arrays] or better yet, use an enum type (int)

Your rVal, gVal, bVal variables should be of type byte, not int and you never check to make sure you increment/decrement stays in the range of 0-255 which is necessary for analogWrite().

First off, I am on an arduino uno.
Secondly, I should try to change them to byte to see if it works.
And thirdly, I do check before I increment to make sure that the value is less then 255 before I add(ex. 240 or lower) or higher than 0 (ex. 15 or higher) before I add and subtract respectively

that is true, but it only works because you are using a value (15) that divides into 255.

something like this will use a lot less dynamic memory

#include <IRremote.h>

const int IRpin = 3;
IRrecv IR(IRpin);
decode_results cmd;


const int rPin = 9;
const int gPin = 10;
const int bPin = 11;

int rVal = 0;
int gVal = 0;
int bVal = 0;

enum { UNKNOWN_CODE, ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE,
       POWER, VOL_UP, VOL_DOWN, FUN, REWIND, PLAY, FF, UP, DOWN, EQUAL, ST
     };
int myCom;

enum { RED, GREEN, BLUE };
int mode;


void setup() {
  pinMode(rPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(bPin, OUTPUT);
  Serial.begin(9600);
  IR.enableIRIn();
}

void loop() {

  while (IR.decode(&cmd) == 0) {}

  switch (cmd.value) {

    case 0xFF6897:
      myCom = ZERO;
      mode = RED;
      Serial.println( F("zero"));
      break;

    case 0xFF30CF:
      myCom = ONE;
      mode = GREEN;
      Serial.println( F("one"));
      break;

    case 0xFF18E7:
      myCom = TWO;
      mode = BLUE;
      Serial.println( F("two"));
      break;

    case 0xFF7A85:
      myCom = THREE;
      Serial.println( F("three"));
      break;

    case 0xFF10EF:
      myCom = FOUR;
      Serial.println( F("four"));
      break;

    case 0xFF38C7:
      myCom = FIVE;
      Serial.println( F("five"));
      break;

    case 0xFF5AA5:
      myCom = SIX;
      Serial.println( F("six"));
      break;

    case 0xFF42BD:
      myCom = SEVEN;
      Serial.println( F("seven"));
      break;

    case 0xFF4AB5:
      myCom = EIGHT;
      Serial.println( F("eight"));
      break;

    case 0xFF52AD:
      myCom = NINE;
      Serial.println( F("nine"));
      break;

    case 0xFFA25D:
      myCom = POWER;
      Serial.println( F("power"));
      break;

    case 0xFF629D:
      myCom = VOL_UP;
      Serial.println( F("v+"));
      break;

    case 0xFFE21D:
      myCom = FUN;
      Serial.println( F("fun"));
      break;

    case 0xFF22DD:
      myCom = REWIND;
      Serial.println( F("rewind"));
      break;

    case 0xFF02FD:
      myCom = PLAY;
      Serial.println( F("play"));
      break;

    case 0xFFC23D:
      myCom = FF;
      Serial.println( F("ff"));
      break;

    case 0xFFE01F:
      myCom = DOWN;
      Serial.println( F("down"));
      break;

    case 0xFFA857:
      myCom = VOL_DOWN;
      Serial.println( F("v-"));
      break;

    case 0xFF906F:
      myCom = UP;
      Serial.println( F("up"));
      break;

    case 0xFF9867:
      myCom = EQUAL;
      Serial.println( F("equal"));
      break;

    case 0xFFB04F:
      myCom = ST;
      Serial.println( F("st"));
      break;

    default:
      myCom = UNKNOWN_CODE;
      Serial.print( F("unknown code "));
      Serial.println(cmd.value, HEX);
      break;
  }

  if (myCom == UP) {
    if (mode == BLUE) {
      if (bVal < 255) {
        bVal += 15;
      }
    }
    else if (mode == RED) {
      if (rVal < 255) {
        rVal += 15;
      }
    }
    else if (mode == GREEN) {
      if (gVal < 255) {
        gVal += 15;
      }
    }
  }
  
  if (myCom == DOWN) {
    if (mode == RED) {
      if (rVal > 0) {
        rVal -= 15;
      }
    }
    if (mode == BLUE) {
      if (bVal > 0) {
        bVal -= 15;
      }
    }
    if (mode == GREEN) {
      if (gVal > 0) {
        gVal -= 15;
      }
    }
  }
  
  if (myCom == POWER) {
    rVal = 255;
    gVal = 255;
    bVal = 255;
  }
  if (myCom == FUN) {
    rVal = 0;
    gVal = 0;
    bVal = 0;
  }

  Serial.println(rVal);
  Serial.println(gVal);
  Serial.println(bVal);
  analogWrite(rPin, rVal);
  analogWrite(gPin, gVal);
  analogWrite(bPin, bVal);

  delay(500);
  IR.resume();
}

I see, but I don't believe that memory is an issue as when I upload my code it says that I use 33% of storage memory and 26% of dynamic memory.

Correct me if I'm wrong about this.

Edit: I also don't see the possibility of this being a hardware issue as all of these components work on their own and I have checked the wiring multiple times. The circuit is very simple and uses no other components except for the RGB led and the IR receiver.

that 33% is static memory. That is the memory the compiler knows about. This is primarily all the strings you have in your code like "up", "down", etc. It has nothing to do with the amount of dynamic memory the code uses which the String class does behind the scenes using malloc().

On a small memory device like an Uno, there is no garbage collection and memory can get fragmented and eventually fail which will crash your program.

What about the 26% dynamic memory?

My mistake. The 33% is how much space the code consumes. the 26% is the global variables known to the compiler.

Why is it such a problem if it is only a quarter used?
Or is this at a certain time?

I see, I will try using enums instead and edit this post if it works.

Kind of related question, but why is it only happening with blue?

that is exactly what my code does in post #4

I used the code you used and the same problem still occurred. Could local memory take up that much space.

For reference this is my memory:
[info] Sketch uses 9410 bytes (29%) of program storage space. Maximum is 32256 bytes.
[info] Global variables use 424 bytes (20%) of dynamic memory, leaving 1624 bytes for local variables. Maximum is 2048 bytes.

Yeah, I can't seem to find anything about it, at least in the 2.2.3 doc

Do you suggest I try another pin?

I changed the blue pin to pin 6 and it worked. Thank you so much for helping me. I was confused with this for the past 2 days. Thanks!

You are using an Uno (Atmega328) and Pin 3 which prevents pins 3 and 11 from using analogWrite()

What happens if you add 15 to 255?
Or subtract 15 from 0?

Yes, I am aware and I have already solved this issue

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.