Time to look for alternatives.

Time to look for alternatives.

I have a strip of LEDs where the physical layout requires me to “rotate” the data of variably-sized blocks of the LEDs by a variable number of LEDs, both variables defined by the block definitions. By rotate, I mean, for example:
1234 56789 (Group of four and group of five)
becomes
2341 78956 (Shifted by one and two respectively)

I already have a solution that handles this by using two CRGBArrays and moving data from one to the other. The downside is this uses substantially more memory.

I wanted to save SRAM by using a small section of extra space at the end of the main array or a scratch array, either of which would be the size of the largest possible block. Remap one block to the scratch space, then move it in line back to the original location. Logically, this should be trivial and easy. Unfortunately, something wonky goes on when it gets compiled and instead of moving the data, I end up with a convoluted tangle of references and pointers instead, which makes a mess of things.At this point, there is enough other code that uses RGBSets to handle the groups that I’m not keen on the idea of moving to straight pixel arrays and a monolithic remap function like the XY Map Generator.

Does anybody have any insight on a good way to shift around the contents of blocks of pixels in a long pixel array without using an entirely different array worth of space? Or a way to get scratch space shuffling working?

I imagine 1 CRGB variable and some clever logic is all you need.

@Gibbedy_G Using that variable as a temporary holder for the data point that is being moved into means that the main array still has attempts being made to move from one location in the array to another at which point the Tangled Mess of References occurs and the main array gets to be a mess. :slight_smile: Even sort-moving data into a scratch array of CRGB and then back into the proper location makes a mess. The size of the array makes no difference. Would be a good idea if things behaved. ^.^

@Kit_Parenteau i do this kind of stuff like using a Malloc to create the necessary space execute some transformation and then free the allocated space. Maybe easier if we could see a piece of code ?

You can use a single auxiliar variable then perform some SL^1 function (shift left). Good luck

@Yves_BAZIN I can drop a CRGB array on the stack that gets deleted when it leaves scope, but the moves within scope create a problem anyway. Same code as the other post that faded, the main thing is focusing on getting the remap done efficiently EVerything else works just fine. However if it helps understand the issue better, I’ll make a pseudo-remap sketch that anybody with ten LEDs can run that shows the problem.

@David_Sole_Gonzalez I’ve been trying to write the shift in about a dozen different ways and logically it should work. But it’s not.

The shortest version, for example:

void remap() {
uint8_t i = 0;
for (uint8_t thisFan = 0; thisFan < NumberOfFans; thisFan++) {
leds(NUM_LEDS, NUM_LEDS + LedsPerFan - 1) = leds(i, i + LedsPerFan - 1);
leds(i, i + ShiftCCW - 1) = leds(NUM_LEDS + LedsPerFan - ShiftCCW, NUM_LEDS + LedsPerFan - 1);
leds(i + ShiftCCW, i + LedsPerFan - 1) = leds(NUM_LEDS, NUM_LEDS + LedsPerFan - ShiftCCW - 1);
i = i + LedsPerFan;
}
}

Notes:
ShiftCCW, NUM_LEDS, NumberofFans, and LedsPerFan are all constexprs that pull various values. Applying numeric constants for testing purposes does not solve the issue. Values of “12” for LedsPerFan, 10 for NumberOfFans, 120 for NUM_LEDS, and 2 for ShiftCW can be used as common values for sanity checking.

leds is a CRGBArray of size NUM_LEDS + 14 (Where LedsPerFan <= 12 in all cases)

I’ve tried it as a manual iteration. I’ve tried it with other global CRGBArrays. I’ve tried it with CRGB arrays (just plain pixel arrays). I’ve tried it with local data stores. I’ve tried rearranging the parts to the other location then moving it back as one chunk. I’ve tried manual iteration for some parts and CRGBSet for the other parts in various combinations. It just makes a mess of the CRGB data in the array every time.

Short sketch that breaks will be provided when I don’t have too little sleep before a long drive to car repairs.

https://github.com/DoHITB/SHA1.cob/blob/master/SHA1HEX.CBL

Here I implemented a left-shift function on cobol you may want to take a look (sorry for spam but my phone crashes when trying to reach the code… Look for "Left-shift).

Regards

@David_Sole_Gonzalez Creating the shift is not the issue. The structures that it’s operating on in fast led are the limiting factor and misbehaving. The code implemented should work, logically, but when it’s compiled and run, it ends up working with pointers and references instead of moving the data around. And it only does it when doing the double move. A single move of data doesn’t have a problem. If I didn’t have to operate on the data in situ, I’d start with it shifted to the side and then do one move and see if that works. Might be able to do that anyway at the cost of a few ms of processing. Shift it right, modify it, then shift it left and sort it at the same time.

Ah OK sorry didn’t understand that point. So, just a thought but when you said “one move” are you telling “one move for each loop?” it is that, a cheap way to solve it could be doing the shift on two steps with really small time window?

@David_Sole_Gonzalez Taking arbitrary values of a group of four and a shift of two, the current code and all attempts thereat does:

Move 1 2 3 4 to holding location.
Move 3 4 to index 1 2 from holding location.
Move 1 2 to index 3 4 from holding location.

Index starting with one just for clarity.

The first move to the holding location has stable data. When it gets moved back, both the holding location and the target get linked references or something instead of copied data. I’ve tried with many different ways of shuffling it around with no luck. Sort first then move in order. Move in order then sort. Using different crgb data structures. Try using the same array or different arrays. Move using crgbset internal iterations vs manual iterations. Create holding containers transiently or have global containers. Nothing is working.

In the example what is the type of the variable leds?

@Gibbedy_G LED type is ws2812. The program addresses them all as a sequential strip of 120, grouped into four or twelve currently and with ShiftCCW being 1, 2, or 10 depending on the physical object.

I think the = operation is moving the reference pointer not the data.

Have you tried to stablish some separated led then assigning into the position of the array?

@Kit_Parenteau Ok. But in the example you give what is the data type for leds variable.

When I see this line:
leds(NUM_LEDS, NUM_LEDS + LedsPerFan - 1)…

leds is a function?
I’m misunderstanding something here.

@David_Sole_Gonzalez That’s pretty much what I’m seeing. But not consistently. Anything working directly with any CRGB variable or array of any type seems to be triggering the printer move instead of data move.

When I get a chance, I might see if I can extract individual uint8_t data from the CRGB channel data and see if that works. Painful, but ah well.

@Gibbedy_G Ah. leds is a CRGBArray from FastLED

And making it on a static way is possible? You can try to do it on a static way…

@David_Sole_Gonzalez FastLED needs to operate on the CRGB data type array to feed the hardware. I have a lot of code locked into using CRGBSet code as well, so jumping out of that would not be a minor effort. But working with even just basic arrays gets broken too.

I’ve tried with global variables and local variables and extensions of the main array and even temporary arrays that are created and destroyed on the heap. The last there got really interesting because the pointers still got moved instead of data, but then the location was not allocated. Got very flashy. I’d expect a static CRGB data set to still end up behaving the same as a global one, but I’ll give it a try.

I mean… Programming it like a gif… Set up the main array then sleep, setup it again with new values and so on…

Ok. I didn’t know about CRGBArrays. I only use CRGB arrays.
I’m no help then. :slight_smile: