Crash when incrementing integer

Hi All,

I have been working on the below program for some time, and I have based it off the topic I found here:

Here is my code:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>

// LCD Driver
// A4 (SDA), A5 (SCL)
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x20(Cooperate with 3 short circuit caps) for a 16 chars and 2 line display

// Motion Sensor
// D3 (PWM)
#define motionPin 3
#define ledPin 2

// RGB Driver
// D4, D9 (PWM), D10 (PWM), D11 (PWM)
#define irPin 4
#define bluePin 9
#define redPin 10
#define greenPin 11
IRrecv irrecv(irPin); // initialise IRRecv library

// Digital Button
// D13
#define buttonPin 13


//Remote Signals
#define ON                0XFF827D
#define OFF               0XFF02FD
#define BRIGHTNESS_UP     0xFF3AC5
#define BRIGHTNESS_DOWN   0xFFBA45
#define FLASH             0xFFD02F
#define FADE7             0xFFE01F
#define FADE3             0xFF609F
#define JUMP7             0xFFA05F
#define JUMP3             0xFF20DF
#define RED               0xFF1AE5
#define GREEN             0XFF9A65
#define BLUE              0xFFA25D
#define WHITE             0xFF22DD
#define PINK              0XFF12ED

#define ORANGE            0xFFB04F
#define YELLOW_DARK       0xFFA857
#define YELLOW_MEDIUM     0xFF9867
#define YELLOW_LIGHT      0xFF8877
#define GREEN_LIGHT       0XFF30CF
#define GREEN_BLUE1       0XFF28D7
#define GREEN_BLUE2       0XFF18E7
#define GREEN_BLUE3       0XFF08F7
#define BLUE_RED          0XFF708F
#define PURPLE_DARK       0XFF6897
#define PURPLE_LIGHT      0XFF58A7

#define INCREMENT 10

//maximum duty cycle to be used on each led for color balancing.
//if "white" (R=255, G=255, B=255) doesn't look white, reduce the red, green, or blue max value.
const int max_red = 255;
const int max_green = 255;
const int max_blue = 255;

int MotionStatus = 0;    // stores whether motion detection is on or off
decode_results results;  // stores data received over IR

unsigned long rgb = 0;
int r, g, b;

void setup() {
  // Setup Pins
  pinMode(bluePin, OUTPUT);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(motionPin, INPUT);

  lcd.init();          // Initialise LCD I2C connection
  lcd.backlight();
  irrecv.enableIRIn(); // Start the IR receiver
  Serial.begin(9600);  // Start serial
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX); //Print raw data

    if ( results.value != 0xFFFFFFFF) {

      switch (results.value) {
        case BRIGHTNESS_UP :
          VaryBrightness (r, INCREMENT);
          VaryBrightness (g, INCREMENT);
          VaryBrightness (b, INCREMENT);
          break;

        case BRIGHTNESS_DOWN :
          VaryBrightness (r, -INCREMENT);
          VaryBrightness (g, -INCREMENT);
          VaryBrightness (b, -INCREMENT);
          break;

        case OFF :
          r = g = b = 0;
          break;

        case ON :
          break;

          // colours are in same hex used in HTML, just add 0x00
        case RED           : RGB(0x00FF0000); break;
        case GREEN         : RGB(0x0000FF00); break;
        case BLUE          : RGB(0x000000FF); break;
        case WHITE         : RGB(0x00FFFFFF); break;
        case ORANGE        : RGB(0x00FF7F00); break;
        case YELLOW_DARK   : RGB(0x00FFAA00); break;
        case YELLOW_MEDIUM : RGB(0x00FFD400); break;
        case YELLOW_LIGHT  : RGB(0x00FFFF00); break;
        case GREEN_LIGHT   : RGB(0x0000FFAA); break;
        case GREEN_BLUE1   : RGB(0x0000FFFF); break;
        case GREEN_BLUE2   : RGB(0x0000AAFF); break;
        case GREEN_BLUE3   : RGB(0x000055FF); break;
        case BLUE_RED      : RGB(0x00000080); break;
        case PURPLE_DARK   : RGB(0x003F0080); break;
        case PURPLE_LIGHT  : RGB(0x007A00BF); break;
        case PINK          : RGB(0x00FF00FF); break;
      }

      Serial.println(results.value, HEX);
      Serial.println(r, DEC);
      Serial.println(g, DEC);
      Serial.println(b, DEC);
      setColor (r, g, b);

    }
    irrecv.resume(); // Receive the next value

  }
}

