Programme Driver led BD2808MUV-ME2

Bonjour, je cherche à contrôler un driver de led BD2808MUV-ME2 en utilisant la librairie SPI d'arduino. Je ne trouve pas de projet similaire, j'ai cru comprendre qu'il fallait utiliser la commande SPI.transfer(), pour s'adresser au périphérique voulu et lui envoyer la valeur du PWM que l'on souhaite mais je ne parviens pas à faire piloter mes leds. Est-ce que quelqu'un a eu l'occasion de travailler sur un projet similaire ?

Ci-dessous une image de la "register map" fournie dans la datasheet du BD2808MUV-ME2

Merci d'avance

à titre indication, voici mon programme développé sur l'arduino IDE:

#include <SPI.h>

#define PIN_CS 10

void setup() {

pinMode(PIN_CS, OUTPUT);

digitalWrite(PIN_CS, HIGH);

SPI.begin();

// Commence la transaction SPI avec : 500 kHz, MSB first, SPI mode 0
SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));

// Données à envoyer
sendToBD2808(0x06, 0b11111111); // OUTR0
sendToBD2808(0x07, 0b11111111); // OUTG0
sendToBD2808(0x08, 0b11111111); // OUTB0

// Latch
sendToBD2808(0x1E, 0x01);

// Fin de la transaction SPI
SPI.endTransaction();
}

void loop() {
}

void sendToBD2808(uint8_t address, uint8_t value) {
digitalWrite(PIN_CS, LOW);
SPI.transfer(address);
SPI.transfer(value);
digitalWrite(PIN_CS, HIGH);
}

Merci de prendre quelques minutes pour lire "Les bonnes pratiques du forum francophone" et les appliquer.

En particulier, la mise en forme du code avec des balises en cliquant sur l'icône <code/>

A noter, pas la peine de faire un nouveau message avec le code entre balise. Tu peux éditer le message en question (clique sur le petit crayon sous le message) et y ajouter les balises.

Tu as malheureusement oublié de mettre ton code entre balise < code>, comme indiqué dans les bonnes pratiques :slight_smile:

On attend que tu présentes ton code correctement pour aller plus loin mais je peux déjà te recommander de lire la datasheet du composant dans le détail cela te fera gagner du temps.

Bonjour,

Je vous présente mes excuses pour la lisibilité du code, je reposte une seconde version avec la mise en page demandée.

#include <SPI.h>

#define PIN_CS 10


void setup() {

  pinMode(PIN_CS, OUTPUT);

  digitalWrite(PIN_CS, HIGH);


  SPI.begin();

  // Commence la transaction SPI avec : 500 kHz, MSB first, SPI mode 0
  SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));

  // Données à envoyer
  sendToBD2808(0x06, 0b11111111);  // OUTR0
  sendToBD2808(0x07, 0b11111111);  // OUTG0
  sendToBD2808(0x08, 0b11111111);  // OUTB0

  // Latch
  sendToBD2808(0x1E, 0x01);

  // Fin de la transaction SPI
  SPI.endTransaction();
}

void loop() {
}

void sendToBD2808(uint8_t address, uint8_t value) {
  digitalWrite(PIN_CS, LOW);
  SPI.transfer(address);
  SPI.transfer(value);
  digitalWrite(PIN_CS, HIGH);
}

J'ai étudié la datasheet de ce composant mais je programme en utilisant la librairie SPI pour la première fois. J'ai rédigé ce programme afin d'allumer une led rgb à partir des informations que j'ai pu relever dans la datasheet. Je cherche à envoyer 3 paquets de 8 bits pour régler la valeur des signaux PWM à 255 aux adresses des leds 0x06, 0x07 et 0x08 (led R0, G0, B0).

Merci beaucoup.

Sans doute pas suffisamment.
Il ne suffit pas d'envoyer RGB pour que cela fonctionne. Il y a un protocole à respecter voir les pages 12 et 13 de la datasheet.
il faut envoyer :

  • une suite de "1" pour sortir le(s) BD2808MUV-ME2 de veille.
  • envoyer l'adresse du BD2808MUV-ME2 dans lequel tu veux écrire
  • envoyer l'adresse du registre auquel tu veux accéder
  • envoyer la (ou les) donnée(s). Tu peux écrire une série de données dans des registres consécutifs car l'adresse s'incrémente automatiquement.
  • envoyer une suite de "1" pour remettre le BD2808MUV-ME2 en veille.

Merci pour votre retour, je vous joins les modifications apportées au code avec les commentaires

#include <SPI.h>

#define PIN_CS 10


void setup() {

  pinMode(PIN_CS, OUTPUT);
  digitalWrite(PIN_CS, HIGH); //CS au repos


  SPI.begin();
  SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0)); // Commence la transaction SPI avec : 500 kHz, MSB first, SPI mode 0
  
  SPI.transfer(0xFF); // "réveil" du driver
  SPI.transfer(0xFF); // "réveil" du driver
  
  
  
  
  digitalWrite(PIN_CS, LOW); // Active la communication SPI (sélectionne le device)
  SPI.transfer(0x00); // adresse du BD2808, les pads A0 à A5 sont connectés à la masse
  SPI.transfer(0x06); //register adress led R0
  SPI.transfer(0xEE); //data envoyée à R0
  SPI.transfer(0xEE); //data envoyée à G0 (incrémentation automatique)
  SPI.transfer(0xEE); //data envoyée à B0 (incrémentation automatique)

  SPI.transfer(0xFF); //mise en veille du driver
  digitalWrite(PIN_CS, HIGH); //CS au repos

  SPI.endTransaction(); // Fin de la transaction SPI

  
}

void loop() {
}


Ce code ne fonctionne pas non plus. Je continue à étudier la datasheet et enverrai une nouvelle version si je parviens à obtenir un résultat

Je n'ai pas vu de CS sur la datasheet du composant.
A ne pas confondre avec l'Output Enable (OE) qui déactive les sorties.


Par défaut, le registre 02h est dans le mode "Brightness register is latched on edge of EN " ce qui veut dire que le circuit attend une écriture dans le registre 1Eh pour valider les changements, ce qui permet un changement de toutes les LEDs au même instant.

Le CS correpondait à la broche Chip Select de l'arduino mais je pense que sa gestion se fait par les commandes SPI.

J'ai voulu apporter des modifications en suivant l'ordre des commandes en page 13. J'ai aussi fixé un courant maximal sur les canaux R avec le registre 03h et écrit un bit à 1 dans le registre 1Eh pour autoriser les changements... sans succès.

#include <SPI.h>

void setup() {
  SPI.begin();

  SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));

  SPI.transfer(0xFF); //réveil
  SPI.transfer(0xFF); //réveil

  SPI.transfer(0x00); // adresse device BD2808 (A0-A5 à 0)
  SPI.transfer(0x03); // registre configuration du courant pour les canaux R
  SPI.transfer(0x3F); // on fixe le courant maximum

  SPI.transfer(0xFF); //Retour à start standby
  SPI.transfer(0xFF); //Retour à start standby
  
  SPI.transfer(0x00);  // adresse device (toujours 0)
  SPI.transfer(0x06);  // registre PWM R0 (exemple)
  SPI.transfer(0xEE);  //data pour PWM

  SPI.transfer(0xFF); //Retour à start standby
  SPI.transfer(0xFF); //Retour à start standby

  SPI.transfer(0x00);  // adresse device BD2808 (A0-A5 à 0)
  SPI.transfer(0x1E);  // registre latch 
  SPI.transfer(0x01);  // active le latch

  SPI.transfer(0xFF); // Sleep

  SPI.endTransaction(); 
}

void loop() {

}

J'ai pensé que l'erreur pouvait venir de l'adresse de mon driver, les pads A1 et A5 sont connectées à la masse et le pad A0 n'est exposé à rien, j'ai essayé les adresses 0x00, 0x01, 0x3E et 0x3F mais rien ne fonctionne.

Pensant que le registre 0x1E pouvait correspondre à une autorisation plus qu'un changement, j'ai aussi essayé de placer la commande correspondante en début de programme mais cela n'a pas fonctionné non plus

Mais tu l'as connecté à quoi.
Il n'y a pas de CS sur le BD2808MUV-ME2

Non la librairie SPI ne gère pas le CS, c'est à la charge de l'application.

à un arduino nano, je suis parti d'un programme SPI qui servait d'une des borches de l'arduino comme chip select mais je l'ai enlevé vu que là ça servait à rien. Je cherche à avoir une réponse de mon driver mais je n'ai rien

Il faut que A0 soit à un niveau fixe et connu.
Il vient d'où ce module?

Dans la doc il est indiqué que c'est la transition à 1 du bit EN qui valide le transfert des registres internes vers les sorties.

OE est bien tiré au +5V?

OE est bien à un potentiel de 5V, en ce qui concerne la transition à 1 du bit EN, c'est ce que j'ai voulu faire avec

SPI.transfer(0xFF); //Retour à start standby
  SPI.transfer(0xFF); //Retour à start standby

  SPI.transfer(0x00);  // adresse device BD2808 (A0-A5 à 0)
  SPI.transfer(0x1E);  // registre latch 
  SPI.transfer(0x01);  // active le latch

  SPI.transfer(0xFF); // Sleep

Pour moi, ceci ne colle pas avec la description du protocole page 13.

  SPI.transfer(0xFF); //Retour à start standby
  SPI.transfer(0xFF); //Retour à start standby

Il faudrait faire

  SPI.transfer(0xFF); //Fin de l'échange
 
  SPI.transfer(0xFF); //Retour à start standby
  SPI.transfer(0xFF); //Retour à start standby

Après, tu as toujours la possibilité de désactiver le mode " Brightness register is latched on edge of EN" en mettant à 1 le bit ENMD dans le registre 02d. Ce qui évite d'avoir à écrire dans le registre 1Eh.

Bonjour ! Je partage une petite mise à jour sur l'état de mes "recherches"

pour

SPI.transfer(0xFF); //Fin de l'échange
 
  SPI.transfer(0xFF); //Retour à start standby
  SPI.transfer(0xFF); //Retour à start standby

C'est ce que j'écrivais à la base puis j'ai lu page 13 de la datasheet " Condition becomes START standby in any condition, if “1” is detected more
than 16 times. For example, Sleep condition starts if “1” is received 8 times while
waiting for register address. Moreover, the condition becomes START standby
after receiving “1” 8 times" et j'ai voulu essayer avec "seulement" 16 bits à 1. Dans les deux cas cela ne fonctionne pas. Même chose pour ce qui est de mettre à 1 le bit ENMD du registre 02d.

En revanche, j'ai écrit un programme exploitant le registre 00 qui permet de détecter l'adresse du driver:

#include <SPI.h>

void setup() {
  Serial.begin(9600);
  SPI.begin();

  for (uint8_t addr = 0x00; addr <= 0x3F ; addr++) {
    Serial.print("Tentative de lecture depuis adresse 0x");
    Serial.print(addr, HEX);
    Serial.print("... ");

    SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE0));

    // Réveil
    SPI.transfer(0xFF);
    SPI.transfer(0xFF);

    // Lecture du registre 0x00
    SPI.transfer(addr);     // Adresse device testée
    SPI.transfer(0x00);     // Registre 0x00
    SPI.transfer(0x00);     // Dummy write (standard pour SPI read)

    // Lecture de la réponse (dummy cycle)
    uint8_t data = SPI.transfer(0x00);  // Le chip devrait répondre ici

    SPI.transfer(0xFF); // Fin
    SPI.endTransaction();

    // Affichage du résultat
    if (data == addr) {
      Serial.print("Réponse détectée ! Adresse réelle = 0x");
      Serial.println(data, HEX);
    } else {
      Serial.println("Pas de réponse");
    }

    delay(200);
  }
}

void loop() {}

Ce programme-ci fonctionne, me retourne que l'adresse du driver est bien 0x00 et montre que le circuit détecte bien mon composant. J'ai essayé d'écrire mes données en rajoutant les commandes begin et endTransaction au début et à la fin de chaque échanges de données mais ça n'a pas fonctionné non plus.

Bref, je vous tiens au courant de si j'avance

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.