Addressable LEDs

Still learning, so sorry for what are probably daft questions...

I assume if I wire 16 ws2812 LEDs then the first one on the data pin will be 0 and the last one 15.

What happens if I wire two banks of eight LEDs to the same pin in parallel..or is the operative word just...”don’t”?

You can do that. Both banks will have the same numbering and you will not be able to control the banks individually (e.g. if you send a signal to LED 0 then LED 0 on both banks will react).

If you want to be able to individually control 16 (or more) LEDs, without using every single pin on your Arduino, you need to look at some way of switching them independently.

2 options - one simple, one hard(er):

Simple: Buy some 74HC595 chips, and read this page.

Complex: Arrange LEDs in banks of 8, with a common cathode for each bank, connected to the collector of an NPN transistor. Connect (via a base current limiting resistor) each transistor base to an Arduino pin. Connect the anodes of each corresponding LED in each bank together & to an Arduino pin, via a current limiting resistor.

e.g. if you had 3 banks of LEDs: Connect LED1 of banks A,B, and C to pin 2, LED2 to pin 3, and so on. through to LED8 (connect to pin 9).

Connect the transistor base linked to bank A to pin 10, bank B to 11 and C to 12 (repeat for as many banks as you have, until you run out of pins).

Now, in code, very rapidly switch pins 10, then 11, then 12 on in turn; and whatever LEDs you need in bank A, bank B or bank C in time with their cathode pins. This is called multiplexing... You've used 11 pins, but you're controlling 24 LEDs.

However, it's WAY easier to use 3x '595 chips, and just push out 3 bytes of information every time you need to change an LED from ON to OFF; plus the LEDs are lit all the time & not just for a few milliseconds.

GreyArea is using addressable WS2812 LEDs. You can control hundreds of them from a single pin.

pert:
GreyArea is using addressable WS2812 LEDs. You can control hundreds of them from a single pin.

I see....

Curses. There goes my fancy explanations then!

HA... I was just going to post the SAME THING!..

(good thing I scrolled down a bit to pert's response!) LOL

pert; thanks for your answers...I thought they might behave like that (each bank replicating the instructions) but wasn’t sure.

Thanks to AdeV too...didn’t know about the chips and it may come in useful if I’m ever using traditional LEDs.

Just a word of caution, though pert is correct about how they work technically, power drain adds up very quickly so that may limit any project requiring hundreds of LEDs. Also if the display is complex, bitbanging the data into each one can slow sketches down quite a bit.

power drain adds up very quickly

No it adds up in a perfectly linear way at the same speed that adding normally goes.

Also if the display is complex, bitbanging the data into each one can slow sketches down quite a bit.

You can’t bit bang these LEDs because they require precise timing that has to be done with interrupts disabled. I think you are confused about what bit banging is.

Hi mike.

Okay, power demand does indeed add up as predicted...I was only trying to inform other newbies like me that the promised land of displays of “100s of LEDs” on a single pin came with other considerations.

Yes, my terminology may be off as to bitbanging, but the point remains...more LEDs, slower responses.

but the point remains...more LEDs, slower responses.

No not at all.

That implies you can see the response getting slower as the number of LEDs increases, quite simply you don't. It all depends on what sort of buffer manipulation you are doing. In practice you have to slow things down with a delay or something to stop patterns going too fast.

Grumpy_Mike:
No not at all.

That implies you can see the response getting slower as the number of LEDs increases, quite simply you don't. It all depends on what sort of buffer manipulation you are doing.

Sorry Mike I’m standing my ground on this one. Since we’re discussing addressable LEDs specifically, it’s unlikely they’re receiving a mass “all on / all off” command, or even something as simplistic as a running light pattern. The higher number of LEDs implies increasing complexity of display, and that takes time.

If the display is a simple running light or mass on/off, why go to the bother of using individually addressable LEDs in the first place?

Sorry Mike I'm standing my ground on this one.

You can but it will crumble under your feet.

If the display is a simple running light or mass on/off, why go to the bother of using individually addressable LEDs in the first place?

How else can you have a running slug of lights it it is not with an addressable LED strip? Like this video:-

The other thing you underestimate is the speed of the Arduino's operation. Given you can't perceive updates at a rate faster than 18 times a second, that is a hell of a lot of CPU cycles you have to play with per update. I make it 888,888 CPU operations per update. Unless your code is very very crap that is not going to be a limiting factor.

The higher number of LEDs implies increasing complexity of display,

Yes, but their is a limit to the number of LEDs that you have the memory for in an Arduino. You are going to reach that limit before it has a visible impact.

and that takes time.

Yes but it is time you have in abundance so it will not be noticeable to an observer.

There are running light kits you can solder with traditional LEDs. I know I bought one to improv3 my soldering skills...no, it didn’t help much!

You’ve seen my code; it IS very, very crap.

I didn’t know the LEDs had a direct impact on memory...I can drive 44 or 144 with the same code by changing one number...the available memory doesn’t drop?

Anyway as usual we’re disputing minutiae; my point was the fact that you CAN drive 100s of WS2812b’s from a single pin doesn’t mean it’s easy.

Not for me, anyway.

There are running light kits you can solder with traditional LEDs.

Not with 240 LEDs there are not. For that sort of operation you need one output per LED.

the available memory doesn't drop?

Yes it does, the SRAM usage will increase, although it is not reported by the compiler in the IDE.

It takes 3 bytes of memory for each LED. On a Uno you only have 2K of this sort of memory for everything. The problem with a small controller and a compiled language is that you don't get a warning when you over run an array. So you can put what ever size of LED buffer you like in a program, say 700, but if you try and run that many the program will fall over when running.

It's arguable whether "bitbanging" is an appropriate description of how we drive the single-wire addressable LEDs; If we take that to mean a case where we're outputing some protocol without hardware acceleration, hence a blocking operation. If we use some other definition of bitbanging, maybe not.

That implies you can see the response getting slower as the number of LEDs increases, quite simply you don't. It all depends on what sort of buffer manipulation you are doing. In practice you have to slow things down with a delay or something to stop patterns going too fast.

The problem isn't updating the buffer, it's sending the data. Updating WS2812 LEDs does take time, it's 800 khz, so 100KB/s. 3 bytes per LED, call it 99KB/s to make math easier - 33,000 LED-updates per second. Most people would want 30 FPS minimum for animated LEDs, so once you're past 1000 LEDs, you can't update them fast enough to hit 30 FPS (and the controller is spending almost it's whole time focused on just writing out the data). For PoV stuff, one typically needs faster frame rates than that (though for PoV, the low PWM frequency of the 2812 is an issue too). Of course, on a '328, you run out of RAM at 600ish LEDs even if you have nothing else filling memory, but on larger chips, the time it takes to update the LEDs is the limiting factor on the length of the string. That's one of the big selling points of the more expensive APA102 (the APA102TW version also has a better red) - they claim to be able to take data at up to 32MHz (and also PWM's it's leds at higher frequency too);

