Seeking advice on running 7 x WS2812b strips of 72 LEDs each over a distance

Greetings fellow Arduino-heads.

I'm new to Arduino but have been coding for decades. My major shortcoming is knowing near nothing about electronics and circuitry. I'm really enjoying the learning process but, at present, my aspirations seem to outpace my ability. :confused:

I'm prototyping a system that will illuminate each step of the staircase I'm building in our tiny house project. I want it to be controlled by two simple buttons that can be mashed as people ascend/descend the stairs; hence, one button would live at the top of the staircase and one at the bottom. I've already coded and tested that and it's working great .... AT CLOSE proximity to the breadboard/Arduino Uno that I'm using.

Here's the Git repo for the project if you're interested.

The problem comes when I'm running the buttons and LEDs from a distance. I've not yet hooked up all the strips since the first one went nutso when I hooked it up. I attached a 100uF capacitor across the positive and negative near the strip and that seemed to stabilize it ..... when the long button circuit is disconnected. I can substitute a testing button circuit on a breadboard just next to the Aduino and this works fine. When I pull this out and plug in the long actual button circuit, the LED strip goes unstable again.

It's got me a bit frustrated at the moment so any help would be greatly appreciated.

The first LED strip starts at about 1.5 metres from the arduino and power source (20 AWG for + and ground, 22 AWG for data line).
The first button is about 2.5 metres from the Arduino. (22 AWG)
The second button is about 8 metres from the Arduino. (22 AWG)

Each step would have a single WS2812b strip of 72 Individually programmable LEDs. There are 7 steps in the staircase so 7 x 72 = 504 LEDs in total.

I've got got 5V @10amps driving the circuit as you can see in the drawings below. (I know that more amperage would be ideal but we never plan to run this on full brightness. It's meant to be a bit dim/subtle and I've coded it to not go over 50% brightness.)

I've gone to a bit of trouble to make a schmatic and Fritzing breadboard to clearly communicate my currently dysfunctional idea.
(Better quality images: schematic | breadboard).

And here's an example of what the end result would look like. I used one strip at a close distance for this image.

Why the 10K pull-down on the buttons? Try removing that. Could be that the 10K and the internal pull-ups (20~50K) are forming a voltage divider, resulting in a voltage at the input pin which does not reliably read HIGH or LOW.

OK, a couple of practicalities.

72 LEDs at a potential 60 mA each comes to 4.32 Amps. Even half of that is quite significant passed through the foils on the LED strips. It would be preferable to provide a power rail (connection) at both ends of the strip.

Snaking the data connection back from the end of one strip to the start of the next is a concern. It would be preferable to have the data line go with the ground and power connection on the other side of the step directly up to the start of the next step given that the strip on alternate steps runs in the opposite direction. This substantially shortens the data run.

Nevertheless if you must run connections to one side of the step only, the data line must come back directly along the strip and not be separated from it. All three lines - data, ground and power, must always run together everywhere. And not only at the start of the first strip, but wherever there is significant distance - perhaps 30 cm or so - that the data line travels, it should have a 330 or 470 Ohm resistor in series at the start ("data in" point) of each strip section.

It follows also that the data line from the Arduino (Nano) to the LED strip must travel with the ground line. In practice, you run the 5 V power and ground back to the Arduino from the 470 µF capacitor at the start of the first strip together with the data line. Note: you do not power the Arduino from 12 V.

I too wonder why you would have that 10k resistor in the ground line from the buttons. If you think it is some form of "protection" against something then it is exactly the opposite! :astonished: And almost certainly part of the cause of your problems along with the lack of debounce code. :roll_eyes: But then you have not posted the code here (using "code" tags) either.

Of course it also follows that the wiring to your buttons must also run in paired (or triplet) cable.

Thanks for the responses.

PaulRB:
Why the 10K pull-down on the buttons? Try removing that. Could be that the 10K and the internal pull-ups (20~50K) are forming a voltage divider, resulting in a voltage at the input pin which does not reliably read HIGH or LOW.

I'll first try getting rid of the 10K resistor on the button ground line and see if that helps. I put that there because a tutorial I was following on debouncing a button used one. It did work fine in close proximity to the board but clearly that's a different scenario than running several metres through the walls of a steel-framed house.

Paul__B:
Nevertheless if you must run connections to one side of the step only, the data line must come back directly along the strip and not be separated from it. All three lines - data, ground and power, must always run together everywhere. And not only at the start of the first strip, but wherever there is significant distance - perhaps 30 cm or so - that the data line travels, it should have a 330 or 470 Ohm resistor in series at the start ("data in" point) of each strip section.

Very useful info there, cheers. The way the stairs are designed doesn't allow me to run the strips in alternating directions although, as you pointed out, that would be ideal. The data line runs back under the strip as you suggested.

Paul__B:
It follows also that the data line from the Arduino (Nano) to the LED strip must travel with the ground line. In practice, you run the 5 V power and ground back to the Arduino from the 470 µF capacitor at the start of the first strip together with the data line.

