Daisy Chained 10 x 16bit pixel rings

I have 10 x 16bit neopixel rings which are all daisy chained together (DO - DI),

is there a simple way to define each ring as its self ie ring1, ring2....?

or should i be looking at putting these into some sort of array?

or any other suggestion?

looking to be pointed in the right direction

Thanks Wayne

What is a 16 bit NeoPixel ring? You mean a 16 pixel ring? If so (I own one), first which library are you using to drive them?

Yes, you could use arrays or even just math.

so if you want pixel x (0..15) of ring y (0..9) to go green you could write

strip.setPixelColor(16 * y + x, 0x00ff00);

you’ll want to take care to keep x and y in range… the 17th pixel of ring 3 is the same as the 2nd pixel of ring 4. Or something like that.

There are many ways to make the abstraction you seek. None, however, will escape the hard fact that it is one real ring and strip.show is going to update the entire collection of rings. This shouldn’t be an issue with 160 LEDs.

a7

With this kind of LED, there is always an array. That is because the entire strip must be written at one time, even if you only need to change one or a few LEDs. So you have to keep an array in memory and modify any pixels that you want to change. The popular libraries create and manage such an array for you.

aarg:
What is a 16 bit NeoPixel ring? You mean a 16 pixel ring? If so (I own one), first which library are you using to drive them?

yeah one of them, i will probably be running them on the Adafruit library

alto777:
Yes, you could use arrays or even just math.

so if you want pixel x (0..15) of ring y (0..9) to go green you could write

strip.setPixelColor(16 * y + x, 0x00ff00);

you’ll want to take care to keep x and y in range… the 17th pixel of ring 3 is the same as the 2nd pixel of ring 4. Or something like that.

There are many ways to make the abstraction you seek. None, however, will escape the hard fact that it is one real ring and strip.show is going to update the entire collection of rings. This shouldn’t be an issue with 160 LEDs.

a7

thanks will give this a go, just to get a fell of how it works, although in the long run i think going down the array path may make my coding easier long term

If you use FastLED, this should work.

#include <FastLED.h>

constexpr uint8_t ledsPerRing = 16;
constexpr uint8_t numRings = 10;
constexpr uint8_t numLeds = numRings * ledsPerRing;
constexpr uint8_t ledPin = 4;

CRGB rings[numRings][ledsPerRing];

void setup() {
  FastLED.addLeds<WS2812B, ledPin, GRB>(rings[0], numLeds);

}

void loop() {
}

I have a library that does that. You set groups and program each as individual objects.

chainPixel class allows groups of pixels to be coded independantly from each other, while running off of a single processor pin.

You can have a look if you like : LC_neoPixel

-jim ee

alto777:
Yes, you could use arrays or even just math.

so if you want pixel x (0..15) of ring y (0..9) to go green you could write

strip.setPixelColor(16 * y + x, 0x00ff00);

you’ll want to take care to keep x and y in range… the 17th pixel of ring 3 is the same as the 2nd pixel of ring 4. Or something like that.

There are many ways to make the abstraction you seek. None, however, will escape the hard fact that it is one real ring and strip.show is going to update the entire collection of rings. This shouldn’t be an issue with 160 LEDs.

a7

The fittest abstraction in such cases is sometimes to extend the class to include a new function that does the same math in the background. Then you create a new object 'strip' in the inherited class and you can say

strip.setPixelRingColor(ring_01, 3, 0x00ff00);

The fittest abstraction in such cases is sometimes to extend the class to include a new function that does the same math in the background. Then you create a new object 'strip' in the inherited class and you can say

I would say the way to go, though some other solutions came to mind. First solutionstrip.setPixelColor(16 * y + x, 0x00ff00);could also be easily modified to work like

void SetRingPixelColor(uint16_t ring, uint16_t pixel, uint32_t colorl) {
  strip.setPixelColor(16 * ring + pixel, color);
}

Actually in all it's simplicity, no extra library, no modification of library, i think i would do this.

Yes. I use two smart LED libraries, so I wrote two sets of my own functions so I can think about strips in just one way no matter which library I employ. I've always called these cover functions, it looks like "wrapper" is the real term of art.

If a third library comes along, I'll just wrestle it into the way I want to think about it with a third set of wrappers.

No doubt I reduce the beauty and flexibility of the originals - for example, I'd not be able to directly actually have two strips on two outputs but

I don't really care and

when the day comes where I need two separate strip objects I'll wonder what I've gotten up to.

So far maps and maths have sufficed.

I would do like @Deva_Rishi shows, only it would be less beautiful 'cause I stick with static, unsigned, int, long, and char vocabulary for declarations. Which are also destructive of the more precise uint_16 kind of thing.

I can see my future well enough to know I'll not be bitten on the gluteus maximus. Y'all might be, um, younger.

a7

Setting it up so that each bit can be thought of by "the human" as a independent piece is best, because it matches the human way of thinking. Having to use offsets or math Just adds needless complications the matter, making it hard for mr user to get done what he/she''s looking to do.

Yes the Math and complication is still there. But abstract it away and let the processor deal with it. Isn't that what libraries are for?

Here is an example of 3 sections of neoPixels all programmed and running independtly on one daisy chained wire. Vemo video

The main loop() read inputs and set up the variables from the RC receiver. Each section of LEDs read those variable and decided what it should do given its inputs. In fact it was easier than that because there was only two different types of section. The tail light and the flood lights. I just added the floodlight object twice to the list.

-jim lee

only it would be less beautiful 'cause I stick with static, unsigned, int, long, and char vocabulary for declarations. Which are also destructive of the more precise uint_16 kind of thing.

Equally beautiful, the only reason i chose uint16_t (aka unsigned integer) is that even though there is no need (8 bits would easily suffice, a sign is not needed of course) but i am going to multiply the ring with the number of pixels per ring, and i wanted to make sure that 20 rings would not exceed the size of the variable, the pixels should probably only uint8_t, but what if your program wants to make use of the strip as a whole, at times, in that case you might want the number of pixels per ring as an argument as well, that as 16-bit, the number of rings as 8-bit, and the pixel as 16-bit. The reason i use uint16_t as a type instead of unsigned integer is that it is clearer for me what it is and it is less to type. It is not for beauty.

Deva_Rishi:
Actually in all it's simplicity, no extra library, no modification of library, i think i would do this.

You do not have to modify a library or add one, to extend a class.

Thanks for all the help guys, just getting back onto this project after working all week, i have give alto’s a try and it working perfect

im going to have a look through some of your other solutions

alto777:
Yes, you could use arrays or even just math.

so if you want pixel x (0…15) of ring y (0…9) to go green you could write

strip.setPixelColor(16 * y + x, 0x00ff00);

you’ll want to take care to keep x and y in range… the 17th pixel of ring 3 is the same as the 2nd pixel of ring 4. Or something like that.

There are many ways to make the abstraction you seek. None, however, will escape the hard fact that it is one real ring and strip.show is going to update the entire collection of rings. This shouldn’t be an issue with 160 LEDs.

a7

i based this on 3 rings to keep it simple

#include <Adafruit_NeoPixel.h>

#define PIN 6 

#define NUMPIXELS 48

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {

  pixels.begin();
}

void loop() {
  pixels.clear();

    for(int i=0; i<16; i++) {
    pixels.setPixelColor(16 * 0 + i, 0x00ff00);
    pixels.setPixelColor(16 * 1 + i, 0x0000ff);
    pixels.setPixelColor(16 * 2 + i, 0xffff00);
    }

    pixels.show();  

    delay(500); 
  }

ok so this seems to be working as intended, as @altos & @Deva_Rishi suggestion, next question can this be easily modified to exchange the colour for an effect, for example theaterchase

#include <Adafruit_NeoPixel.h>

#define PIN 6 

#define NUMPIXELS 48

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {

  pixels.begin();
}

void loop() {
  pixels.clear();
  
for(int i=0; i<16; i++) {
  SetRingPixelColor(2, i, 0xffff00);
}
    pixels.show();  

    delay(500); 
  }

  void SetRingPixelColor(uint16_t ring, uint16_t pixel, uint32_t color) {
  pixels.setPixelColor(16 * ring + pixel, color);
}

can this be easily modified to exchange the colour for an effect, for example theaterchase

of course it can but it does depends on how you are going create the theater chase. If you are planning to expand beyond the theater chase, and you want different patterns on different rings, with different speeds & | colors, then you should create non-blocking code, either using millis() compared to time elapsed or time elapsed and modulo the cycle length. If you just want to have a chase synchronous on multiple rings, but with different colors, that is fairly straight forward.

It would be the first, different effects / colours, now i know this is possible i will look into it, how difficult would you rate that

It should be straightforward. Any examples you find should be able to work directly on a portion of you total LED resources.

As @Deva says, if you are looking for multiple independent effects each playing out on its own group of LEDs you’ll have to get your mind around the “multiple things at once” type approach that is mentioned on these fora about 17 times a day… there’s a reason it comes up so much, the methods work and it is quite gratifying to see your little machines cranking away as if you had several many UNOs on in there.

BTW at this time you might want to put some range checking in the low level call, so if when you make an errant call, say to the 17th pixel or a non-existent 11th ring you get a head’s up.

I wrote a function that just prints a message on Serial port and hangs up. When I do something bad, it prints a message that I have done and appears to stop.

void errorStop(unsigned char theMessage)
{
    Serial.println(theMessage);
    
    for (; ; );
}

so

if (pixel < 0 || pixel > 9) errorStop(“bad pixel!”);

in the SetPixelRingColor function will fire off. Similarly others.

It’s admittedly quite crude, but easy to do, costs little enough, can be left in the final code and at least gives you a start on where to look.

It doesn’t matter if you leave it there, you can output to the Serial even if nothing is hooked up, just let it talk to no one because it shouldn’t talk at all.

Hook it up if it ever hangs and see if you get one of your messages.

I like to Seril print the name of the program, too, I wish I had always done as I have too many projects and too few notes about what code eventually got placed on them, I an totally without discipline, a xcharacter flaw that can make programming a challenge.

Be better.

a7

how difficult would you rate that

Hard to say, i've done something similar (different though), but what does that say. Anyway, yes you will have to start using millis() for timing, and in a way you can find out by simply creating a single effect, using millis() for timing (basically re-write examples that come with the library you are using) Just start with one effect, and see if you can run it with different parameters (color, speed, maybe something else) on different rings. Do have a look through the forum if you want examples of using millis() for timing on LED-strip, they are there, but i have no idea under what topic name.