1

I am trying to use a rotary encoder to cycle through the brightest versions of R, G & B. And it works! Red goes to blue just fine. Then G happens. For some reason, the int for green goes completely haywire. And it does this the same way on two Arduinos.

So my question is this: why would two, identically assigned variables treat ++ completely differently? After hours (and hours and hours) of looking, I'm completely out of possible answers.

#include <Encoder.h>
#include <FastLED.h>

/* Encoder */
Encoder myEnc(2, 3);
const int swPin = 4 ;
long oldPosition  = -999;

/* LEDs */
#define LED_PIN     7
#define NUM_LEDS    150
CRGB leds[NUM_LEDS];

/* RGB Loop */
volatile int cycle = 1;
volatile int brightness = 0;
volatile int r = 127;
volatile int g = 0;
volatile int b = 0;

void setup() {
  pinMode(swPin, INPUT);
  Serial.begin(9600);
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
}

void loop() {
  // Read from rotary encoder.
  long newPosition = myEnc.read();

  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition); /* Sends elsewhere */
  }

  /* Will eventually move this inside the above if 
   * statement so the color shift is controlled by
   * a rotary encoder.  Down here for debugging. 
   */
  delay(50);
  updateColor( );
}

void updateColor(  ) {

  Serial.println(" "); // For readability. 

  if ( brightness >= 127 ) {
    brightness = 1;
    if ( cycle > 6 ) {
      cycle = 1;
    } else {
      cycle++;
    }
  } else {
    brightness++;
  }

  if ( cycle == 1) {
    b++;
  }
  else if ( cycle == 2) { /* rb --> b */
    r--;
  }
  else if ( cycle == 3) { /* b --> bg */
    g++;
  }
  else if ( cycle == 4) { /* bg --> g */
    b--;
  }
  else if ( cycle == 5) { /* g --> rg */
    r++;
  }
  else if ( cycle == 6) { /* g --> rg */
    g--;
  }
  else {
    Serial.print("==================== ");
  }

  /* Debugging */
  Serial.print("brightness:");
  Serial.print(brightness);
  Serial.print("   cycle:");
  Serial.print(cycle);
  Serial.print("   r:");
  Serial.print(r);
  Serial.print(" g:");
  Serial.print(g); // goes completely bonkers
  Serial.print(" b:");
  Serial.print(b);
  Serial.println(" ");


  for (int i = 0; i <= NUM_LEDS; i++) {
    leds[i].setRGB( r, g, b );
  }

  FastLED.show();

}

spits out the following in the serial monitor :

brightness:1   cycle:1   r:127 g:0 b:1 

brightness:2   cycle:1   r:127 g:127 b:2 

brightness:3   cycle:1   r:127 g:32639 b:3 

brightness:4   cycle:1   r:127 g:32639 b:4 

brightness:5   cycle:1   r:127 g:32639 b:5 

brightness:6   cycle:1   r:127 g:32639 b:6 

Red and blue are doing exactly what I want. Green is off on Mars.

Any/all help would be enormously appreciated. Thanks in advance.

  • 127 = 0x7F, 32639 = 0x7F7F. – Jot May 14 at 9:05
  • I can't yet comment so therefore here. Could you try casting the rgb printouts to uint8_t? It could be that it goes out of bounds or something? I don't see anything wrong with the code so maybe it could be that some pointer is changing the value of g? – Tarick Welling May 14 at 9:19
  • I do not see a relation between the encoder and the r,g,b values. Or between the encoder and your rgb problem. BTW: rgb values are byte, not int – DataFiddler May 14 at 9:54
  • laffan, we don't see the problem. It could be a compiler or optimization bug (not likely, but it is possible) or a bug in a library that overwrites memory. You have to try a number of things. Start with an example, and slowly change that in the direction of your sketch. The setRGB is a inline function that has uint8_t as parameters. I think there is no need to make the variables volatile. – Jot May 14 at 14:33
  • Thank you all! @Jot I think you're on to something. I'm not sure what you're on to, but that at least explains the number. Looks like I need to learn some more about hexidecimals. And good to know re: that variable volatility (I was grasping at straws.) Tarik Welling - I'm afraid this hobbiest hasn't gotten to pointers yet, but I'll take a look. DataFiddler - The new/old position thing is the rotary encoder part (see comments) which works, incredibly. Thanks for the byte tip. – laffan May 14 at 16:26
3

Here:

CRGB leds[NUM_LEDS];

you are defining an array of NUM_LEDS objects of the CRGB type. Valid indices for this array range from 0 to NUM_LEDS-1.

Here:

for (int i = 0; i <= NUM_LEDS; i++) {
  leds[i].setRGB( r, g, b );
}

you are accessing the array elements at indices 0 to NUM_LEDS. The last iteration is an out-of-bounds access, which is causing memory corruption. You should instead write

for (int i = 0; i < NUM_LEDS; i++) ...
  • Thank you so much @edgar-bonet - I don't think I ever would have figured that out. – laffan May 15 at 20:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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