Diviser un strip led en plusieurs sections

Bonjour à tous,
J'utilise FastLed pour éclairer un strip de 144 leds via un Arduino Nano.
J'aimerais le diviser en 3 sections allumées simultanément, les deux premières avec les exemples animés "Pacifica" et "Fire2012" de FastLed et la dernière avec une couleur fixe.
J'ai fait des recherches sur CRGBSet, et j'arrive à diviser ma bande avec des couleurs fixes mais je ne parvient pas à y intégrer les exemples animées plus complexes.
Est-ce possible ? Est-ce que vous auriez une piste pour m'aiguiller ?
Merci d'avance.

Le plus simple est de couper ton ruban en trois.

Je le couperais par la suite en effet, mais ça m'obligerait à l'alimenter par un Arduino différent à chaque fois non ?

Non, tu peux déclarer 3 strips sur 3 IOs différents

Merci pour cette réponse, mais je ne sais pas ce que c'est.
iOs comme système d'exploitation ? Mon niveau en programmation n'est pas énorme.

Bonsoir kapout
Le plus simple, tu subdivises tes 144 LED en 3 segments logiques, ce qui te donnes 3 départs de segment: 0, 47 et 95.
Pour Pacifia
Début de la boucle for i = 0.
NUM_LEDS = 48

Pour Fire2012
NUM_LEDS = 48
Début de la boucle for i = 48

Dernier segment, départ à 95.

C'est pas essayé "en vrai" :wink:

Cordialement
jpbbricole

  • Tu coupes ta bande de LEDs en 3 (puisque de toutes les façons c'est ce que tu veux faire au final)
  • Tu les connectent sur 3 sorties différentes
  • Dans ton code (que tu ne donnes pas) tu déclares 3 tableaux de LEDs

Merci beaucoup pour vos réponses !
En effet, je suis obligé de découper et ressouder le strip en espaçant les bandes car les leds me servent à animer une crèche de Noël. Une rivière, un coin feu, l'éclairage des bâtiments, ...

Je me voyais mal copier le code de démo de la librairie sur lequel je viens simplement toucher les valeurs de couleurs, de luminosité et autre vitesse. Je vais l'ajouter du coup.

J'ai fait le test sur "Pacifica" en changeant la valeur de i sur les différentes occurrences comme tu me l'a indiqué jpbbricole mais ça ne décale pas la position des leds sur le strip. Je dois surement rater quelque chose.

Idéalement je voudrais pouvoir l'alimenter sur un seul usb car j'ai d'autres strips à brancher.

//
//  "Pacifica"
//  Gentle, blue-green ocean waves.
//  December 2019, Mark Kriegsman and Mary Corey March.
//  For Dan.
//

#define FASTLED_ALLOW_INTERRUPTS 0
#include <FastLED.h>
FASTLED_USING_NAMESPACE

#define DATA_PIN            3
#define NUM_LEDS            48
#define MAX_POWER_MILLIAMPS 500
#define LED_TYPE            WS2812B
#define COLOR_ORDER         GRB

//////////////////////////////////////////////////////////////////////////

CRGB leds[NUM_LEDS];

void setup() {
  delay( 3000); // 3 second delay for boot recovery, and a moment of silence
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS)
        .setCorrection( TypicalLEDStrip );
  FastLED.setMaxPowerInVoltsAndMilliamps( 5, MAX_POWER_MILLIAMPS);
}

void loop()
{
  EVERY_N_MILLISECONDS( 20) {
    pacifica_loop();
    FastLED.show();
  }
}

//////////////////////////////////////////////////////////////////////////
//
// The code for this animation is more complicated than other examples, and 
// while it is "ready to run", and documented in general, it is probably not 
// the best starting point for learning.  Nevertheless, it does illustrate some
// useful techniques.
//
//////////////////////////////////////////////////////////////////////////
//
// In this animation, there are four "layers" of waves of light.  
//
// Each layer moves independently, and each is scaled separately.
//
// All four wave layers are added together on top of each other, and then 
// another filter is applied that adds "whitecaps" of brightness where the 
// waves line up with each other more.  Finally, another pass is taken
// over the led array to 'deepen' (dim) the blues and greens.
//
// The speed and scale and motion each layer varies slowly within independent 
// hand-chosen ranges, which is why the code has a lot of low-speed 'beatsin8' functions
// with a lot of oddly specific numeric ranges.
//
// These three custom blue-green color palettes were inspired by the colors found in
// the waters off the southern coast of California, https://goo.gl/maps/QQgd97jjHesHZVxQ7
//
CRGBPalette16 pacifica_palette_1 = 
    { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, 
      0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 };
CRGBPalette16 pacifica_palette_2 = 
    { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, 
      0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F };
CRGBPalette16 pacifica_palette_3 = 
    { 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33, 
      0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF };


void pacifica_loop()
{
  // Increment the four "color index start" counters, one for each wave layer.
  // Each is incremented at a different speed, and the speeds vary over time.
  static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4;
  static uint32_t sLastms = 0;
  uint32_t ms = GET_MILLIS();
  uint32_t deltams = ms - sLastms;
  sLastms = ms;
  uint16_t speedfactor1 = beatsin16(3, 179, 269);
  uint16_t speedfactor2 = beatsin16(4, 179, 269);
  uint32_t deltams1 = (deltams * speedfactor1) / 256;
  uint32_t deltams2 = (deltams * speedfactor2) / 256;
  uint32_t deltams21 = (deltams1 + deltams2) / 2;
  sCIStart1 += (deltams1 * beatsin88(1011,10,13));
  sCIStart2 -= (deltams21 * beatsin88(777,8,11));
  sCIStart3 -= (deltams1 * beatsin88(501,5,7));
  sCIStart4 -= (deltams2 * beatsin88(257,4,6));

  // Clear out the LED array to a dim background blue-green
  fill_solid( leds, NUM_LEDS, CRGB( 2, 6, 10));

  // Render each of four layers, with different scales and speeds, that vary over time
  pacifica_one_layer( pacifica_palette_1, sCIStart1, beatsin16( 3, 11 * 256, 14 * 256), beatsin8( 10, 70, 130), 0-beat16( 301) );
  pacifica_one_layer( pacifica_palette_2, sCIStart2, beatsin16( 4,  6 * 256,  9 * 256), beatsin8( 17, 40,  80), beat16( 401) );
  pacifica_one_layer( pacifica_palette_3, sCIStart3, 6 * 256, beatsin8( 9, 10,38), 0-beat16(503));
  pacifica_one_layer( pacifica_palette_3, sCIStart4, 5 * 256, beatsin8( 8, 10,28), beat16(601));

  // Add brighter 'whitecaps' where the waves lines up more
  pacifica_add_whitecaps();

  // Deepen the blues and greens a bit
  pacifica_deepen_colors();
}

// Add one layer of waves into the led array
void pacifica_one_layer( CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff)
{
  uint16_t ci = cistart;
  uint16_t waveangle = ioff;
  uint16_t wavescale_half = (wavescale / 2) + 20;
  for( uint16_t i = 48; i < NUM_LEDS; i++) {
    waveangle += 250;
    uint16_t s16 = sin16( waveangle ) + 32768;
    uint16_t cs = scale16( s16 , wavescale_half ) + wavescale_half;
    ci += cs;
    uint16_t sindex16 = sin16( ci) + 32768;
    uint8_t sindex8 = scale16( sindex16, 240);
    CRGB c = ColorFromPalette( p, sindex8, bri, LINEARBLEND);
    leds[i] += c;
  }
}

// Add extra 'white' to areas where the four layers of light have lined up brightly
void pacifica_add_whitecaps()
{
  uint8_t basethreshold = beatsin8( 9, 55, 65);
  uint8_t wave = beat8( 7 );
  
  for( uint16_t i = 48; i < NUM_LEDS; i++) {
    uint8_t threshold = scale8( sin8( wave), 20) + basethreshold;
    wave += 7;
    uint8_t l = leds[i].getAverageLight();
    if( l > threshold) {
      uint8_t overage = l - threshold;
      uint8_t overage2 = qadd8( overage, overage);
      leds[i] += CRGB( overage, overage2, qadd8( overage2, overage2));
    }
  }
}