void VaryBrightness (int &color, int increment) {
  // Adds 10 to RGB index unless it's > 255
  Serial.println("Inc Value:");
  Serial.println(increment);
  if (increment > 0) {
    if (color + increment <= 255) {
      color += 10;
    }
    else {
      color = 255;
    }
  }

  // Removes 10 from RGB index unless it's < 0
  else if (increment < 0) {
    if (color + increment >= 0) {
      color += increment;
    }
    else {
      color = 0;
    }
  }
}

void RGB(unsigned long value) {
  // Convert Hex to RGB
  r = value >> 16;
  g = (value >> 8) & 0xFF;
  b = value & 0xFF;
}

void setColor(int red, int green, int blue)
{
  //scale the values with map() so that the R, G, and B brightnesses are balanced.
  analogWrite(redPin, map(red, 0, 255, 0, max_red));
  analogWrite(greenPin, map(green, 0, 255, 0, max_green));
  analogWrite(bluePin, map(blue, 0, 255, 0, max_blue));
  lcd.home();
  lcd.print("                ");
  lcd.home();
  lcd.print("R" + String(red) + "  G" + String(green) + "  B" + String(blue));

}

The issue I am having, and I have scratched my head over this for hours now, is that in the VaryBrightness function, when incrementing the brightness UP, the whole arduino locks up.

It however works PERFECTLY when it’s going down. I see no logical reason for this to be happening - I have tried reversing the reference/dereferencing methods to no avail, thinking it was reference related.

I’m uploading this to an Arduino Uno with SDK 1.5.6-r2. I’m hoping someone can shed some light on what I am missing here which is causing this to fail!

Thanks in advance :slight_smile:

Not your problem but

if (color + increment <= 255) {
color += 10;

presumably should be “color += increment”.

How do you know it fails inside that function? Do you not see the “Inc Value:” being printed?

If you do start placing debug prints in the function to narrow the problem down to a single line.

EDIT:

Pretty sure this

VaryBrightness (r, INCREMENT);
...
color += increment;

should be

VaryBrightness (&r, INCREMENT);
...
*color += increment;

You are passing an int but receiving a pointer to an int, then modifying that pointer in the func and that’s all, in fact I can’t see how it works at all and how it doesn’t generate an error.

Hmmm, just tried that and I got an error.


Rob

OK, I got a bit confused myself there, had a & and should have been a *, here is a working snippet that you should be able to adapt.

int r, g, b;

void setup() {
 Serial.begin(115200);
}

void loop() {
          VaryBrightness (&r, 10);
          Serial.println(r,DEC);
          delay(500);
 }

void VaryBrightness (int *color, int increment) {
    *color += increment;
}

Rob

Wouldn't a reference rather than a pointer be simpler and more intuitive?

Lose the String class entirely, its likely the culprit - space-leak in printing the debugging...

References are better than pointers for this sort of thing - less chance of error.

Graynomad: presumably should be "color += increment".

Quite right you are, that was me attempting to debug the code.

Graynomad: VaryBrightness (r, INCREMENT); ... color += increment;

should be

VaryBrightness (&r, INCREMENT);
...
*color += increment;

You are passing an int but receiving a pointer to an int, then modifying that pointer in the func and that's all, in fact I can't see how it works at all and how it doesn't generate an error.

I have actually tried it both ways and both ways result in the same stupidity with it not working.

The interesting thing is that if I run the program with everything as is, but the color += increment; line commented out in the increasing brightness if statement, it runs fine. It is literally only here there that it crashes.

If you were to run through my code, what happens is that I run the arduino, vary the brightness down and I get serial output on

Serial.println("Inc Value:"); Serial.println(increment);

But then when I increase it, the serial monitor shows "Inc Val " then nothing.

Bizarre.

I'm not sure what you're talking about MarkT?

String class - your code uses the String class.

Eliminate it and see if it solves the problem.

lcd.print("R" + String(red) + "  G" + String(green) + "  B" + String(blue));

If you mean that - commented it out - still nothing.

Serial.println("Inc Value:"); Serial.println(increment);

But then when I increase it, the serial monitor shows "Inc Val " then nothing.

Bizarre.

Not bizarre at all if "increment" is a small value because non-ASCII characters do not print with the serial monitor, try

Serial.println(increment, DEC);


Rob

Not bizarre at all if "increment" is a small value because non-ASCII characters do not print with the serial monitor, try

Serial.println(increment, DEC);

It doesn't matter how small increment is. It's an int, so it is converted to a string by the print() method. The string will consist entirely of printable characters.

Doh, yes that's right, I was mixing .print() with .write()


Rob