Go Down

Topic: PROBLEM making WS2812B work from END to START  (Read 486 times) previous topic - next topic

eesaam0nx


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.



Code: [Select]

#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);
     
     
     
     
     

     
     
     
}

}



Paul__B

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:
Code: [Select]
 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.  :smiley-lol:

ballscrewbob


@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.
It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google (who would have thunk it ! ) or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

eesaam0nx

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. 

Code: [Select]
// 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);
                                    }
                              }   

PaulRB

#4
Nov 20, 2020, 07:54 am Last Edit: Nov 20, 2020, 07:55 am by PaulRB
Code: [Select]
void loop() {
   
}

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

eesaam0nx

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.

PaulRB

Quote
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.

eesaam0nx

So which code would I be putting into the loop?

PaulRB

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.

Code: [Select]
      digitalWrite (motionPin, LOW);
      digitalWrite (motionPin2, LOW);

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

eesaam0nx

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

PaulRB

#10
Nov 20, 2020, 08:07 pm Last Edit: Nov 20, 2020, 08:31 pm by PaulRB
Quote
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!)

eesaam0nx

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  :)



Code: [Select]
#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);
                                    }
                              }   



PaulRB

#12
Nov 22, 2020, 10:24 am Last Edit: Nov 22, 2020, 10:41 am by PaulRB
This may help, I'm not sure, but it's certainly more correct:
Code: [Select]
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.

Quote
how I could add a small shooting star
You should describe in more detail what you mean by that.

PaulRB

Quote
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.

Paul__B

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.  :smiley-lol:

Go Up