I am messing around with some strips oriented in a matrix,

I am messing around with some strips oriented in a matrix, the strips are wired one after another in a reverse ‘s’ fashion:
1,2,3,4,5,6,7,8,9,10
20,19,18,17,16,15,14,13,12,11.

It is 10 wide x 9 tall for a total of 90 ic’s. I am looking for some assistance in Inverting every other row so my patterns originate from one side of the matrix. Right now, my code ‘pushes’ the leds[] array. I set leds[0] to whatever color I want it to be and show() the string, then push everything over by one. With this configuration and my strips, the animation travels from right to left, etc.

I am wanting to create some method/code that will take my LEDs and change the order of my LEDs:
1,2,3,4,5,6,7,8,9,10
11,12,13,14,15,16,17,18,19,20

Anyone have a bread crumb they could throw my way?

Try unions of arrays that will flick the orders without any direct processing in your program.

I conceptually understand how it needs to work, I struggle with the programming syntax to achieve the desired result.

What exactly is “unions of arrays” ?

So, you’re going to have one giant array of leds, right? (Apologies for some of the basic code/math in here, hoping this can help other people as well)

  #define   NUM_LEDS 90
CRGB leds[NUM_LEDS];

Let’s look at the math to access your 10 wide by 9 high array, assuming that it’s not an S curve (where X and Y is the column and row of your pixel that you want)

leds[X + (Y * 10)] = CRGB::White;

of course, you want to swap the order for every other row. So, where rows 0, 2, 4, 6, 8 are “forward”, rows 1,3,5,7, and 9 are “backwards”. In C, using the modulus operator (%), which gives you the remainder when you divide by another number. So, if you want to tell if a number is even or odd, you mod it by 2 - which, behind the scenes divides by 2, and if the number is odd, there will be a remainder of 1, and if it’s even, there will be a remainder of 0. So now, we can do:

if((Y % 2) == 0) {
// we’re even, and going forward!
leds[X + (Y*10)] = CRGB::White;
} else {
// we’re odd, now we need to go backwards!
}

When indexing into the array - (Y*10) gives you the start of a row. So, that doesn’t need to change. But, we want to swap X around, so that 0 becomes 9, 1, becomes 8, etc… aka (9-X) (in reality, it’d be “(NUM_IN_ROW-1)-X”)

if((Y % 2) == 0) {
// we’re even, and going forward!
leds[X + (Y10)] = CRGB::White;
} else {
// we’re odd, now we need to go backwards!
leds[(9-X) + (Y
10)] = CRGB::White;
}

et. voila! You can use X & Y coordinates to index into the right point in the array :slight_smile: To give you a function that makes life easier for you:

CRGB & getPixel(int X, int Y) {
if( (Y%2) == 0) { return leds[X + (Y10)]; }
else { return leds[((NUM_IN_ROW-1)-X) + (Y
10)]; }
}

and anywhere else you can say things like:

getPixel(5,8) = CRGB::Blue;

We all keep pushing @Daniel_Garcia to get his matrix code done and published already. :wink:

Working on trying to come up with a good, clean solution for N-way mapping right now (e.g. you give it X sets of led array bits, and say what’s written to one gets written to all). I think i have the rough idea worked out in my head, now though. (There’s naive solution options that would introduce far far more overhead than I want :slight_smile:

Hey, I realize this isn’t your day job. I’m just messing with ya. Whenever you finish it, I’m sure it’ll be awesome no matter what.

Amazing, thank you Daniel.

following mr garcia’s info before, i did the same thing, but it was messing my head too much… so here is a less clever solution, but it opens out the usage in my mind better;

set up an array;

int allleds[32] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
};

int alltim[32] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
};

then you can use;

leds[allleds[i]].setRGB(random(254), random(254), random(254));
LEDS.show();

leds[alltim[i]].setRGB(random(254), random(254), random(254));
LEDS.show();

i like this, as you can setup specific set places, like corners, centres, and call them directly. its not as fluid, but it works!

Randomly (hah! see what I did, there?) the library comes with much faster random number generators than the arduino ones, including a random8() which already clamps values from 0-255 for you :slight_smile:

Also, if you want colors of a consistent brightness, but still a bit more random on the color leveling/saturation, i’d say instead:

leds[allleds[i]] = CHSV(random8(), random8(), 255);

Unions in C allow you to over-lay variables in memory on top of each other. In your case, you want one array that you work with to ‘load’ your output pattern. This sits on top of the array that matches your LED matrix and is used to ‘output’ the result.

So one array you ‘load’ data that 'union’ed onto the array that you output to the LEDs via FastSPI. They occupy the same memory as far as the compiler is concerned, so only take up one lot of RAM.

Google for ‘C union tutorial’ and you probably want to also look up ‘struct’ too to allow construction of odd arrays. Then you can sit your two structures on top of each other with the union statement.

Should get you started, very useful knowledge in C and C++ to be ale to do this.

The one problem with using a union is there’s no way in C to say “this array indexes backwards” - and you don’t want to have individual elements as union elements. Here’s an led matrix class that would almost work like a normal 2 dimensional array (the difference is that [] does a linear walk through the array elements, and () w/two parameters is used for x,y):

template<int ROWS, int COLS, bool ZIGZAG=false> 
class CLEDMatrix {
    struct CRGB *m_ledData;
    int m_ledCount;
public:
        CLEDMatrix(struct CRGB *ledData) : m_ledData(ledData), m_ledCount(ROWS * COLS) {}

    int rows() const { return ROWS; }
    int cols() const { return COLS; }
        int size() const { return COLS * ROWS; }

    struct CRGB& operator[](uint16_t x) { return m_ledData[x]; }
    struct CRGB& operator()(uint16_t row, uint16_t col) { 
	            if(ZIGZAG && (row & 0x01)) {
		                return m_ledData[row*COLS + ((COLS-1) - col)];
	            } else {
		                return m_ledData[row*COLS + col];
	            }
        }
};


CLEDMatrix<9,10,true> ledmatrix(leds);

ledmatrix(x,y) = CRGB::Blue;

(This is from an older version of the led containers library that I’m putting together).

That said, unions are very very very useful.

The way I handle this is to use a defined function that essentially handles all the translation for you, similar to:

void SetLED(byte x, byte y, int color) {
int pos;
if(y%2){pos = x + y10;}
else {pos=10-x + y
10;}
leds[pos] = color;
}

This way it handles all of the transformations you might need. I have a few projects that have required mapping the position of LEDs on a strip to different locations on a odd shaped 3D object, and use similar functions to define things like the front edge, sides, loops, arcs, etc… and regardless of the number of LEDs, have it map to 1-255 or 1024. This allows me to address them individually from anywhere in my program without having to customize it to how many LED’s are actually in that particular strip.

I grasp the concept of how to find a specific point in the LED array now. Now, in moving forward I am somewhat confused still. Do I need to create an array of preset data to pull from, say:

//MATRIX
//int matrix[4][10]={
//{000,255,000,000,000,000,000,000,255,000},
//{000,000,255,000,000,000,000,255,000,000},
//{000,000,000,255,000,000,255,000,000,000},
//{000,000,000,000,255,255,000,000,000,000}};

Using Arren’s post, my FUNCTION would look like this:

void SetLED(byte x, byte y, int color) {
int pos;
if(y%2){pos = x + y10;}
else {pos=10-x + y
10;}
leds[pos] = color; //this initializes CRGB?
}

Now, the next part is escaping me. I understand my function is populating my CRGB array. If I were to create a for statement that would populate the whole CRGB array before I call the LEDS.show?

Arren’s code has an off by 1 error in it - that second line should be 9-x (the value of x is going to be from 0-9, not 0-10, because you have ten items in each row).

There’s no need, most likely, for you to do an array of preset data - unless you’re going to be animating presets?

Also - I wouldn’t use ints to pass colors around with FastSPI_LED2 - use CRGB objects - they have the correct representation internally, you don’t have to worry about making an RGB value into an int, and you won’t get snagged by things that the code above has, like int is 16 bits wide, which is not enough to hold the 24 bits of color dat a needed for pixels :). If color was a uint32 then leds[pos]=color; would do the right thing.

Good catch :slight_smile: Was just writing that up in line, and was basing it off of some code that I worked with recently that used INT to store the color data. (Octo library for Teensy)

But yes, you could easily just pass in the CRGB object instead I believe.

Daniel, it seems that animating presets is the only way I can wrap my mind around this subject. What are the downfalls for programming this way? For me, the visual aspect of seeing my patterns appeals to me.

Perhaps, does anyone have a link to some suggested reading material? I have found limited resources explaining the subject of using led strips in a matrix.

@Kelvin_Mead In your code,:
#define NUM_LED 20

int allleds[20] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
19,18,17,16,15,14,13,12,11 };
int alltim[20] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20};

the two different arrays are acting as your matrix coordinates right? So if I create:

for( int i = 0; i < NUM_LED; i++)

the “i” int will control the x and y coordinates in:

leds[allleds[i]].setRGB(255,255,255);
LEDS.show();
leds[alltim[i]].setRGB(255,255,255);
LEDS.show();
delay(10);

The end result is a single white pixel traveling from Left to Right down each horizontal row?

I found @Zeke_Koch 's raindrop’s sketch extremely helpful in understanding the coding of a matrix. His code was extremely easy to modify from the adafruit library over to the fast_spi and modify for my specific matrix needs. Thanks!!!