The matter of supplying power is of course another issue - you run into that one much sooner, IIRC 100-something LEDs for that flexible LED strip, and a 5.0v input has drooped enough by the far side that the blue starts to dim and the whole thing looks like crap. But if you use an appropriately sized power supply, and have wires of appropriate thickness (there are calculators online) to supply power to points along the strip, this is just an annoyance...

(I also don't think it's inaccurate to say that the current adds up quickly - people are constantly getting caught off guard by how few LEDs it takes for supplying power to become an issue)

Don't get me started about the Neopixel library using dynamic memory allocation to set up the buffer; suffice to say I think it's a dumb design decision. Even if you might use multiple lengths with the same code - declare a static buffer of the maximum size - problem solved. But no, passing the constructor a pointer to a buffer is too hard for people, apparently. GitHub - SpenceKonde/Adafruit_NeoPixel_Static: Adafruit w/out pinMode or malloc()/free() to save flash.

But no, passing the constructor a pointer to a buffer is too hard for people, apparently.

No it isn't. The technique in the fast LED libiary is to allow you to avoid having a SRAM buffer and use any other area of memory to hold the bit patterns to output to the LEDs.

Grumpy_Mike:
No it isn't.

I don't think it is either, but apparently adafruit (who made the adafruit neopixel library that is one of the two competing libraries people use for WS2812) does.

I’ve read DrAzzy’s post seven times now. I think he stepped in to defend my position, but amongst that long list of acronyms I got very very lost. (POV I know As point of view, but I guess in this case, persistence of vision...the rest I’m still googling).

I set my LEDs with a for next loop or similar. I’m usually doing something mathematical based like my little “worm” program, so there’s an equation of sorts that I just pump numbers in and get pretty patterns out. The loops of course take time, which was my point.

Mike, I’m still green enough that I do things in weird inefficient ways...I think doing it my way is/could be described as bitbanging...but I don’t know why it should contribute to memory use...I (or rather the loop) set one pixel at a time and apart from the worm where I did have a (very small) array to hold the data, to my mind once the Arduino tells the LED it’s necessary info (“Oi. LED number 7. Yes you...red please!”) the Arduino can forget about it...I thought the LED just held the info on its little chip until the next instruction.

Is that not the case?

but I don't know why it should contribute to memory use..

The way that the driving of these LED strings are driven is that their is a chunk of memory in the Arduino that holds the RGB values for each individual LED . So each one requires three bits of memory.
When you set the colour of a single LED all you are doing is changing the numbers in this memory, you are not setting the actual LED.

Now when you call the show method what happens is that all the data in that memory is sent out into the LED strip and the actual LEDs get changed. Those memory locations you haven’t changes still send the data to the same LED and it gets a new value, but it is the same value as the previous time so you see no change.

Their is no way to send data to just one LED in a strip you have to send data to them all and that is why you need those three bytes to hold the data for each and every LED in your strip.

Aha!

So does this line

Adafruit_Neopixel strip = (Adafruit_Neopixel, N_LEDS, NEO_GRB, +NEO_KHZ800)

Effectively allocate the memory for (N_LEDS) neopixels? I notice it has the frequency tagged on the end too...thanks DrAzzy for clearing up that one.

Is it effectively creating some sort of array, and if so is there any way to “read” it to get the data for the neopixels? It would be cool if there was an equivalent of “if Neopixel (0) is red, then do ”...