So you think the 5V from the Arduino Uno could supply 504 LEDs? I didn't know they were capable of that as most of the examples of long LED runs I've seen online inject power from elsewhere. Perhaps I should also run positive and ground from the Arduino in addition to the injected power?

Paul__B:
Note: you do not power the Arduino from 12 V.

Someone should tell whoever runs the official Arduino store. There it is specified: "Input Voltage (recommended) 7-12V"

Paul__B:
And almost certainly part of the cause of your problems along with the lack of debounce code. :roll_eyes: But then you have not posted the code here

I linked my repo in the original post. The code spans across three files. The buttons are debounced. Interesting that you would assume they aren't.

Here's the relevant "button" code class.

// this class defines a button object
// we instantiate it with the pin number, eg:
// Button button1(2);

class Button
{

  private:
    bool _state;
    uint8_t _pin;
    int _debounceDelay;

    long _lastButtonPressTime;
    int _waitTime;
    int _clickCount;


  public:
    Button(uint8_t pin) : _pin(pin) {} // object is instantiated with pin #

    void begin()
    {
      pinMode(_pin, INPUT_PULLUP);     // init button
      _state = digitalRead(_pin);      // read the state of the button
      _clickCount = 0;                 // count the clicks
      _lastButtonPressTime = millis(); // initialise button press time
      _waitTime = 1000;                // milliseconds to wait for next button press
      _debounceDelay = 50;             // milliseconds to delay for debounce effect

      delay(_debounceDelay);           // delay to "debounce" button
    }

    int buttonChanged()
    { // detects if the button has changed state

      bool v = digitalRead(_pin);

      if (v != _state)
      { // compares current state to previously recorded state

        _state = v; // records this state

        // create timing to see if it's a multi-click
        long now = millis();
        long interval = now - _lastButtonPressTime; // checks the difference between this press and the previous one
        _lastButtonPressTime = now; // resets last button press to current time
        
        if (interval > _waitTime)
        {
          // reset click count
          _clickCount = 1;
        }
        else
        {
          _clickCount++;
        }

        Serial.println(_clickCount);
        return _clickCount;
      }
      return 0;
    }
};

What you have is neither a pull-up or pull-down resistor. The easiest solution is to enable the internal pull-ups. Then, one side of the switch goes to the Arduino input and the other side gets a direct-connection to ground. (The button will normally read high until the button is pressed. When the button is pressed the switch "overpowers" the pull-up, grounding the input and the input will read low.)

If you get noise (false triggers) you can add a lower value pull-up (maybe 1K) between the Arduino input and +5V, or you can add a capacitor (maybe 0.1uF) between the Arduino input and ground.

I want it to be controlled by two simple buttons that can be mashed as people ascend/descend the stairs; hence, one button would live at the top of the staircase and one at the bottom.

I'm not going to "analyze" your code but logically you may not need to debounce…

If you activate the button at the bottom of the stairs, presumably "something happens". And, presumably that "something" doesn't stop if you activate the same button again, or if it bounces. Maybe the sequence starts-over if you press the button again, or maybe nothing happens until you activate the button at the opposite end of the stairs, or maybe it stops after some time-out.

ekendra:
I'll first try getting rid of the 10K resistor on the button ground line and see if that helps. I put that there because a tutorial I was following on debouncing a button used one.

I very much doubt that. Even if it was one of those "instructables" we encounter here with such dread! :astonished: It is completely nonsensical. :roll_eyes:

ekendra:
So you think the 5V from the Arduino Uno could supply 504 LEDs? I didn't know they were capable of that as most of the examples of long LED runs I've seen online inject power from elsewhere. Perhaps I should also run positive and ground from the Arduino in addition to the injected power?

This is a very confused statement. The Arduino (to quote another recent contributor, "The UNO is for prototyping, the Nano is for production") has nothing to do with supplying power to anything. You supply the LED strings from a regulated 5 V power supply.

Because you have a regulated 5 V power supply, that is what you use to power the Arduino via the "5V" pin. This avoids two concerns, one is that the regulator in the Arduino is not capable of powering anything beyond the main chip and USB chip (which draws power even if not connected to USB), the other that is avoids having the first LED in the strip fed with power from the data line if the strip is not powered but the Arduino is. This is actually, part of the protective function of the 330/ 470 Ohm resistor.

ekendra:
Someone should tell whoever runs the official Arduino store. There it is specified: "Input Voltage (recommended) 7-12V"

Indeed - a common trap for "newbies" causing problems over and over and over again.

ekendra:
I linked my repo in the original post. The code spans across three files.

Good for you. But not too many people looking at problems here are keen to search through your repos fixing problems. :roll_eyes:

ekendra:
The buttons are debounced. Interesting that you would assume they aren't.

OK, that is a very crude but mostly effective de-bouncing. :grinning: The rule in these forums is: "Suspect everything." :grinning: