WS2812b Strips Led moving smoothly based on Sharp distance sensor.

Hi all,

I building a stair project. As i’m new in programming, I read a lot topics in this forum wich help me to archeive this stae. Unfortunatly, I’m stuck in programming. Below a summary of my project;

I have 12 strips LED WS2812B (one per stair) - One strip, include 22 pixels.

Strips are chained in series - External powered. - I used digital PIN 13 for data.

I’m getting distance form Sharp GP2Y0A710K0F with 100-550 distance range. This one is pin to analog A0.

I’m using Adafruit_Neopixel.h Librairy and SharpIR.h ( for the sensor).

In my loop, I’m mapping the reading distance 100 cm to 380 cm to number of stairs 0 - 12.
getting"distance" from the sensor for a average. The average is means to be draw by the function draw.

Then, i’m trying to move smoothly light stair per stair based on the average of distance reading.

the serial.println (dis) = real distance between object and sensor

the serial.println (i) = stairs (0,1,2,3,…11)
the serial.println (j) = Nbr of pixels from 0 to 264 included in stairs numbers.

distance 55
0 stairs
1
2
3
4
.
.
.
21

1 stairs

22
23
24
25
.
.
.
.
44

2 stairs

The value of variable (i) and (j) seems to be correct but I was excpeted to have my PIX moving but
instead…I got nothing…I spent hours and hours along night to find ans answers to my issue but didin’t find something.

As i said, I never did any program…i’m nearly an amator…but I know there is masters here on programming whom may help me.

In advance Thank you so much.

Code Test.txt (1.79 KB)

  int dispix = map(dis,100,380,0,12);

dispix? Does that mean something to you? Means nothing to me.

    Serial.println(i);

Anonymous printing sucks. Printing the index of the loop only shows you that the loop is iterating correctly.

        strip.setPixelColor(pix,255,0,0);

It's the jth pixel that you want to set the color of, not the pixel at the average location, isn't it?

What, EXACTLY, is the relationship between average, stair number, and pixel to light?

Hello, Thank you for your interest to my need of assistance.
dispix it's just a variable...I could call it "mapit"...dispix helps the average to smooth between stairs steps 0 to 11.

The average is given by the variable "pix" so I would like to translate pix position in one strips of pixels (0-22) which represent on step stair.
aybe I'm completly wrong with my code. my point is to light one step stair based on distance read. then if distance changing stair step is changing. I read that the sharp sensor is not really accurate, reason why I'm using a average.

Hope this give you a better pictures.

OP code

#include <Adafruit_NeoPixel.h>
#define PIN 13
#define NUMPIXELS 264

#include <SharpIR.h>

#define ir A0
#define model 100500

const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int newValue = 0;


SharpIR SharpIR(ir, model);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {

  Serial.begin(9600);
   strip.begin();
   for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
   }
}

void loop() {
 
  int dis=SharpIR.distance();  


  Serial.print("distance: ");  
  Serial.println(dis);
  
  int dispix = map(dis,100,380,0,12);
 

 if ((dispix >= 0) && (dispix <12)) {
 newValue = dispix;
 } else {
 newValue = 0;
 }  
// subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = newValue;
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  draw(average);
  strip.show();
}
void draw(int pix) {
    for (int i = 0; i < 12; i++){
    int start = strip.numPixels()/12*i;
    Serial.println(i);
    
        for (int j = start; j < start + 22; j++){
        Serial.println(j);
        strip.setPixelColor(pix,255,0,0);
        
        }   
  strip.show();
  delay(2000);
  }
}

This line of code is incorrect

int start = strip.numPixels() / 12 * i;

since when i = 0 there is a divide by zero.

It looks like you are passing to draw() the number of the stair from 0 - 12 (if you have 12 stairs this should be 0 - 11). Then in draw you have an outer loop from 0 - 11 as if you want to light pixels on all stairs. I think you only want to light the stair corresponding to the number passed in. Maybe something like this:

void draw(int pix) {

  // first pixel on passed stair #
  int start = pix * 22;

  // set color of each pixel on stair
  for (int j = start; j < start + 21; j++) {
    Serial.println(j);
    strip.setPixelColor(j, 255, 0, 0);
    strip.show();
    delay(2000);
  }

}

my point is to light one step stair based on distance read. then if distance changing stair step is changing.

So, average represents which step you are on?

In the draw() function, then, the argument should be called stepNumber, and you need only one for loop to light up the pixels for that step.

void draw(int stepNumber)
{
   int startPixel = stepNumber * strip.numPixels()/12;
   for(int i=0; i<strip.numPixels()/12; i++)
   {
      strip.setPixelColor(startPixel+i, 255, 0, 0);
   }
   strip.show();
}

Notice that there is NO delay() in this code. It is OK to call this function 100 times while the cripple hobbling up the stairs is on one step.

There IS a problem, though. You will fall down those stairs a lot.

Light the next step up or down, depending on the way you are going, NOT the step you are on.

@blue eyes : Thank you for your interest. I modified as adviced and I got my step light sequencly depending on distance. That a huge step for me....But as PaulS mentionned, I have to figure out how to clear step stair behind me (fading) depending on direction walking up or walking down.
Anyway I still have long way to go :slight_smile:

PaulS:
So, average represents which step you are on?

In the draw() function, then, the argument should be called stepNumber, and you need only one for loop to light up the pixels for that step.

void draw(int stepNumber)

{
  int startPixel = stepNumber * strip.numPixels()/12;
  for(int i=0; i<strip.numPixels()/12; i++)
  {
      strip.setPixelColor(startPixel+i, 255, 0, 0);
  }
  strip.show();
}




Notice that there is NO delay() in this code. It is OK to call this function 100 times while the cripple hobbling up the stairs is on one step.

There IS a problem, though. You will fall down those stairs a lot. 

Light the next step up or down, depending on the way you are going, NOT the step you are on.

Yes Average shows the distance I am and so the step to light up.

I made modification as mentionned. Thank you. step stair are light on but I thought that as average value is changing as I’m moving up or down, the lighting stair step will follow me…something like “Billie jean video clip” but on my stair step.

By the way I am Belgian my english isn’t top. Sorry about that.

By the way I am Belgian my english isn't top. Sorry about that.

Your English is way better than my Belgium, and is good enough to understand. Don't worry about it. The value in average is increasing or decreasing as you move towards, or away from the sensor. If the sensor is at the bottom of the stairs, and you are going down, the value in average will decrease as you get closer to the bottom. So, it is relatively simple to anticipate which step to light up. The value will increase as you go up, so it is relatively easy to anticipate which step to light up.

What I'd prefer, though, is that all the LEDs, on all the steps come on, and that they go off behind me as I clear each step. That way, the remaining steps are lit, regardless of whether I am going up or going down. Doesn't matter that it dark behind me. As long as it is light in front of me, I can go up or down the stairs safely.