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– Jot2019年05月14日 09:05:33 +00:00Commented May 14, 2019 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– Tarick Welling2019年05月14日 09:19:44 +00:00Commented May 14, 2019 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 intDataFiddler– DataFiddler2019年05月14日 09:54:18 +00:00Commented May 14, 2019 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– Jot2019年05月14日 14:33:25 +00:00Commented May 14, 2019 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– laffan2019年05月14日 16:26:53 +00:00Commented May 14, 2019 at 16:26
1 Answer 1
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– laffan2019年05月15日 20:13:47 +00:00Commented May 15, 2019 at 20:13
Explore related questions
See similar questions with these tags.