[Résolu] Problème de transition entre modules LED WS2812B (PCB DIY)

Salut à tous,

Je me tourne vers vous car j'ai débuté un projet il y a deux ans (avant la naissance de ma fille) pour créer un compteur d’abonnés YouTube.

À l'époque, j’ai sorti mes deux neurones dédiés à l’électronique (et encore, pas sûr d’en avoir deux pour ça :sweat_smile:), mais miraculeusement, j’ai réussi à créer mes propres modules de LED WS2812B.

:wrench: Mon projet de module est en images ci-jointes.



Schéma-ModuleLED
tracés-PCB-Module-Led

ATTENTION : J’ai inversé la sérigraphie des bornes 5V et GND (erreur de fabrication :face_with_peeking_eye:) mais c'est juste une erreur de sérigraphie pas de circuiterie.

Je voulais calquer le fonctionnement de mes modules sur celui des rubans de LED WS2812B classiques, avec la possibilité d'assembler plusieurs modules en série.

:point_right: Détail des modules :

Chaque module contient 16 LEDs WS2812B 5050
Chaque Led est précédé d'un condensateur entre le +5v et le Gnd.
Les modules sont connectables en série (DOUT → DIN)
L’alimentation est en 5V

:pushpin: Mon problème :

Maintenant que je suis devenu un papa bidouilleur, j’ai enfin décidé de finaliser mon projet.
J’ai donc investi dans un ESP32 D1 Mini Live (WiFi + Bluetooth) pour la partie logicielle.

Mais… rien ne fonctionne comme prévu ! :sob:
:point_right: La 16e LED de chaque module s’allume en même temps que la 1ère du module suivant.
:point_right: Elles se comportent comme si elles étaient jumelées !
:mag: Ce que j’ai déjà testé :

Avant de venir ici, j’ai essayé plusieurs solutions avec l’aide de mon cher ami ChatGPT (20€/mois :laughing:) :

:heavy_check_mark: Ajout d’une résistance de 300Ω puis 470Ω sur la ligne DATA
:heavy_check_mark: Ajout d’un condensateur de 0.1µF (104) sur l’alimentation
:heavy_check_mark: Vérification des connexions GND et 5V
:heavy_check_mark: Test avec un simple ruban LED WS2812B → Aucun problème
:heavy_check_mark: Modification du délai de reset (FastLED et Adafruit NeoPixel testés)
:heavy_check_mark: Utilisation d’un code de test simple pour voir le comportement des modules

Voici le code de base que j’ai utilisé pour tester mes modules et observer le problème :

#include <Adafruit_NeoPixel.h>

#define LED_PIN     16      // Broche utilisée pour le signal DATA des LEDs
#define NUM_LEDS    50      // 5 modules de 10 LEDs chacun
#define BRIGHTNESS  100     // Luminosité (0-255)

Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
    Serial.begin(115200);
    Serial.println("Démarrage du test LEDs WS2812B-B !");
    
    strip.begin();
    strip.setBrightness(BRIGHTNESS);
    strip.show(); // Éteint toutes les LEDs au démarrage

    delayMicroseconds(1000); // Pause plus longue pour WS2812B-B
}

void loop() {
    Serial.println("Mode 1: Remplissage Rouge Lent");
    clearLeds();
    testLeds(strip.Color(255, 0, 0), 1000); // 🔹 Lent
    delay(2000);

    Serial.println("Mode 2: Clignotement Bleu");
    clearLeds();
    blinkLeds(strip.Color(0, 0, 255));
    delay(2000);

    Serial.println("Mode 3: Arc-en-ciel");
    clearLeds();
    rainbowEffect();
    delay(2000);
}

// Fonction pour éteindre toutes les LEDs
void clearLeds() {
    strip.clear();
    strip.show();
    delayMicroseconds(1000); // Pause plus longue
}

// Fonction pour allumer les LEDs progressivement (lentement ou rapidement)
void testLeds(uint32_t color, int vitesse) {
    for(int i = 0; i < NUM_LEDS; i++) {
        strip.setPixelColor(i, color);
        strip.show();
        delay(vitesse);
    }
    delay(500);
}

// Fonction pour faire clignoter les LEDs
void blinkLeds(uint32_t color) {
    for(int j = 0; j < 5; j++) {
        for(int i = 0; i < NUM_LEDS; i++) {
            strip.setPixelColor(i, color);
        }
        strip.show();
        delay(500);

        clearLeds();
        delay(500);
    }
}

// Effet arc-en-ciel sur 50 LEDs
void rainbowEffect() {
    for(int k = 0; k < 256; k++) {
        for(int i = 0; i < NUM_LEDS; i++) {
            int hue = (i * 256 / NUM_LEDS) + k;
            strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(hue)));
        }
        strip.show();
        delay(50);  // Ajuste ici pour ralentir ou accélérer l'effet arc-en-ciel
    }
}

:face_with_monocle: Ce que j’observe avec ce code

Quand je teste ce code, la 16e LED de chaque module s’allume en même temps que la 1ère du module suivant.
Même si je ne demande pas d’allumer le second module, sa première LED réagit comme si elle était "liée" à la dernière du précédent.

