PROBLEM making WS2812B work from END to START

Hi, I am new to arduino and I am building a sequence so my LED's turn on when walking up the stairs and they sweep down when coming back down. I am having a problem of trying to get the LED's to sweep back down. I cannot find a solution however I have got the code to sweep up the stairs to work. I am currently testing us 8LEDS because the power supply is on the way and I am not adding the motion sensor into the code yet because I am trying to nail the code to work before adding motion sensors. My problem is to make the LED strip perform the code from the end to start so from pixel 7-0 as it is currently working from 0-7.

#include <Adafruit_NeoPixel.h>
 
#define PIN      6
#define N_LEDS 8

 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRB + NEO_KHZ800);
 
void setup() {
  strip.begin();
  chase(strip.Color(255, 255, 255)); // this sweeps the LED up
  chase(strip.Color(255, 255, 255)); // 
  delay(50);
  chase(strip.Color(0,0,0)); // this is the end of the first bit sweeping up and it is the end of the working bit to sweep up the stairs
  
  
  
  
 
}

void loop() {
   
}
 
static void chase(uint32_t c) {
  for(uint16_t i=0; i<strip.numPixels()+4; i++) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.show();
      delay(75);
      
      
      
      
     

     
      
      
}

}

Following the tradition of giving you a "karma point" for reading the instructions and/ or otherwise being sensible enough to correctly post code.

The "down" code will of course be similar, but you have to initialise it accordingly if you have already executed the first operation; you would have to turn the LEDs off again.

Try:

 for(uint16_t i = strip.numPixels()+3; i >= 0; i--) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.show();
      delay(75);

Are you enjoying the slight "sparkle" effect you have created as each LED turns on? Change the delay to 150 to see it better. :grinning:

@eesaam0nx

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Now I have got the LED strip to run the code backwards but I cannot get it so the strip activates with the motion sensor. I have tried and this is what I have come up with. Any help will be appreciated.

// Simple NeoPixel test.  Lights just a few pixels at a time so a
// 1m strip can safely be powered from Arduino 5V pin.  Arduino
// may nonetheless hiccup when LEDs are first connected and not
// accept code.  So upload code first, unplug USB, connect pixels
// to GND FIRST, then +5V and digital pin 6, then re-plug USB.
// A working strip will show a few pixels moving down the line,
// cycling between red, green and blue.  If you get no response,
// might be connected to wrong end of strip (the end wires, if
// any, are no indication -- look instead for the data direction
// arrows printed on the strip).

#include <Adafruit_NeoPixel.h>
 
int motionPin = 3;
int motionPin2 = 5;
int senseMotion = 0;
int senseMotion2 = 0;

 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(217, 6, NEO_GRB + NEO_KHZ800);
 
void setup() {
  pinMode(motionPin, INPUT);
  pinMode(motionPin2, INPUT);
  

  
  senseMotion = digitalRead(motionPin);
  senseMotion2 = digitalRead(motionPin2);
  strip.begin();
  strip.show();

    if (senseMotion == HIGH || senseMotion2 == HIGH) {
  
      if (senseMotion2 == HIGH) { 
      
      chase(strip.Color(255, 255, 255)); 
      chase(strip.Color(255, 255, 255)); 
      delay(25);
      chase(strip.Color(0,0,0));
    
                                      }

    if (senseMotion == HIGH) {  
      
      chase2(strip.Color(255, 255, 255)); 
      chase2(strip.Color(255, 255, 255)); 
      delay(25);
      chase(strip.Color(0,0,0));                                      
                                 }

    else {
      digitalWrite (motionPin, LOW);
      digitalWrite (motionPin2, LOW);
      chase(strip.Color(0,0,0));
      strip.show();                            
    }
  
  
    }
}

void loop() {
   
}
 
void chase(uint32_t c) {
  for(uint16_t i=0; i<strip.numPixels()+4; i++) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.show();
      delay(5);
                              }    
                        }

void chase2(uint32_t c) {
  for(uint16_t i=206; i<strip.numPixels()+4; i--) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.show();
      delay(5);
                                    }
                              }
void loop() {
   
}

Have you understood the purposes of setup() and loop() in an Arduino sketch?

From what i understand is that the loop runs continuously. I am not wanting this. I am requiring the lights to turn on once when hitting the motion sensor and following the sequence and turning off until a motion sensor is touched again.

I am not wanting this.

Incorrect. The setup() function runs once and only once, when the Arduino is powered up or reset is pressed. You want to continuously check the sensors.

So which code would I be putting into the loop?

Most of what is currently in setup() should be in loop() I suspect. The pinMode(), strip.begin() and strip.show() should remain in setup() I think.

      digitalWrite (motionPin, LOW);
      digitalWrite (motionPin2, LOW);

Why is your code writing to these pins? They are supposed to be inputs, not outputs.

I tried to adjust the code from a different script and put this into mine. Is it possible you can re arrange the full code to what it should look like and post it because I am honestly lost to what is going on now

I tried to adjust the code from a different script and put this into mine

Don't do that, you will only confuse yourself. Adjust the code you posted above, as I suggested.

It is possible that I can rearrange your code, I have been programming for 40 years. But I want to teach you to fish, not give you a fish so you can eat today.

(Apologies if that sounded bombastic!)

Hi, I have now got everything working with the motion sensors. The final problem I am having is that on the way down the LED strip turns on as it should but instead of turning off from the 203rd pixel, it turns off from the 1st which is not how I want it. On the way up, it turns on from the 1st and goes to the top and then turns off from the first so it follows you on the way up. On the way down, it turns on from the 203rd goes to the bottom and then turns off from the first so it comes in the opposite direction to you which ruins the whole setup. Can you please tell me how i would fix this and also how I could add a small shooting star at the end just for a cool effect :slight_smile:

#include <Adafruit_NeoPixel.h>
 
int motionPin = 3;
int motionPin2 = 9;
int senseMotion = 0;
int senseMotion2 = 0;

 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(203, 6, NEO_GRB + NEO_KHZ800);
 
void setup() {
  pinMode(motionPin, INPUT);
  pinMode(motionPin2, INPUT);
  strip.begin();
  strip.show();

}

void loop() {

  senseMotion = digitalRead(motionPin);
  senseMotion2 = digitalRead(motionPin2);
  
    if (senseMotion == HIGH || senseMotion2 == HIGH) {
  
      if (senseMotion == HIGH) { 
      chase(strip.Color(0, 0, 255)); 
      chase(strip.Color(0, 0, 255)); 
      delay(25);
      chase(strip.Color(0,0,0));
    
                                      }

    if (senseMotion2 == HIGH) {  
      chase2(strip.Color(0, 0, 255)); 
      chase2(strip.Color(0, 0, 255)); 
      delay(25);
      chase(strip.Color(0,0,0));                                      
                                 }

    else {
      digitalWrite (motionPin,LOW);
      digitalWrite (motionPin2, LOW);
      chase(strip.Color(0,0,0));
      strip.show();                            
    }
  
  
    }
}
 
void chase(uint32_t c) {
  for(uint16_t i=0; i<strip.numPixels()+4; i++) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.show();
      delay(5);
                              }    
                        }

void chase2(uint32_t c) {
  for(uint16_t i=203; i<strip.numPixels()+4; i--) {
      strip.setPixelColor(i , c); // Draw new pixel
      strip.show();
      delay(5);
                                    }
                              }

This may help, I'm not sure, but it's certainly more correct:

void chase2(uint32_t c) {
  for(int16_t i=strip.numPixels()-1; i>=0; i--) {

Notice I changed uint16_t to int16_t so that "i" can reach -1 and stop the for-loop.

how I could add a small shooting star

You should describe in more detail what you mean by that.

on the way down the LED strip turns on as it should but instead of turning off from the 203rd pixel, it turns off from the 1st

I can see the error that causes that. It's nothing complicated, you should be able to find it easilly.

I presume a "small shooting star" is a single white pixel rapidly chasing through the chain.

If the chain is black at that point, it is relatively simple, you step the full white through the array and blank the previous one. If it is through a different illuminated pattern you need to read the previous value of each pixel before lighting it fully and save it so it can be restored at the next step.


I foresee a little matter here. Chasing through 8 NeoPixels is straightforward, but on a stair, you will presumably be using an actual strip across each tread. This leads to a decision. Do you wish to program the whole group for each stair as one unit, or do you propose to use sub-animation such as the light "expanding" from the centre to the side of each tread and "closing" afterwards?

In which latter case, the "shooting star" could for example, travel diagonally with a different trajectory each time. :grinning:

I have added this code and it seems to be doing the exact same thing as before. Basically, after it goes from the 203rd pixel to the 1st it should then turn off from the 203rd to the 1st instead of turning off from the 1st to the 203rd. On the way down the stairs if it turns off from the 1st pixel to the last one then the leds are travelling in the opposite direction to what you are walking when we need them so that they follow you down the stairs.

For the shooting star bit, at the end of each motion I want it just to have a pixel going through the strip with a small trail behind it, I will attach a video for more understanding.

I have added this code...

Added what? EDIT: oh, you mean you made the change I suggested in reply #12. It is better like that, but it will not fix the problem. Did you see my reply #13?

Sorry, I should have mentioned......i do not intend to have LEDs on each stair tread. I am using a strip of LEDs that go on the side of the stairs as one whole piece.

Just want to also say that I appreciate all the help i am getting from you guys.....its greatly appreciated and good to know to you can turn to the experts for help when needed :wink:

No problem.

Did you find that error yet? It is a very small error, a simple mistake. You will curse yourself when you find it. That is normal in the process of de-bugging code!

I have not found it yet maybe hint me in the right direction?