I am currently working on making my own RBG LED strip controller, similar to those you would get with a cheap strip you may buy off Amazon. The code has been working fine except for this rainbow setting - which I have isolated into its own code for troubleshooting. Whenever the outer loop switches to a different if statement (ie when "i" changes from 256 to 257) the pixels all reset and flutter off for a moment (the duration of which corresponds to the delay value from what I can tell). I'm a bit confused because from my understanding, even if the data pin is disconnected from the strip, the strip will hold its last color, which would work just fine for this application, but does not happen. I've tried moving around the delay as well as when the pixels are set but I get the same result each time. Any suggestions?
P.S. In case you are wondering, there are currently 6 neopixels connected to the arduino via a 1k resistor to pin 10, 5v, and ground.
void loop() {
for (int i = 0; i < 768; i++) {
for (int k = 0; k < PIXEL_COUNT; k++) {
if (i <= 256)
{
redVal = 256 - i; // Red from full to off
grnVal = i; // Green from off to full
bluVal = 1; // Blue off
}
else if (i <= 512)
{
L2 = (i - 256); // Normalizes to 0-255
redVal = 1; // Red off
grnVal = 256 - L2; // Green from full to off
bluVal = L2; // Blue from off to full
}
else
{
L3 = (i - 512); // Normalize to 0-255
redVal = L3; // Red from off to full
grnVal = 1; // Green off
bluVal = 256 - L3; // Blue from full to off
}
strip.setPixelColor(k, redVal, grnVal, bluVal, 255);
strip.show();
delay(10);
}
}
}
blh64:
The values you set as redVal, grnVal, and bluVal need to be in the range of 0-255, not 0-256. 256 is the same as zero.
Your 'i<=256' should be simply less than. Same for the 512 comparison.
Not quite as easy as just changing the <= to < you have to avoid the problem where any of the values will be 0 if you don't want the LEDs to go completely off. Without changing a lot of the numbers around in the math, simply skipping over the majority of the code when i is evenly divisible by 256 does away with the blinking.
void loop() {
for (int i = 0; i < 768; i++) {
for (int k = 0; k < PIXEL_COUNT; k++) {
if (i % 256 != 0) { // line added to avoid any LED turning off completely
if (i <= 256)
{
redVal = 256 - i; // Red from full to off
grnVal = i; // Green from off to full
bluVal = 1; // Blue off
}
else if (i <= 512)
{
L2 = (i - 256); // Normalizes to 0-255
redVal = 1; // Red off
grnVal = 256 - L2; // Green from full to off
bluVal = L2; // Blue from off to full
}
else
{
L3 = (i - 512); // Normalize to 0-255
redVal = L3; // Red from off to full
grnVal = 1; // Green off
bluVal = 256 - L3; // Blue from full to off
}
strip.setPixelColor(k, redVal, grnVal, bluVal, 255);
strip.show();
delay(10);
}
}
}
}
Thank you both, good points. The 256 instead of 255 was really just a brain fart on my part, I'm not sure why I did that but I'll fix it asap
david_2018:
Not quite as easy as just changing the <= to < you have to avoid the problem where any of the values will be 0 if you don't want the LEDs to go completely off. Without changing a lot of the numbers around in the math, simply skipping over the majority of the code when i is evenly divisible by 256 does away with the blinking.
I understand your point here, this addition will prohibit i from ever equalling 0, therefore never fully turning off a color. I should say, before I make my comment, that I haven't had a chance to test this out yet to even tell if it works. My question is purely hypothetical in an effort to further understand the solution.
I'm not sure that any of the color values equalling 0 would cause an issue, would it? Should that not simply turn off only that color led withing the neopixel? Furthermore, and what truly makes me wonder, why would that only cause stuttering at the moment of switching from one portion of the if statement to another? At the switching points, theoretically, none if the number values would change. GrnVal would reach 256 at the end of the first if statement as I counts up, then would remain at 256 for the first instance of the else if loop since L2 would then be 0. Unless it's the redVal equalling 0 that is causing the issue... Hmm, I'm interested to see if this is indeed my problem. I'll update this thread tomorrow after I get some time to test out the code with these changes.
UPDATE:
I updated the code (I'll add it to this post later, but for now, please see what David posted below as it essentially shows the change). Unfortunately, this does not seem to be the issue. I'm sure it stabilizes the code, preventing any color value from hitting 0, but the stuttering is still occurring. It's occurring at the same spot. When the if statement changes its level, the LEDs turn completely off for a moment. This one really has me stumped! Nowhere in the code does the strip clear, so I can't think of why they would turn off for a cycle.
david_2018:
void loop() {
for (int i = 0; i < 768; i++) {
for (int k = 0; k < PIXEL_COUNT; k++) {
if (i % 256 != 0) { // line added to avoid any LED turning off completely
if (i <= 256)
{
redVal = 256 - i; // Red from full to off
grnVal = i; // Green from off to full
bluVal = 1; // Blue off
}
else if (i <= 512)
{
L2 = (i - 256); // Normalizes to 0-255
redVal = 1; // Red off
grnVal = 256 - L2; // Green from full to off
bluVal = L2; // Blue from off to full
}
else
{
L3 = (i - 512); // Normalize to 0-255
redVal = L3; // Red from off to full
grnVal = 1; // Green off
bluVal = 256 - L3; // Blue from full to off
That code still has some values trying to be set at 256 which results in 0.
This code fixes that
void loop() {
for (int i = 0; i < 768; i++) {
for (int k = 0; k < PIXEL_COUNT; k++) {
if (i < 256)
{
redVal = 255 - i; // Red from full to off
grnVal = i; // Green from off to full
bluVal = 0; // Blue off
}
else if (i < 512)
{
L2 = (i - 256); // Normalizes to 0-255
redVal = 0; // Red off
grnVal = 255 - L2; // Green from full to off
bluVal = L2; // Blue from off to full
}
else
{
L3 = (i - 512); // Normalize to 0-255
redVal = L3; // Red from off to full
grnVal = 0; // Green off
bluVal = 255 - L3; // Blue from full to off
}
strip.setPixelColor(k, redVal, grnVal, bluVal, 255);
strip.show();
delay(10);
}
}
}
Can you post the your complete code, instead of just the loop section, so we can see how you are setting everything up, and which libraries you are using?
Here is the updated code with setup included. Keep in mind the set-up was copied in from the full code so it has some unused portion in this debugging version.
#include <Adafruit_NeoPixel.h>
#define BUTTON_PIN 4
#define PIXEL_PIN 10
#define PIXEL_COUNT 6
bool oldState = HIGH;
int cycleNum = 0;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
int potPin = 1; // Potentiometer output connected to analog pin 3
int potVal = 0; // Variable to store the input from the potentiometer
int rbVal = 0; // Variable for rainbow setting
int DelayAmount = 0;
int redVal = 0; // Variables to store the values to send to the pins
int grnVal = 0;
int bluVal = 0;
int L1;
int L2;
int L3;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
strip.begin();
strip.setBrightness (255);
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
for (int i = 0; i < 765; i++) {
for (int k = 0; k < PIXEL_COUNT; k++) {
if (i % 256 != 0) {
if (i < 256)
{
redVal = 256 - i; // Red from full to off
grnVal = i + 1; // Green from off to full
bluVal = 1; // Blue off
}
else if (i < 511)
{
L2 = (i - 256); // Normalize to 0-255
redVal = 1; // Red off
grnVal = 256 - L2; // Green from full to off
bluVal = L2 + 1; // Blue from off to full
}
else
{
L3 = (i - 512); // Normalize to 0-255
redVal = L3 + 1; // Red from off to full
grnVal = 1; // Green off
bluVal = 256 - L3; // Blue from full to off
}
strip.setPixelColor(k, redVal, grnVal, bluVal, 255);
strip.show();
delay(10);
}
}
}
}
I posted this now seeing the mistakes. I added the "+1" and some other tidbits to attempt to ensure that the color values never hit zero. I am realizing though, that this is causing an inadvertent extra loop where all values equal zero, or at most 1 (since one will rise above 255). I imagine this is definitely the issue, and also answers my question of why the pixels are turning off without a strip.clear command. I'll update the code again attempt to fix this now that I have blh64's code as an example (couldn't quote this for some reason, the Arduino site has been acting funny all day).
blh64:
That code still has some values trying to be set at 256 which results in 0.
This code fixes that
void loop() {
for (int i = 0; i < 768; i++) {
for (int k = 0; k < PIXEL_COUNT; k++) {
if (i < 256)
{
redVal = 255 - i; // Red from full to off
grnVal = i; // Green from off to full
bluVal = 0; // Blue off
}
else if (i < 512)
{
L2 = (i - 256); // Normalizes to 0-255
redVal = 0; // Red off
grnVal = 255 - L2; // Green from full to off
bluVal = L2; // Blue from off to full
}
else
{
L3 = (i - 512); // Normalize to 0-255
redVal = L3; // Red from off to full
grnVal = 0; // Green off
bluVal = 255 - L3; // Blue from full to off
}
strip.setPixelColor(k, redVal, grnVal, bluVal, 255);
strip.show();
delay(10);
}
}
}
This was indeed the issue. The 256 values were out of range and therefore registering as zeros. This then caused a single loops worth of off pixels which explains why it directly related to the delay. Thanks for all the help!