J'ai dû essayer une trentaine de code différents, avec des modifications de timing, de rafraichissement, des modifications de comptages des leds et même en codant comme s'il s'agissait d'une seule et même bande led ... bref (et j'en passe) mais rien n'y fait. Je suppose donc que c'est un problème matériel ???

:bulb: Hypothèses possibles selon chat GPT :

:pushpin: Problème de conception de mes modules (mauvais routage du signal DATA ?)
:pushpin: Erreur dans le buffer interne des WS2812B ?
:pushpin: Niveau logique trop faible pour transmettre correctement le signal entre les modules ?
:pushpin: Besoin d’un buffer logique type 74AHCT125 pour amplifier le signal DATA ?

Si quelqu’un a déjà rencontré ce type de problème avec des modules LED WS2812B personnalisés, je suis preneur de vos conseils.
Je suis quasiment sûr que la solution est simple, mais je ne trouve pas ce qui cloche dans ma conception.

Merci d’avance à tous pour votre aide ! :raised_hands:

Nicolas

Bonsoir @mikolah

la Data Sheet des WS1812 indique qu , pour que le fonctionnement soit garanti Din ne doit pas descendre plus bas que 0,7 * la tension d'alimentation , soit 3,5V dans ton cas

La condition n'est pas remplie en sortie d'un GPIO d'ESP32, le niveau haut est un poil en dessous de 3,3V., du moins pour le DIN de la première LED. Le fonctionnement n'est donc pas garanti
(ça rejoint les deux dernières hypothèses de ton I.A)

Peux tu tester avec une carte UNO ou autre fonctionnant sous 5V et non 3,3V ?

Ce n'est pas très net mais il me semble que ce n'est pas le Dout de la dernière LEDs que tu propages vers le module suivant.
Dans le schéma, le Dout de LED16 n'est pas connecté.
Dans le typon, on ne peut pas faire un zoom sur l'image mais j'ai l'impression que c'est Din qui est propagé et pas Dout.

oui , c'est le DOUT de la 15e LED (= DIN de la 16e) qui est propagé

la 16e LED d'un module est donc en // avec la 1ere du suivant ,
elles reçoivent la même choses sur leurs DIN

Et voilà comment une petite bêtise peut coûter Cher :man_facepalming:t3:.

Merci 1000 fois à vous deux pour votre aide. :tada:Je ne sais pas si c'est réparable ou s'il faut que je re-commande des PCB. Mais en tout cas je vous remercie encore :clap:t3::clap:t3::clap:t3:.

C'est juste une piste à couper et un fil à tirer.
C'est l'affaire de quelques minutes par carte.


Si j'avais un conseil à donner, si tu devais refaire des cartes, il faudrait grossir les pistes d'alimentation car en l'état tu ne pourras pas cascader beaucoup d'afficheurs car il y a aura une bonne chute de tension à travers chaque carte. Une carte qui affiche un 0 en blanc va consommer dans les 500mA et tes pistes d'alimentation sont très fines. Tu devrais exploiter mieux le fait que c'est du double faces.

Ah ok je vois, je vais essayer de faire ça pour rétablir la connexion​:ok_hand:t2::smiling_face:

Et pour les pistes je te remercie du conseil ! J'anticiperai ça dans mes prochains PCB.

Pour aller plus loin, existe-t-il du coup une formule qui permette de calculer la largeur optimale des pistes selon l'épaisseur et la tension appliquée ?

Et sinon est ce qu'une piste trop large peut aussi être problématique à l'inverse ou pas du tout ? (Je pose la question juste pas curiosité )

Les leds sont alimentées en puissance par la borne VCC 5v de ma carte. Mais je n'avais pas songé au fait que la data du GPIO32 etait en 3v3 :thinking:.

Oui, voir ici :

Il y en a d’autres sur le net

Non.

Le mieux serait de:

  • router les Din et Dout au plus court pour ne pas créer de blocage pour la suite du routage.
  • remplir la face supérieure avec le GND.
  • router le Vcc dans l'espace libre sur l'autre face.

Avec ce genre de modules il vaut mieux avoir un maximum de surface pour le GND et le VCC pour 2 raisons:

  • tu ne sais pas à priori combien de modules tu seras amené à cascader dans le futur.
  • la surface de cuivre aidera à dissiper la chaleur des LEDs

Merci EGT59 je vais potasser ça pour ma V2, va vraiment falloir que j'approfondisse mes connaissances👌🏻.

Et pour définitivement valider la résolution de mon problème de data, @fdufnews, @al1fch,voici le résultat après "dérivation" de la data mal desservie :

Résultat.

:clap:t3::tada:

Et bah top ! Je vais recommencer mon prototype en partant de ton conseil. Une face Vcc pleine (avec juste les séparations des pistes data. Et la face dos, avec le GND. Effectivement ça a l'air Parfait comme solution. MERCI :smiling_face:

Je viendrai poster le Typon ici afin de pas me soulager bêtement de 55€ pour un produit mal conçu :sweat_smile:.