Help with Mapping I initially used fadecandy for a project,

Help with Mapping

I initially used fadecandy for a project, but now want to see if I can make it better with FastLED and a Trinket Pro. What I don’t completely understand yet is mapping with FastLED. I have 6 strings (none are chained or wired to each other), three of which have 50 leds and the other 3 have less than 50 (depending on the part of my roof they are setup on). I see the example of ‘one array, many strips’ (Multiple Controller Examples · FastLED/FastLED Wiki · GitHub), but I am unsure how to use it for what I want to see especially when some strings are left to right and others are right to left.

Is there a way to map these strings so that:

#1 Show flowing patterns from left to right including all lights. This would also map multiple individual leds to single positions in a pattern. An example would be that I would want the first pixel in a pattern to move from left to right, it would start with the last led of the yellow string (very last pixel on the far left, which is the last led of that string).

#2, I want some led’s to be duplicated. Say there was a pattern moving from left to right (in the picture below the arrow shows where the first LED is in each string). I would want the very first led of the green string to show the same as the 20th led in the red string. The 2nd led of the green string would show the same as the 19th led in the red string, etc…

Thanks!

You can see examples of what you are trying to do in this code: GitHub - climent/bike-ng: FastLED code mapping several LED strings in a single output.

It has a function (allArrayFTB, short for Front To Back) that maps the LEDs so that they travel through several arrays in a way that present a continuous flow, using several strips that are in different directions and some of them combined together.

Thank you @Jesus_Climent I have been studying this for a bit, but don’t quite understand it all. Are your animations specific to your strings, or can you for instance define or map all the strings you have so that sketches like the example DemoReel100 can use them?

I have 6 strings, so I created 6 arrays. Here are the first three arrays (below), that represent the yellow, red, and green strings in my image.The yellow and red strings do not overlap, so yellow ends at 49 in it’s array and red picks up at position 50 of it’s array. The green and red strings overlap, so the green string starts at position 62 of the array, right where it is closest to the corresponding led in the red string. So:

Array 0, for yellow string 50 leds reversed, so position zero of the array has the value 49 all the way to position 49 which has the value 0,

Array 1, for the red string 32 leds reversed, so position 50 of the array has value 31 all the way to position 81 which has the value 0.

Array 2, for the green string 31 leds (not reversed), so position 62 of the array has the value 0 all the way to position 92 which has the value 30

How do I define these strings for FastLED, so it displays animations across a single ‘virtual’ string? In this case the ‘virtual’ string goes from 0 to 92 leds, but the leds are compromised by 3 strings. Also, because some strings overlap, if an animation wants to light up position 62 of the virtual string, it should map to position both 19 of the red string, and position 0 of the green string.

Including a subset of my array in an image, top row is array index (or index of virtual string), 2nd row is string 0 (yellow string), 3rd row is string 1 (red string), 4th row is string 2 (green string)

missing/deleted image from Google+

One common way of doing this: assign each LED a one byte (0-255) x-axis coordinate. Put these coordinates in an array. Multiple LEDs can have the same coordinate. Now, if you want a rainbow to wipe from one end to the other:

uint8_t speed = 30; // 30 beats per minute, or one cycle every two seconds
for (uint8_t i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(xCoords[i] + beat8(speed), 255, 255);
}

If you have multiple led arrays, just loop through each one. If you want it to run the other direction, just subtract the beat instead of adding. Adjust the speed from 30 to slow down or speed up the wipe.

I may be asking my question the wrong way. I thought it was best to have a single array so that animations like the juggle animation could go all the way from one end of the set of strings to another. I don’t understand how to add the strings to the array, when the order of the led’s is reversed. Some of my strings go left to right, some go right to left.

