Miroir LED infinie avec des PL9823 programmable

Bonjours a tous!

j'ai comme projet de faire un programme pour mon miroir LED infinie, malheureusement je m'y connais pas vraiment en programmation de LED surtout avec ces LED (PL9823) où je n'ai pas trouvé beaucoup de tutos sur internet. j'ai trouvé ce programme dans la partie exemple de la bibliothèque Fastled.

#include <FastLED.h>

#define LED_PIN  3

#define COLOR_ORDER GRB
#define CHIPSET     WS2811

#define BRIGHTNESS 64

// Helper functions for an two-dimensional XY matrix of pixels.
// Simple 2-D demo code is included as well.
//
//     XY(x,y) takes x and y coordinates and returns an LED index number,
//             for use like this:  leds[ XY(x,y) ] == CRGB::Red;
//             No error checking is performed on the ranges of x and y.
//
//     XYsafe(x,y) takes x and y coordinates and returns an LED index number,
//             for use like this:  leds[ XY(x,y) ] == CRGB::Red;
//             Error checking IS performed on the ranges of x and y, and an
//             index of "-1" is returned.  Special instructions below
//             explain how to use this without having to do your own error
//             checking every time you use this function.  
//             This is a slightly more advanced technique, and 
//             it REQUIRES SPECIAL ADDITIONAL setup, described below.


// Params for width and height
const uint8_t kMatrixWidth = 16;
const uint8_t kMatrixHeight = 16;

// Param for different pixel layouts
const bool    kMatrixSerpentineLayout = false;
// Set 'kMatrixSerpentineLayout' to false if your pixels are 
// laid out all running the same way, like this:
//
//     0 >  1 >  2 >  3 >  4
//                         |
//     .----<----<----<----'
//     |
//     5 >  6 >  7 >  8 >  9
//                         |
//     .----<----<----<----'
//     |
//    10 > 11 > 12 > 13 > 14
//                         |
//     .----<----<----<----'
//     |
//    15 > 16 > 17 > 18 > 19
//
// Set 'kMatrixSerpentineLayout' to true if your pixels are 
// laid out back-and-forth, like this:
//
//     0 >  1 >  2 >  3 >  4
//                         |
//                         |
//     9 <  8 <  7 <  6 <  5
//     |
//     |
//    10 > 11 > 12 > 13 > 14
//                        |
//                        |
//    19 < 18 < 17 < 16 < 15
//
// Bonus vocabulary word: anything that goes one way 
// in one row, and then backwards in the next row, and so on
// is call "boustrophedon", meaning "as the ox plows."


// This function will return the right 'led index number' for 
// a given set of X and Y coordinates on your matrix.  
// IT DOES NOT CHECK THE COORDINATE BOUNDARIES.  
// That's up to you.  Don't pass it bogus values.
//
// Use the "XY" function like this:
//
//    for( uint8_t x = 0; x < kMatrixWidth; x++) {
//      for( uint8_t y = 0; y < kMatrixHeight; y++) {
//      
//        // Here's the x, y to 'led index' in action: 
//        leds[ XY( x, y) ] = CHSV( random8(), 255, 255);
//      
//      }
//    }
//
//
uint16_t XY( uint8_t x, uint8_t y)
{
  uint16_t i;
  
  if( kMatrixSerpentineLayout == false) {
    i = (y * kMatrixWidth) + x;
  }

  if( kMatrixSerpentineLayout == true) {
    if( y & 0x01) {
      // Odd rows run backwards
      uint8_t reverseX = (kMatrixWidth - 1) - x;
      i = (y * kMatrixWidth) + reverseX;
    } else {
      // Even rows run forwards
      i = (y * kMatrixWidth) + x;
    }
  }
  
  return i;
}


// Once you've gotten the basics working (AND NOT UNTIL THEN!)
// here's a helpful technique that can be tricky to set up, but 
// then helps you avoid the needs for sprinkling array-bound-checking
// throughout your code.
//
// It requires a careful attention to get it set up correctly, but
// can potentially make your code smaller and faster.
//
// Suppose you have an 8 x 5 matrix of 40 LEDs.  Normally, you'd
// delcare your leds array like this:
//    CRGB leds[40];
// But instead of that, declare an LED buffer with one extra pixel in
// it, "leds_plus_safety_pixel".  Then declare "leds" as a pointer to
// that array, but starting with the 2nd element (id=1) of that array: 
//    CRGB leds_with_safety_pixel[41];
//    const CRGB* leds( leds_plus_safety_pixel + 1);
// Then you use the "leds" array as you normally would.
// Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]",
// AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0].
// leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel".
//
// Now instead of using the XY function above, use the one below, "XYsafe".
//
// If the X and Y values are 'in bounds', this function will return an index
// into the visible led array, same as "XY" does.
// HOWEVER -- and this is the trick -- if the X or Y values
// are out of bounds, this function will return an index of -1.
// And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0],
// it's a totally safe and legal place to access.  And since the 'safety pixel'
// falls 'outside' the visible part of the LED array, anything you write 
// there is hidden from view automatically.
// Thus, this line of code is totally safe, regardless of the actual size of
// your matrix:
//    leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255);
//
// The only catch here is that while this makes it safe to read from and
// write to 'any pixel', there's really only ONE 'safety pixel'.  No matter
// what out-of-bounds coordinates you write to, you'll really be writing to
// that one safety pixel.  And if you try to READ from the safety pixel,
// you'll read whatever was written there last, reglardless of what coordinates
// were supplied.

#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
CRGB* leds( leds_plus_safety_pixel + 1);

uint16_t XYsafe( uint8_t x, uint8_t y)
{
  if( x >= kMatrixWidth) return -1;
  if( y >= kMatrixHeight) return -1;
  return XY(x,y);
}


// Demo that USES "XY" follows code below

void loop()
{
    uint32_t ms = millis();
    int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth));
    int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight));
    DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);
    if( ms < 5000 ) {
      FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));
    } else {
      FastLED.setBrightness(BRIGHTNESS);
    }
    FastLED.show();
}

void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
{
  byte lineStartHue = startHue8;
  for( byte y = 0; y < kMatrixHeight; y++) {
    lineStartHue += yHueDelta8;
    byte pixelHue = lineStartHue;      
    for( byte x = 0; x < kMatrixWidth; x++) {
      pixelHue += xHueDelta8;
      leds[ XY(x, y)]  = CHSV( pixelHue, 255, 255);
    }
  }
}


void setup() {
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  FastLED.setBrightness( BRIGHTNESS );
}

j'ai essayer de le comprendre mais j'ai vraiment du mal et je voudrais moi même réaliser le programme ou au moins le personnaliser et le comprendre.
je voudrais faire un programme qui ressemblerai à celui ci : DIY Infinity Mirror - YouTube

on m'a d'ailleurs conseiller de faire une matrice à une seul ligne mais je ne trouve pas d'exemple sur internet.
j'ai besoin d'aide svp, je prend n'importe quoi comme des conseils, des sites pour m’améliorer ou même faire un skype xD
merci d'avoir lu !

Bienvenue,

Les PL9823 sont des clones de WS2812B, bien plus populaires sur Google :wink:

Je ne comprends pas bien ton problème.

on m'a d'ailleurs conseiller de faire une matrice à une seul ligne mais je ne trouve pas d'exemple sur internet.

Pourtant, juste au dessus tu met un code qui fait précisément cela. une matrice "logicielle", avec une seule série de leds. Ce code est simple, donc se pose la question de ton niveau en programmation. Comprends-tu parfaitement cet exemple au moins? Si non, il est peut être un peu tôt pour penser à des séquences plus complexes... bien que celles que l'on voit dans la vidéo soient très basiques, et ne nécessitent pas de matrice :wink:

guix:
Bienvenue,

Les PL9823 sont des clones de WS2812B, bien plus populaires sur Google :wink:

Je ne comprends pas bien ton problème.

Pourtant, juste au dessus tu met un code qui fait précisément cela. une matrice "logicielle", avec une seule série de leds. Ce code est simple, donc se pose la question de ton niveau en programmation. Comprends-tu parfaitement cet exemple au moins? Si non, il est peut être un peu tôt pour penser à des séquences plus complexes... bien que celles que l'on voit dans la vidéo soient très basiques, et ne nécessitent pas de matrice :wink:

merci de la réponse! je comprend l'exemple que tu m'as donné en général par exemple je sais que ce programme va faire allumer une LED en rouge pendant 500ms puis l'eteindre pendant 500ms ce qui va la faire clignoter. Mais je ne cache pas que m'on niveau en programmation arduino est très mauvais.

Le programme que j'ai posté et que tu trouves simple est très compliqué pour moi. j'aurais juste besoin que l'on me l'explique ou que l'on me donne une piste pour le comprendre. Ensuite tu dis que les programmes dans la vidéo ne nécessitent pas de matrice, je n'ai aucune idée de comment faire un tel programme et je n'arrive pas à trouver de bon tuto pour me l'expliquer.
j’espère que j'ai été un peu plus clair :wink:

Non désolé, ce n'est pas encore assez clair :slight_smile:

je comprend l'exemple que tu m'as donné en général [...]. Mais je ne cache pas que m'on niveau en programmation arduino est très mauvais.

Donc, à la question:

Comprends-tu parfaitement cet exemple au moins?

La réponse est non? Dans ce cas, sans vouloir te décourager, je pense que tu devrais commencer par lire des tutoriaux pour débutants en C++.

Je n'ai aucune idée de ce que tu comprends ou pas, donc pour t'expliquer le code, il faudrait que je t'explique d'abord ce qu'est un tableau, un pointeur, une classe, une structure, etc...

Je peux t'aider, mais à condition que tu expliques précisément ce que tu n'as pas vraiment compris dans l'exemple Blink. On reviendra à l'autre code, plus complexe (mais bien commenté... encore faut-il connaître l'anglais), par la suite :wink:

guix:
Je n'ai aucune idée de ce que tu comprends ou pas, donc pour t'expliquer le code, il faudrait que je t'explique d'abord ce qu'est un tableau, un pointeur, une classe, une structure, etc...

j'ai regardé sur le site du zero et c'est vrai que je comprends mieux. Maintenant la seul chose que je comprend pas c'est le CRGB devant. c'est une fonction ?

Après dans le programme de matrice je n'arrive pas a comprendre ceci kMatrixSerpentineLayout = false;
je ne sais pas si il faut le mettre en true ou en false alors que c'est expliqué. Mais lorsque je le change sur mon miroir LED rien ne change ( ce qui veut dire que ça ne change rien pour une ligne de LED?)

Maintenant la seul chose que je comprend pas c'est le CRGB devant

CRGB est une structure, qui définit des fonctions et variables permettant de représenter et modifier une couleur. Par exemple, la fonction fadeLightBy(), qui permet d'ajuster la luminosité de la couleur:

CRGB led;
led = CRGB::Blue;
led.fadeLightBy(128);

Si ça t'intéresse, la structure CRGB est déclarée ici, mais ne t'y attardes pas, ça devient cryptique et ça va t'embrouiller!

En ce qui concerne ton projet de miroir infini: pourquoi penses-tu avoir besoin d'une matrice? Ce n'est pas le cas si ton miroir est comme dans la vidéo, avec une ligne de leds en série, en forme de cercle.

Une matrice est utile pour faire un quadrillage, afin d'y afficher des caractères ou des images, et ce "programme de matrice" est utile seulement si on veut disposer une ligne de leds en série, en forme de serpentin, de façon à former un quadrillage.

Fais voir à quoi ressemble ton miroir afin de dissiper toute confusion :slight_smile:

Ok merci beaucoup je comprend mieux ! c’était mon professeur d'option qui m'a dit ça mais j'ai l'impression qu'il n'en sait pas plus que moi :wink:

guix:
Une matrice est utile pour faire un quadrillage, afin d'y afficher des caractères ou des images, et ce "programme de matrice" est utile seulement si on veut disposer une ligne de leds en série, en forme de serpentin, de façon à former un quadrillage.

En effet mon miroir et exactement le même que celui sur la vidéo (je n'ai juste pas encore mis les miroirs)
donc je pense oubliée les matrices si ce n'est pas indispensable :wink:

Par contre je ne voit pas par où commencer pour faire un programme comme dans la vidéo. tous les exemples que je trouve sont avec des LEDs RGB classique et non avec les miennes :slightly_frowning_face:

void loop() {

   for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
    
      leds[whiteLed] = CRGB::Green;

     
      FastLED.show();

      delay(100);
     
      leds[whiteLed] = CRGB::Black;
   }

j'ai réussi a trouver et à adapter ce programme qui fait tourner la couleur de LED en LED tout en éteignant les autres le problème c’est que sa marche pour le bleu et le vert met quand je met le rouge sur une certaine LED la moitié de mon miroir s'allume ça vient de mon miroir ou du programme ? (en sachant que je comprendrait pas pourquoi ça vient du programme.) merci! :slight_smile:

Peut-être un problème sur la ligne FastLED.addLeds? Voilà à quoi elle devrait ressembler:

FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);

guix:
Peut-être un problème sur la ligne FastLED.addLeds? Voilà à quoi elle devrait ressembler:

FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);

Ah oui en effet j'ai mis ceci a la place

 FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);

et sa va mieux il reste juste une LED qui bug qui devient rouge soit ne s'allume pas soit devient vert soit tout ce passe normalement c'est bizarre moi sa doit être un bug de cette LED

Sinon je sais que je peux faire en sorte de choisir une couleur de LED avec le nombre de pixel (quelque chose comme ça pour avoir la couleur rouge) mais ça ne marche pas et je ne sais pas quelle ligne de code il faut mettre pour que ça marche, en sorte que je puisse nuancer les couleurs pour faire du violet, du orange etc...)

leds[whiteLed] = CRGB::(255,0,0);

Ces leds sont très sensibles et fragiles. il leur faut une tension bien stable de 5V, et il est recommandé de mettre un condensateur de découplage de 1000 uF. J'ai eu récemment une led qui n'affichait plus de bleu après avoir été un peu trop chauffée avec mon fer à souder, et il peut arriver qu'une led toute neuve ne fonctionne pas correctement, ou pas du tout. Elles sont pratiques mais loin d'être parfaites.

On peut utiliser CRGB comme une fonction.

led = CRGB(255,0,0);

Si tu veux nuancer des couleurs, regardes l'exemple ColorPalette :slight_smile:

guix:
Ces leds sont très sensibles et fragiles. il leur faut une tension bien stable de 5V, et il est recommandé de mettre un condensateur de découplage de 1000 uF. J'ai eu récemment une led qui n'affichait plus de bleu après avoir été un peu trop chauffée avec mon fer à souder, et il peut arriver qu'une led toute neuve ne fonctionne pas correctement, ou pas du tout. Elles sont pratiques mais loin d'être parfaites.

On peut utiliser CRGB comme une fonction.

led = CRGB(255,0,0);

Si tu veux nuancer des couleurs, regardes l'exemple ColorPalette :slight_smile:

Merci j'ai quasiment achevé mon programme il me reste juste un problème: comment faire pour faire enchaîner plusieurs programme qui tiendront par exemple 1min. ( c'est à dire faire un peu comme la vidéo mais en changent de programme) ex: le début allumer tout en rouge puis ensuite tout en bleu puis ensuite tout en vert, ensuite faire allumer les LED une par une puis accélérer la vitesse puis faire allumer les couleur au hasard et ainsi de suite :slight_smile:
Tous ces programmes je sais les faire individuellement mais les assembler en disant je met ce programme 10 sec puis celui la 5 sec je ne sais pas comment m'y prendre pour mettre le tout dans la carte arduino. :wink:

Je n'ai toujours pas trouvé le programme ne veux pas ce lancer.... :confused:

As-tu essayé et regardé le code de l'exemple ColorPalette ? Il fait à peu près ce que tu veux.

FastLED/examples/ColorPalette/ColorPalette.ino at master · FastLED/FastLED · GitHub.

Sers-toi de cet exemple comme base pour ton programme.

le début allumer tout en rouge puis ensuite tout en bleu puis ensuite tout en vert

C'est pourtant pas compliqué. Il suffit d'une boucle qui assigne la couleur à chaque led, et pour patienter jusqu'au prochain changement de couleur, tu peux mettre un delay(). Personnellement j'utilise une méthode un peu plus complexe, dite non bloquante (voir l'exemple Arduino "Blink Without Delay") qui permet à l'arduino de ne pas se tourner les puces pendant un delay :). Mais pour faire simple pour l'instant, utilise un delay.

for ( uint8_t i = 0; i < NUM_LEDS; i++ )
    leds[i] = CRGB::Red;
FastLED.show();
FastLED.delay(10000UL);

for ( uint8_t i = 0; i < NUM_LEDS; i++ )
    leds[i] = CRGB::Blue;
FastLED.show();
FastLED.delay(10000UL);

for ( uint8_t i = 0; i < NUM_LEDS; i++ )
    leds[i] = CRGB::Green;
FastLED.show();
FastLED.delay(10000UL);