# Scrolling Algorithm for LEDs that Follow Someone

I'm using an ultrasonic sensor aimed down a hallway to determine where a person is, and light up Neopixels LEDs, lining the walls, at that persons location. Since the LEDs are spaced 3cm apart, adjacent LEDs would 'toggle' if a person was standing still. It's too sensitive. I wanted to reduce the sensitivity, so to speak, so that a person would have to move a significant amount before the LEDs started following them. I'm trying to do this by only changing the LED strip once a person has moved 6cm, the distance of 2 LEDs, by lighting the next LED for a short time, them lighting the LED 6cm away, and so on. This might not be the most efficient or sophisticated way to go about doing it, but I'm trying to get this to work before I start making improvements.

Problem:
The code does what I like, lighting up sequential LEDs as the person moves, however when a person changes direction it lights up the intermediary (red) LED on the wrong side of the new LED, and the new LED acts as if the direction hadn't changed until the next iteration of the loop. For example, if you were to give LEDs numbers they might light up in this order: (18, 17, 16, 15, 12, 13,). Here, the direction switched at 12. It should have read (18, 17, 16, 15, 16, 17).

Also, after maybe 30 seconds the code ignores the intermediary (red) LED and just starts scrolling every other. Does anyone know what I might have done wrong or if there was a better way to go about how I'm approaching this? I feel there must be a better approach to go about doing this. (Even after getting this code to function properly, it won't work well if someone is walking at a good speed.

``````void loop() {
ping(); //Send ping and receive distance in cm called "cm"

//Convert the distance, "cm," to a corresponding LED
if (var==0){ //If in the process 'scrolling' through lights, don't enter
newLED=(cm-offset)/3;  //"offset" is the distance between the sensor and the first LED
smoothTimer=millis();  //Resets timer that controls the amount of time LEDs are on for
}

//Find the difference between the old and new locations
pixelDif=oldLED-newLED;

//The following will turn on the lights based on the sensor data
//Turn light between newLED and oldLED on
if (millis()-smoothTimer < 100 && abs(pixelDif) > 1){
stripClear();
strip.setPixelColor(oldLED+(pixelDif/2), strip.Color(60, 0, 0)); //Set LED red
strip.show();
//Used to understand how code is working
if(var==0){
Serial.print("Red light is: ");
Serial.println(oldLED+(pixelDif/2));
Serial.print("oldLED was: ");
Serial.println(oldLED);
}
var=1; //Prevents newLED from being recalculated until the "scrolling" motion is stopped
}

//Turn on the next LED and wait 30ms until worrying about the next position and LED
if(millis()-smoothTimer > 100 && abs(pixelDif) > 1){
stripClear();
strip.setPixelColor(oldLED, strip.Color(60,60,60));
strip.show();
//Reset oldLED after 30 ms
if(millis()-smoothTimer >130){
smoothTimer=millis();
oldLED=newLED;
//Used to understand how code is working
if(var==1){
Serial.print("oldLED is now: ");
Serial.println(oldLED);
var=0;
}
}
}
}
``````

And some readout from the command window.

Red light is: 20
oldLED was: 19
oldLED is now: 17

Red light is: 18
oldLED was: 17
oldLED is now: 15

Red light is: 16
oldLED was: 15
oldLED is now: 13

Red light is: 12
oldLED was: 13
oldLED is now: 15

Post all of your code.

Also, after maybe 30 seconds

That's often a sign that you've used an int variable to store millis in rather than unsigned long.