// Deepen the blues and greens
void pacifica_deepen_colors()
{
  for( uint16_t i = 48; i < NUM_LEDS; i++) {
    leds[i].blue = scale8( leds[i].blue,  145); 
    leds[i].green= scale8( leds[i].green, 200); 
    leds[i] |= CRGB( 2, 5, 7);
  }
}

#include <FastLED.h>

#define LED_PIN     3
#define COLOR_ORDER GRB
#define CHIPSET     WS2811
#define NUM_LEDS    144

#define BRIGHTNESS  200
#define FRAMES_PER_SECOND 60

bool gReverseDirection = false;

CRGB leds[NUM_LEDS];

void setup() {
  delay(3000); // sanity delay
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness( BRIGHTNESS );
}

void loop()
{
  // Add entropy to random number generator; we use a lot of it.
  // random16_add_entropy( random());

  Fire2012(); // run simulation frame
  
  FastLED.show(); // display this frame
  FastLED.delay(1000 / FRAMES_PER_SECOND);
}


// Fire2012 by Mark Kriegsman, July 2012
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
//// 
// This basic one-dimensional 'fire' simulation works roughly as follows:
// There's a underlying array of 'heat' cells, that model the temperature
// at each point along the line.  Every cycle through the simulation, 
// four steps are performed:
//  1) All cells cool down a little bit, losing heat to the air
//  2) The heat from each cell drifts 'up' and diffuses a little
//  3) Sometimes randomly new 'sparks' of heat are added at the bottom
//  4) The heat from each cell is rendered as a color into the leds array
//     The heat-to-color mapping uses a black-body radiation approximation.
//
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
//
// This simulation scales it self a bit depending on NUM_LEDS; it should look
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking. 
//
// I recommend running this simulation at anywhere from 30-100 frames per second,
// meaning an interframe delay of about 10-35 milliseconds.
//
// Looks best on a high-density LED setup (60+ pixels/meter).
//
//
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames.  More cooling = shorter flames.
// Default 50, suggested range 20-100 
#define COOLING  55

// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire.  Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
#define SPARKING 120


void Fire2012()
{
// Array of temperature readings at each simulation cell
  static uint8_t heat[NUM_LEDS];

  // Step 1.  Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
    }
  
    // Step 2.  Heat from each cell drifts 'up' and diffuses a little
    for( int k= NUM_LEDS - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
    }
    
    // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int y = random8(7);
      heat[y] = qadd8( heat[y], random8(160,255) );
    }

    // Step 4.  Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      CRGB color = HeatColor( heat[j]);
      int pixelnumber;
      if( gReverseDirection ) {
        pixelnumber = (NUM_LEDS-1) - j;
      } else {
        pixelnumber = j;
      }
      leds[pixelnumber] = color;
    }
}


C'est un peu contradictoire si on considère la consommation de 144 LEDs.
Une couleur d'une LED à fond c'est environ 20mA. Une LED allumé en blanc à fond c'est donc 60mA.
Même en admettant que tu n'utilises pas beaucoup le blanc et que les LEDs ne soient pas allumées au maximum, tu vas consommer plusieurs ampères. C'est plus que ce qu'un port USB peut fournir nativement.

Bonsoir, je ne suis pas certain d'utiliser l'ensemble des leds, surement dans les 90 seulement. En effet cela semble beaucoup au calcul, pourtant branché sur un petit bloc d'alimentation qui délivre du 5V - 2,5A l'ensemble du strip s'allume sans problème.

Je vais me renseigner sur les tableaux merci.
Au pire j'ai toujours la solution de mettre un Arduino par section, surtout si il vaut mieux que j'alimente moins de leds à chaque fois.

Je ne suis pas spécialiste des alimentations, mais je suppose que tes LED ne sont pas allumée à pleine puissance ?

Si tes animations sont complétement indépendante les unes des autres, tu peux passer par 3 Arduino(voir 3 esp8266 ou esp32), que tu pourra peut être plus tard contrôler via ton smartphone.

Désolé, je pense le contraire. Il me semble plus simple de n'utiliser qu'un seul Arduino et d'y connecter 3 rubans indépendants (comme disait @fdufnews). Ca se fait très bien avec FastLed.

Il suffit de déclarer 3 instances de FastLED, connectées chacune à une IO différente et ayant chacune son tableau de valeurs. Ensuite, tu attribues les animations comme tu le désires.

Pour la connectique, la référence se trouve ici : lis cette page et les suivantes. Le schéma de connexion d'un ruban est ceci :

Il te faut une résistance par ruban et une capa pour l'ensemble. Tu vois que l'alimentation est faite par une alim externe, elle alimente l'Arduino et les rubans (avec GND communs). Pour choisir la puissance de l'alimentation, tu prends le nombre total de leds, tu multiplies par 0.06 et tu obtiens les ampères nécessaire (au maximum d'illumination). Si tu es sûr que tu n'auras jamais toutes les leds allumées en blanc en même temps, tu peux diminuer cette valeur.

Pour 144 leds, ça te fait 144 * 0.06 = 8.64A, soit 10A en arrondissant.
Si tu penses que tu auras 50% des leds allumées en même temps (72 leds) et que aucune ne sera blanche (donc jamais les 3 composantes en même temps), tu peux diminuer ton budget : 72 * 0.04 = 2.88A soit 3A à fournir. Mais ce n'est qu'un exemple, tu dois faire ton calcul en fonction de ton besoin réel.

FastLed permet de fixer un courant max à ne pas dépasser. La valeur de la luminosité est ajustée en fonction de la puissance donnée comme limite.

et

http://fastled.io/docs/3.1/class_c_fast_l_e_d.html#ab07d62cdec036af9ede70cbd06ece40f

Je suppose que tu répond à mon commentaire?
Dans ce cas ne soit pas désolé, chacun voit midi à sa porte :slight_smile:
Peut tu développer car je ne vois pas en quoi c'est plus simple de gérer simultanément 3 animations, que de reproduire 3 fois le même montage avec le même programme à un valeur de variable près.
Sans parlais d'introduire un câble assez long pour chaque bande en fonction de la ou tu veux le mettre et d'avoir une alimentation 3 fois plus "grande"?

Oui, je pense que c'est plus cher et plus complexe de faire 3 sketches sur 3 hardwares différents, notamment pour la maintenance ou l'évolution du besoin. S'il faut en plus synchroniser les animations, ça devient trop compliqué.

Par contre, c'est vrai que si les 3 bandes sont éloignées, il risque d'y avoir d'autres problèmes liés aux pertes en ligne, mais si c'est pour mettre sur un sapin ou une crèche ça devrait aller.

Après, c'est juste un avis personnel...

Oui, on est d'accord au moins la dessus, cela reste que notre avis personnel et en aucune manière un jugement.
La bonne méthode reste celle qui nous convient le plus :slight_smile:
Après je ne dis pas que ça serait la solution que j'aurais privilégié personnellement.

Je n'ai jamais parlé de 3 sketches différents sur 3 hardwares au propriété différents.
Mais du même sketch sur 3 hardware identiques.
On peut imaginer un bouton switch à 3 état, pour sélectionner l'animation par exemple, si on ne veut pas le faire par programmation ou passer par le port série.

par contre si on veut par la suite synchroniser le tout, là ce n'est pas la même chose effectivement.
Mais on pourrait simplement pousser le programme un peu plus loin et passer par le dialogue avec un smartphone, pour changer l'animation ou certaine propriétés.

Merci pour toutes ces réponses. Pour la partie branchement électrique, il n'y a pas de problème.
Sur ce strip les leds sont toutes dans les bleues ou rouges, il n'y a donc que peu de blancs et à puissance réduite.
Vous avez tous l'air très calé mais autant je soude très bien et couper le strip pour mettre un condensateur ne me fait pas peur, autant la partie programmation pure je tâtonne ^^
Et quand vous me parlez d'IO différentes, dont Google ne me donne pas de résultat avec "io arduino" et de tableaux de valeurs je ne sais juste pas comment procéder.
Le mieux est sans doute de rester avec un Arduino Nano par couleur de strip, Je vais passer plus de temps à câbler mais ça ne sera pas forcément plus long que de devoir apprendre à coder mieux.

C'est pourtant pas compliqué.
Il suffit de regarder l'exemple Multiple/MultiArrays.ino qui est installé avec la librairie. Et en plus, pour le même prix, il fait le boulot pour toi puisque justement il gère 3 strips de LEDs.

Allez, ne vous plaignez pas et essayez le code suivant, c'est juste une question de toucher les boucles for et de les adapter à vos besoins.


#include <FastLED.h>

#define DATA_PIN            2
#define NUM_LEDS            144
#define LED_TYPE            WS2812B
#define COLOR_ORDER         GRB
#define BRIGHTNESS  50

#define FRAMES_PER_SECOND 60
#define START_FIRE 0
#define END_FIRE 48
bool gReverseDirection = false;

#define START_PACIFICA 48
#define END_PACIFICA 96
//////////////////////////////////////////////////////////////////////////

CRGB leds[NUM_LEDS];

void setup() {
  delay( 3000); // 3 second delay for boot recovery, and a moment of silence
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness( BRIGHTNESS );
}

void loop() {
  Fire2012();
  pacifica_loop();
  for (int  i = 96; i < 144; i++) {
    leds[i] = CRGB::Magenta;
  }
  FastLED.show();
}

CRGBPalette16 pacifica_palette_1 =
{ 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
  0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50
};
CRGBPalette16 pacifica_palette_2 =
{ 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
  0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F
};
CRGBPalette16 pacifica_palette_3 =
{ 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33,
  0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF
};


void pacifica_loop()
{
  // Increment the four "color index start" counters, one for each wave layer.
  // Each is incremented at a different speed, and the speeds vary over time.
  static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4;
  static uint32_t sLastms = 0;
  uint32_t ms = GET_MILLIS();
  uint32_t deltams = ms - sLastms;
  sLastms = ms;
  uint16_t speedfactor1 = beatsin16(3, 179, 269);
  uint16_t speedfactor2 = beatsin16(4, 179, 269);
  uint32_t deltams1 = (deltams * speedfactor1) / 256;
  uint32_t deltams2 = (deltams * speedfactor2) / 256;
  uint32_t deltams21 = (deltams1 + deltams2) / 2;
  sCIStart1 += (deltams1 * beatsin88(1011, 10, 13));
  sCIStart2 -= (deltams21 * beatsin88(777, 8, 11));
  sCIStart3 -= (deltams1 * beatsin88(501, 5, 7));
  sCIStart4 -= (deltams2 * beatsin88(257, 4, 6));

  // Clear out the LED array to a dim background blue-green
  //fill_solid( leds, END_PACIFICA, CRGB( 2, 6, 10));
  for (int  i = START_PACIFICA; i < END_PACIFICA; i++) {
    leds[i] = CRGB::Blue;
  }

  // Render each of four layers, with different scales and speeds, that vary over time
  pacifica_one_layer( pacifica_palette_1, sCIStart1, beatsin16( 3, 11 * 256, 14 * 256), beatsin8( 10, 70, 130), 0 - beat16( 301) );
  pacifica_one_layer( pacifica_palette_2, sCIStart2, beatsin16( 4,  6 * 256,  9 * 256), beatsin8( 17, 40,  80), beat16( 401) );
  pacifica_one_layer( pacifica_palette_3, sCIStart3, 6 * 256, beatsin8( 9, 10, 38), 0 - beat16(503));
  pacifica_one_layer( pacifica_palette_3, sCIStart4, 5 * 256, beatsin8( 8, 10, 28), beat16(601));

  // Add brighter 'whitecaps' where the waves lines up more
  pacifica_add_whitecaps();

  // Deepen the blues and greens a bit
  pacifica_deepen_colors();
}

// Add one layer of waves into the led array
void pacifica_one_layer( CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff)
{
  uint16_t ci = cistart;
  uint16_t waveangle = ioff;
  uint16_t wavescale_half = (wavescale / 2) + 20;
  for ( uint16_t i = START_PACIFICA; i < END_PACIFICA; i++) {
    waveangle += 250;
    uint16_t s16 = sin16( waveangle ) + 32768;
    uint16_t cs = scale16( s16 , wavescale_half ) + wavescale_half;
    ci += cs;
    uint16_t sindex16 = sin16( ci) + 32768;
    uint8_t sindex8 = scale16( sindex16, 240);
    CRGB c = ColorFromPalette( p, sindex8, bri, LINEARBLEND);
    leds[i] += c;
  }
}

// Add extra 'white' to areas where the four layers of light have lined up brightly
void pacifica_add_whitecaps()
{
  uint8_t basethreshold = beatsin8( 9, 55, 65);
  uint8_t wave = beat8( 7 );

  for ( uint16_t i = START_PACIFICA; i < END_PACIFICA; i++) {
    uint8_t threshold = scale8( sin8( wave), 20) + basethreshold;
    wave += 7;
    uint8_t l = leds[i].getAverageLight();
    if ( l > threshold) {
      uint8_t overage = l - threshold;
      uint8_t overage2 = qadd8( overage, overage);
      leds[i] += CRGB( overage, overage2, qadd8( overage2, overage2));
    }
  }
}

// Deepen the blues and greens
void pacifica_deepen_colors()
{
  for ( uint16_t i = START_PACIFICA; i < END_PACIFICA; i++) {
    leds[i].blue = scale8( leds[i].blue,  145);
    leds[i].green = scale8( leds[i].green, 200);
    leds[i] |= CRGB( 2, 5, 7);
  }
}

// Fire2012 by Mark Kriegsman, July 2012
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
////
// This basic one-dimensional 'fire' simulation works roughly as follows:
// There's a underlying array of 'heat' cells, that model the temperature
// at each point along the line.  Every cycle through the simulation,
// four steps are performed:
//  1) All cells cool down a little bit, losing heat to the air
//  2) The heat from each cell drifts 'up' and diffuses a little
//  3) Sometimes randomly new 'sparks' of heat are added at the bottom
//  4) The heat from each cell is rendered as a color into the leds array
//     The heat-to-color mapping uses a black-body radiation approximation.
//
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
//
// This simulation scales it self a bit depending on NUM_LEDS; it should look
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking.
//
// I recommend running this simulation at anywhere from 30-100 frames per second,
// meaning an interframe delay of about 10-35 milliseconds.
//
// Looks best on a high-density LED setup (60+ pixels/meter).
//
//
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames.  More cooling = shorter flames.
// Default 50, suggested range 20-100
#define COOLING  55

// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire.  Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
#define SPARKING 120


void Fire2012()
{
  FastLED.delay(1000 / FRAMES_PER_SECOND);
  // Array of temperature readings at each simulation cell
  static byte heat[NUM_LEDS];

  // Step 1.  Cool down every cell a little
  for ( int i = START_FIRE; i < END_FIRE; i++) {
    heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / (END_FIRE - START_FIRE)) + 2));
  }

  // Step 2.  Heat from each cell drifts 'up' and diffuses a little
  for ( int k = END_FIRE - 1; k >= 2; k--) {
    heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
  }

  // Step 3.  Randomly ignite new 'sparks' of heat near the bottom
  if ( random8() < SPARKING ) {
    int y = random8(7);
    heat[y] = qadd8( heat[y], random8(160, 255) );
  }

  // Step 4.  Map from heat cells to LED colors
  for ( int j = START_FIRE; j < END_FIRE; j++) {
    CRGB color = HeatColor( heat[j]);
    int pixelnumber;
    if ( gReverseDirection ) {
      pixelnumber = (NUM_LEDS - 1) - j;
    } else {
      pixelnumber = j;
    }
    leds[pixelnumber] = color;
  }
}

Comme vous pouvez le voir, ce sont les débuts et les fins de toutes les boucles "for" qui changent la position dans la bande.
salutations

Un grand merci gonpezzi ! C'est exactement ça marche incroyablement bien, c'est parfait.