I am having trouble with a project I am working on. Basically, a single LED chases up and down a digital addressable neopixel strip and then the whole strip sweeps on and stays on. At least that's what i'm trying to achieve.
So far I can only get the single led to chase up and down the strip but the sweep wont happen. I have narrowed it down to the "Chaseback" part of my code that is causing problems as when i take this bit out of the loop the sweep works fine.
Does anybody know why the sweep wont happen when I include "chaseback" in the loop?
Thanks in advance
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define N_LEDS 27
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
void setup() {
strip.begin();
}
void loop() {
chase(strip.Color(255, 0, 0, 0)); // Red
chaseback(strip.Color(255, 0, 0, 0)); // Red
sweep(strip.Color(255, 0, 0, 0));
}
static void chase(uint32_t c) {
for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
strip.setPixelColor(i , c); // Draw new pixel
strip.setPixelColor(i - 2 , 0); // Erase pixel a few steps back
strip.show();
delay(25);
}
}
static void chaseback(uint32_t c) {
for(uint16_t i=N_LEDS-1; i>=0; i--) {
strip.setPixelColor(i , c); // Draw new pixel
strip.setPixelColor(i + 2 , 0); // Erase pixel a few steps back
strip.show();
delay(25);
}
}
static void sweep (uint32_t c) {
//Ascend strip
for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
strip.setPixelColor(i, c);
strip.show();
delay(10);
}
}
static void chaseback(uint32_t c) {
for(uint16_t i=0; i < N_LEDS; i--) {
strip.setPixelColor(N_LEDS - i , c); // Draw new pixel
strip.setPixelColor(N_LEDS - i - 2 , 0); // Erase pixel a few steps back
strip.show();
delay(25);
}
}
Thanks for the reply, unfortunately it still doesn't work. Now the single led chases up the strip but then the wipe happens straight away before the led has chased back down the strip.
Also, I need the wipe to stay on but it is instantly wiping away after it has wiped on. I'm pretty sure this is due to the loop going back to the chase section which clears the LEDs behind it as it chases down the strip.
In short I need a single LED to chase up and back down the strip followed by a colour wipe that stays on until it is switched off. (I will be adding in the switches when the program is working correctly)
All I did was to stop the for-next loop from bugging the way it had to.
Something changed, right? Isn't that a good thing? It usually is for me when I'm debugging.
So you have to debug some more, expect that when writing new code.
Should this
strip.setPixelColor(N_LEDS - i - 2 , 0); // Erase pixel a few steps back
Be this?
strip.setPixelColor(N_LEDS - i + 2 , 0); // Erase pixel a few steps back
Likely not quite since N_LEDS - i + or - 2 goes out of the range of 0 to N_LEDS.
There should be different limits to that for-next loop or an if() inside to never write pixels outside of range.
Personally, I would temporarily add a delay of 50 in that loop. Then print i to the serial monitor so I know EXACTLY what is going on with that variable. Then work from there. I'm no Arduino guru and that sort of thing makes more sense to me when I can see it.
I didn't repost the code because it's already on the original post... and the code that goforsmoke suggested didn't work so i've kept it as it was. I'm a proper amateur, I have probably spent less than 5 hours working with arduinos so PaulS if you don't plan on being constructive then do me a favour and don't bother commenting...
Here is the code with goforsmokes suggestion.
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define N_LEDS 27
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
void setup() {
strip.begin();
}
void loop() {
chase(strip.Color(255, 0, 0, 0)); // Red
chaseback(strip.Color(255, 0, 0, 0)); // Red
indicator(strip.Color(255, 0, 0, 0));
}
static void chase(uint32_t c) {
for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
strip.setPixelColor(i , c); // Draw new pixel
strip.setPixelColor(i - 2 , 0); // Erase pixel a few steps back
strip.show();
delay(25);
}
}
static void chaseback(uint32_t c) {
for(uint16_t i=0; i < N_LEDS; i--) {
strip.setPixelColor(N_LEDS - i , c); // Draw new pixel
strip.setPixelColor(N_LEDS - i - 2 , 0); // Erase pixel a few steps back
strip.show();
delay(25);
}
}
static void indicator (uint32_t c) {
//Ascend strip
for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
strip.setPixelColor(i, c);
strip.show();
delay(10);
}
}
In this code there is still a problem when N_LEDS - i - 2 would be less than 0.
Also it maybe shouldn't be - 2 but more like + 2 since the motion is supposed to be towards 0, steps back would be +.
static void chaseback(uint32_t c)
{
uint16_t i;
uint16_t index; // don't have to have (uses RAM) but makes the code more clear
uint16_t pixSteps;
for( i = 0; i < N_LEDS; i++ )
{
index = N_LEDS - i; // goes from high to low
strip.setPixelColor( index, c); // Draw new pixel
pixSteps = N_LEDS - i;
if ( pixSteps >= 2 )
{
pixSteps = 2;
strip.setPixelColor(N_LEDS - i + pixSteps , 0); // Erase pixel 2 steps back
}
strip.show();
delay(25);
}
strip.setPixelColor( 1 , 0); // Erase the next to last
strip.show();
delay( 25 );
strip.setPixelColor( 0, 0); // Erase the last
strip.show();
delay( 25 );
}
This should be closer if not 100% right.
NORMALLY IF IT WAS MY PROJECT I'd be testing and debugging which I leave to the OP who has the rig.
I could make something parallel to this (print numbers instead of light leds) and debug that but I don't want to spend the extra hour.
Thank you for all your help goforsmoke. I have updated the code but there is still some problems. The LED strip does exactly what I want for the first loop. Single LED chases up then back down the strip and then the whole strip wipes on. However, after the strip has wiped on, the program then goes back to the single LED which chases back down the strip and then the whole strip wipes on again. This repeats over and over.
I need the strip to stay on after it has wiped on instead of the program continuing to loop everything.
Any suggestions?
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define N_LEDS 27
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
void setup() {
strip.begin();
}
void loop() {
chase(strip.Color(255, 0, 0, 0)); // Red
chaseback(strip.Color(255, 0, 0, 0)); // Red
indicator(strip.Color(255, 0, 0, 0));
}
static void chase(uint32_t c) {
for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
strip.setPixelColor(i , c); // Draw new pixel
strip.setPixelColor(i - 2 , 0); // Erase pixel a few steps back
strip.show();
delay(25);
}
}
static void chaseback(uint32_t c)
{
uint16_t i;
uint16_t index; // don't have to have (uses RAM) but makes the code more clear
uint16_t pixSteps;
for( i = 0; i < N_LEDS; i++ )
{
index = N_LEDS - i; // goes from high to low
strip.setPixelColor( index, c); // Draw new pixel
pixSteps = N_LEDS - i;
if ( pixSteps >= 2 )
{
pixSteps = 2;
strip.setPixelColor(N_LEDS - i + pixSteps , 0); // Erase pixel 2 steps back
}
strip.show();
delay(25);
}
strip.setPixelColor( 1 , 0); // Erase the next to last
strip.show();
delay( 25 );
strip.setPixelColor( 0, 0); // Erase the last
strip.show();
delay( 25 );
}
static void indicator (uint32_t c) {
//Ascend strip
for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
strip.setPixelColor(i, c);
strip.show();
delay(10);
}
}
I can't put it in setup as i'm having the same strip do other things such as a car indicator function. Once the indicator is off I need the strip to revert back to all the LED's being on