Correct, but in your case, IIUC, you want to have a pixel that moves left to right, and when it reaches a fork it follows both strips. To achieve that, you can do the following:

  1. create an array per string. in your case (numbers are random’ish): yellow(50), red(30), green(30), blue(50), pink(20), orange(30): 6 arrays.
  2. count the number of positions: say a single pixel going from left to right would jump a total of 200 positions.
  3. create function that defines a mapping for a certain direction: a pixel going from left to right would do first the 50 yellow pixels, then a subset of only the red, then a subset of the reds and a subset of the greens, then a subset of the greens, and a subset of the greens and a subset of the blues, then a subset of the blues, then the pinks and then the oranges.

void leftToRight(int pos, CRGB color) {
// position along the yellow string
if (pos < 50) {
// the yellow strip is inverted, so the first pixel is the last on the strip
// we do a mapping: for a value of pos the range 0-49 becomes 49-0
int posInStrip = map(pos, 0, 49, 49, 0);
leds1[posInStrip] = color;
}
// position in the initial part of the red strip
if (pos => 50 && pos < 70) {
int posInStrip = map(pos, 50, 69, 19, 0)
leds2[posInStrip] = color;
}
if (pos => 70 && pos < 80) {
// at this point the pixel splits following the red and the green,
// so we have to do 2 mappings
int posInStrip = map(pos, 70, 79, 29, 20)
leds2[posInStrip] = color;
int posInStrip = map(pos, 70, 79, 0, 9)
leds3[posInStrip] = color;
}
}

This function is only for left to right, as if we want to do right to left with a similar splitting effect that follows the strips, you have to do a different mapping.

As an example of how my code works in practice, a video:

I thought there would be a way to define them so that existing animation functions like fill_rainbow, would ‘just work’. Thanks for sharing this example.

I forgot to mention, you can slow down the video to see the actual effect.

And you can wrap that function with a

for (int i = 0; i<200;i++) {
color = SomeFunction(i); // use a fill rainbow type of function
leftToRight(i, color);
}

I am in the process of cleaning up the code and make it more readable. I will let you know when it is ready.

Rodger
I am looking at doing the same thing but with led strips. How did you use the 12v led with a 5 volt pin out of the arduino? Sorry I am new to this.
Thanks

@Joe_Ebert The strips have two separate sets of wires. One set is to power the LED’s (12v in my case), the other set is to control them (I used a 5v Trinket Pro). The strips to share a (-) wire, but the (+) are separate. Upload a clear closeup of the end of your strip with the arrow pointing away, and we (this community) can tell you how to wire them.

Thank You Roger. I was thinking of going to the Arduino mega thinking i would need that to handle 4 @ 12’ long led strips (approx 110 pixel per strip). But you have more that that and handling it with the Trinket… I was thinking that the 12v would help with voltage loss in the length but dont really see the led strips available in 12v any way… But in your case you have a power supply in 12v for the pixels sharing the (-) with a power supply of 5v feeding the trinket??

Thank you

A Tip Roger, as I have several “Lights” also running from the same board, all addressed unique sets of pixels which have the ability to interact with eachother,

I’ve just concatenated all lights to run from one single array, using the number of LEDs in that light, plus the number of leds in each of the previous lights as a seperator.

const int num_lights_connected = 3;

const int leds_a_num = 176;
const int leds_a_pin = 12;
const int leds_a_start = 0;

const int leds_b_num = 4;
const int leds_b_pin = 11;
const int leds_b_start = leds_a_num;

const int leds_c_num = 40;
const int leds_c_pin = 10;
const int leds_c_start = leds_b_start + leds_b_num;

const int num_leds_connected = leds_a_num + leds_b_num + leds_c_num;

CRGB leds[num_leds_connected];

then to run each addLeds,

FastLED.addLeds<NEOPIXEL, leds_a_pin>(leds,leds_a_start,leds_a_num);

FastLED.addLeds<NEOPIXEL, leds_b_pin>(leds,leds_b_start,leds_b_num);

FastLED.addLeds<NEOPIXEL, leds_c_pin>(leds,leds_c_start,leds_c_num);

This is an example of 220 LEDs, but they’re all part of the same array, in order to reverse some of the strips you will need to introduce some of Jesus’ code too.

Hope this helps, I’m no expert, just sharing in case it helps :slight_smile: