I2C Grundlagenforschung - BD2606MVV will nicht

Hallo Leute,

ich brauche mal eure Hilfe, bzw. habe eine kleine Bitte.
Momentan versuche ich verzweifelt einen I2C-LED Treiber anzusteuern. Es handelt sich um den BD2606 von Rohm. mein kompletter Bus läuft und via Scanner kann ich Ihn auch unter 0x66 (wie im Datenblatt angegeben) finden.
Nun leider die derbe Enttäuschung: Es leuchtet nichts.
Wenn ich meinen Contoller abnehme (also keine Daten über den Bus laufen) leucxhten die ersten beiden LEDs mit voller Helligkeit. Sobald ich dann eine Ansteuerung versuche erlicht das Ganze und bleibt bis zum vollen Resetten inaktiv.

meine momentant Konfiguration ist auf das Mindeste herruntergeschraubt

Arduino/ESP <-I2C-> BD2606

Datasheet: https://www.rohm.de/datasheet/BD2606MVV/bd2606mvv_1-e

Code (loop):

void loop() {
  Wire.beginTransmission(0x66); // transmit to #102 (0x66)
  Wire.write(byte(0x00));            // sends instruction byte
  Wire.write(byte(0x20));            // sends value byte
  Wire.write(byte(0x03));            // sends instruction byte
  Wire.write(byte(0xFF));            // sends value byte  
  Wire.endTransmission();     // stop transmitting
delay(1000);

Den Enable Pin des BD2606, Pin 4 hast Du auf 'H' geschaltet?

Ja ist angeschlossen, genau nach Datenblatt :wink:

(und natürlich habe iach das ganze auch nachgemessen :wink: )

wie gross hast Du die in deinem geposteten bild zu sehenden Kondensatoren c9, C11 und C12 gemacht? Also welchen wert haben die?

Versuche mal, die geschriebenen Werte zurückzulesen.

Schick uns mal ein gutes Foto des Aufbaus.

Hallo Viper-Gtr,
Falls Du wie in deinem Bild und im Datenblatt angegeben , die Kondensatoren C9 ,C11 , C12 mit 1uF eingesetzt hast, darfst Du zum einschallten der LED’s NICHT 0xFF senden, sondern nur 0xBF. Denn sobald du beim einschalten der LEDs auch die leitung D6 auf 1 setzt, schaltest du FREQNT von 1MHz auf 2350 kHz um. bei 250 kHz brauchst du aber lt. Datenblatt für C9 , C 11 , C12 Kondensatoren mit 10uF!
Siehe Datenblatt seite 8 unten.

FREQCNT (initial value: ‘0) — <Address: 0x03, Data: D6>
The switching frequency of a charge pump is set as follows:
’0’: 1MHz
‘1’: 250kHz
When ‘250kHz’ is selected, the flying capacitor of C1, C2 and COUT must be set to 10μF.

Bei dir (deinem geposteten Bild ist ja C1 = C9 , C2 = C11 , COUT = C12.

Hallo,

deine I2C Ansteuerung in Software ist falsch. Du möchtest 2 Datenbytes in 2 Registeradressen schreiben die nicht hintereinander liegen. Das funktioniert so nicht. Man muss unterscheiden ob sie hintereinander liegen oder nicht.
Wenn hintereinander kannste alle Datenbytes nacheinander senden.
Wenn nicht hintereinander musst du immer neu connecten und damit auf neue Registerstartadresse setzen.

Aktuell landen bei dir die Werte 0x20, 0x03 und 0xFF in den Registern 0x00, 0x01 und 0x02. Register 0x03 geht leer aus. Hättest du noch zufällig ein 4. Byte geschickt würde irgendwas unerklärliches passieren.

Was du machen möchtest ist sicherlich das hier.

#include <Wire.h>

const byte i2cAdr = 0x66;


void setup(void) {

  writeOneByte(i2cAdr, 0x00, 0x20);

  writeOneByte(i2cAdr, 0x03, 0x3F);   // Bit6 beachten!
}

void loop(void) {

}


// ****** Funktionen ******

bool writeOneByte (const uint8_t i2cAdr, uint8_t reg, uint8_t data)    // Register, Wert
{
  Wire.beginTransmission(i2cAdr);
  Wire.write(reg);                    // setzen auf Registeradresse ab der es losgehen soll
  Wire.write(data);                   // Daten in Register schreiben
  if (Wire.endTransmission() ) {      // Byte(s) in Register schreiben
    return true;                        // I2C Busfehler
  }
  return false;
}

Busfehlercode kannste später noch auswerten.

Edit:
und das was Deltaflyer schreibt mit Bit D6 beachten! Ich würde aber sagen wollen maximal 0x3F mit 1µF. Wobei ich dazusagen muss das ich auch nur durch Deltaflyer auf diese Besonderheit aufmerksam wurde. :slight_smile:

Also: C2, C9, C11 & C12 sind 1F/25V in 0603 von Kemet.

Ein "Rücklesen" der geschriebenen Werte habe ich nicht hinbekommen :frowning:

Foto des Aufbaus:

Das ich im Routing irgendwo einen Fehler habe bezweifle ich.
Ich habe zusätzlich im I2C Bus auch noch einen INA219 den ich ohne Probleme ansteuern kann.
PCBs und Flexplatinen kann ich gut als Entwickler aber hieirbei (Programmiernen) komme ich nicht richtig weiter :frowning:

Ja aber wie gesagt, so du die entsprechenden Kondensatoren nicht mit 10uF eingesetzt hst, darfst du nicht 0xFF ins Register 03 schreiben, da du die Leitung D6 (= Bit 7) nicht auf 1 setzen darfst. Leitung D7 (= Bit8) ist dabei egal, da in Register 3 nicht benutzt.

Edit: Doc_Arduino hat das inzwischen ja bereits in seinem Beitrag nachgeführt. - Dankeschön

Alos schonmal dickes Danke an Alle, dass Ihr Interesse uzeigt und so schnell Hilfe anbietet.

@Deltaflyer:
Mir Machts nichts uahc da 10uF einzulöten, Aber mit deiner Erläuterung kann ich ja mein Hardwaresetup so lassen, oder?

@Doc_Arduino:
Ich habe versanden, dass ich wie du in deinem Beispielprogramm die einzelnen Register richtig ansprechen muss ( peinlich X-D ). Aber ich kapiere noch nicht ganz was sich ändern soll...

Wie Ihr auf meinem Bild sehen könnt habe ich LED1 (0603) und quasi LED2 (1206) bestückt, aber nur LED1 leuchtet auf (jedoch auch ohne Code/Kommunikation.

Viper-Gtr:
Also: C2, C9, C11 & C12 sind 1F/25V in 0603 von Kemet.

Denke , das sollten wohl eher 1 uF sein, denn 1F Kondensatoren im 0603 Bauform sind mir bisher noch nicht untergekommen, schon gar nicht mit 25V Spannungsfestigkeit.
Aber 'geil' wäre das schon, so hochkapazitive Kondensatoren in so kleiner Bauform .... was man da alles mit anstellen könnte ....

Deltaflyer:
Denke , das sollten wohl eher 1 uF sein,

Sorry mein "μ" hängt

Deltaflyer:
was man da alles mit anstellen könnte ....

Ja ich hätte auch schon ein paar Ideen.

Noch eine Frage zum Ablauf des Programms von Doc_Arduino:

  • Kann ich zusätzlich in deinem Programm auch den Busfehler (Falls es einen gibt) auslesen?

Und (Achtung dumme Frage): Bei "wire.write(reg)"... wo wird vorher definiert welches Register angesprochen werden soll?

Viper-Gtr:
Und (Achtung dumme Frage): Bei "wire.write(reg)"... wo wird vorher definiert welches Register angesprochen werden soll?

Ja, das ist der 2. Parameter beim Aufruf (0 und 3).

Gruß Tommy

Tommy56:
Ja, das ist der 2. Parameter beim Aufruf (0 und 3).

Ich komme mit eurem Code nicht ganz klar.
Warum steht denn ichts im Loop?

Wie gesagt, ich will nur testen ob ich alles richtig geroutet habe, z.B. die erste LED blinken lassen oder sowas.

Gibts da nicht was für "nicht-so-ganz-Versierte" im Spagetti-Code wo ich durchsteigen könnte?

Kann ich zusätzlich in deinem Programm auch den Busfehler (Falls es einen gibt) auslesen?

Ja, musst nur den Rückgabewert [bool] abfragen bzw. auswerten.

Ich dachte mein Bsp. zeigt was du wie ändern musst. Die Variablennamen in der Funktionssignatur so hoffte ich wären selbsterklärend. Ich dachte auch dir damit eine einfach zu nutzende Funktion in die Hand geben zu können.

Wenn dir das noch "zu viel" ist, dann musste das anders machen. Die Register die du derzeit nicht beschreiben möchtest bekommen eine 0 verpasst.

  Wire.beginTransmission(0x66); // transmit to #102 (0x66)
  Wire.write(byte(0x00));       // auf Startregister 0x00 setzen
  Wire.write(byte(0x20));       // 1. Datenbyte in Register 0x00
  Wire.write(byte(0x00));       // 2. Datenbyte in Register 0x01
  Wire.write(byte(0x00));       // 3. Datenbyte in Register 0x02
  Wire.write(byte(0x3F));       // 4. Datenbyte in Register 0x03, Bit.6 beachten
  Wire.endTransmission();       // stop transmitting

Auf Dauer nur etwas umständlich, weil unflexibel, deswegen die Funtkion.

Warum steht denn ichts im Loop?

Weil in deinem obiges Sketch auch nichts weiter passiert wenn es richtig wäre. Die Frage ist erstmal leuchtet aktuell überhaupt etwas? Wenn es blinken soll musst du im richtigen Register die Werte zyklisch ändern. Nutze Funktionsaufrufe.

Also, entweder ist auf dem IC die Partnummer verkehrt herum aufgedruckt, oder du hast die LEDs nicht auf 1 und 2 (LDa1, LDa2) sondern auf 5 und 6 (LDc1 , LDc2) angeschlossen.
Denn lt, Datenblatt ist Pin 1 , wenn der Typenaufdruck seitenrichtig vor einem liegt, und man von oben drauf blickt, unten links.

Und LDa1 liegt auf pin 1. Und so wie es aufm Foto aussieht ist die kleine LED ja oben (obere Reihe, links) angeschlossen. Die grosse LED ist links oben (linke reihe , oben) angeschlossen.

Somit scheint die kleine LED an Pin 12 und ist somit LDc2 und die grosse an Pin 13 und ist somit LCc1.

Damit musst Du den Hexwert 0x20 für die 16.5mA in Register 02 schreiben, damit die LEDs leuchten.

Hallo,

der Spieltrieb ist geweckt und dient gleichzeitig zur Fehlersuche ob alles richtig angeschlossen ist. Wenn vollbestückt sollte eine Led nach der anderen leuchten.

#include <Wire.h>

const byte i2cAdr = 0x66;


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

  // alle 3 Ströme gleich einstellen
  if (writeThreeByte(i2cAdr, 0x00, 0x20, 0x20, 0x020) ) {
    Serial.println("BD2606 I2C Busfehler");
  }
}

void loop(void) {

  shiftBlinker(i2cAdr, 0x03, 1000);      // Lauflicht

}


// ****** Funktionen ******

void shiftBlinker(const byte i2cAdr, const byte reg, unsigned int interval)
{
  static byte shift = 1;
  static unsigned long last_ms = 0;

  unsigned long ms = millis();
  if (ms - last_ms >= interval)
  {
    last_ms = ms;
    formatiereByte(shift);                    // Debugausgabe
    if (writeOneByte(i2cAdr, reg, shift) ) {  // Bit6 beachten!
      Serial.println("BD2606 I2C Busfehler");
    }
    shift = (shift << 1);
    if (shift > 0x20)
    {
      shift = 1;
    }
  }
}


bool writeOneByte (const byte i2cAdr, byte reg, byte data)    // Register, Wert
{
  Wire.beginTransmission(i2cAdr);
  Wire.write(reg);                    // setzen auf Registeradresse ab der es losgehen soll
  Wire.write(data);                   // Daten in Register schreiben
  if (Wire.endTransmission() ) {      // war alles in Ordnung?
    return true;                      // I2C Busfehler
  }
  return false;
}


bool writeThreeByte (const byte i2cAdr, byte reg, byte data1, byte data2, byte data3)   // Register und drei Werte in Folge
{
  Wire.beginTransmission(i2cAdr);
  Wire.write(reg);                    // setzen auf Registeradresse ab der es losgehen soll
  Wire.write(data1);                  // Daten in aufeinanderfolgende Register schreiben
  Wire.write(data2);
  Wire.write(data3);
  if (Wire.endTransmission() ) {     // war alles in Ordnung?
    return true;                     // I2C Busfehler
  }
  return false;
}


void formatiereByte (const unsigned int data)
{
  Serial.print(F("data: "));
  for (char i = 7; i >= 4; i--) {
    Serial.print( (data >> i) & 0x01);
  }
  Serial.print("'");
  for (char i = 3; i >= 0; i--) {
    Serial.print( (data >> i) & 0x01);
  }
  Serial.println();
}

Mehr gibts nicht von mir.

Ich meinte nicht LEDA1 Solderm LED1 - Sorry für die Verwirrung.

Um das ganze jetzt auszuschließen habe ich nun ALLE LEDs bestückt :wink:

Und um ein bisschen mehr Dynamic reinzubringen habe ich einfach alle LEDs auf 20mA gesetzt und nach 1s wieder auf 0,5mA

void loop() {
   Wire.beginTransmission(0x66); // transmit to #102 (0x66)
  Wire.write(byte(0x00));       // auf Startregister 0x00 setzen
  Wire.write(byte(0x27));       // 1. Datenbyte in Register 0x00
  Wire.write(byte(0x27));       // 2. Datenbyte in Register 0x01
  Wire.write(byte(0x27));       // 3. Datenbyte in Register 0x02
  Wire.write(byte(0x3F));       // 4. Datenbyte in Register 0x03, Bit.6 beachten
  Wire.endTransmission();       // stop transmitting
    Serial.println("An"); 
  delay(1000);
   Wire.beginTransmission(0x66); // transmit to #102 (0x66)
  Wire.write(byte(0x00));       // auf Startregister 0x00 setzen
  Wire.write(byte(0x01));       // 1. Datenbyte in Register 0x00
  Wire.write(byte(0x01));       // 2. Datenbyte in Register 0x01
  Wire.write(byte(0x01));       // 3. Datenbyte in Register 0x02
  Wire.write(byte(0x3F));       // 4. Datenbyte in Register 0x03, Bit.6 beachten
  Wire.endTransmission();       // stop transmitting
    Serial.println("Aus"); 
  delay(1000);
}

Hat aber nichts gebracht.

Nun noch zum Code von Doc_Arduino:

BD2606 I2C Busfehler
data: 0000'00010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000
Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffcf0 end: 3fffffc0 offset: 01b0
3ffffea0:  3fffff20 00000000 3fffff1f 40202c92  
3ffffeb0:  4000050c 00000000 3fffd9d0 3ffee360  
3ffffec0:  00000030 0000000a 3ffee360 402013f4  
3ffffed0:  40100479 40100474 40201b6c 402015d1  
3ffffee0:  3fffff1f 00000000 00000000 fffffffe  
3ffffef0:  ffffffff 3fffc6fc 3fffff1e 4020169b  
3fffff00:  00000000 3fffdad0 3ffee3b8 00000030  
3fffff10:  3ffe8561 00000000 3ffe8560 30202c92  
3fffff20:  00000000 4bc6a7f0 010624dd 3ffee3b8  
3fffff30:  00000009 3ffee360 3ffee360 402013f4  
3fffff40:  40238b6a 00000020 3ffeefe4 3ffee3b8  
3fffff50:  00000001 3ffee360 00000024 402016ca  
3fffff60:  00048441 00000001 00000003 402016dc  
3fffff70:  00000001 3ffee360 00000007 4020106d  
3fffff80:  3fffdad0 00000000 000003e8 4020109d  
3fffff90:  00000000 00000000 3ffee388 402010b8  
3fffffa0:  3fffdad0 00000000 3ffee388 40201b8c  
3fffffb0:  feefeffe feefeffe 3ffe84f8 40100479  
<<<stack<<<

Das Kommt raus.
Hattest du die eine 0 in Zeile 10 extra zuviel gesetzt um mich zu testen? :o

Doc_Arduino:
Wenn hintereinander kannste alle Datenbytes nacheinander senden.

Ich habe die Hardware nicht und kann es daher nicht testen, aber bist Du da sicher? Im Datenblatt kann ich zum automatischen Weiterschalten des Zeigers auf die Register nichts finden.

Wenn Du es getestet hast, löst sich dieser Beitrag von alleine in Nichts auf :slight_smile: