2x I2C-Bus am ESP32

  • Hallo Reiner,


    danke für die Info, das hatte ich auch so aus KaiR’s Beitrag verstanden und ich habe es jetzt auch so umgesetzt.

    Ich hatte sowie die unten aufgeführten Codebeispiele zeigen auch schon mit 2 Bussen gespielt. Nur scheinbar scheinen die Library’s dies nicht 100% zu unterstützen und versuchen trotzdem den 1. Bus, sprich den mit Wire bezeichneten anzusprechen was dann zum versagen einiger Komponenten führt.


    2 BME280 Sensoren konnte ich auch schon an 2 verschiedenen Bussen nutzen. Un im I2C Scann werden auch alle Adressen in den entsprechenden Bussen gefunden. In meinem Fall war glaube ich der RTC der Übeltäter.


    Die über den Link gezeigten Beispiele und Erklärungen sind gut verständlich gezeigt. Vielen Dank!

  • Alle Boards, die ich mit Pullups gesehen habe, verwenden höherwertige Widerstände. 4k7-10k. Dies ist meist der maximaler Wert, der verwendet werden sollte.
    Die Spezifikation für I2C ist, dass das Gerät in der Lage sein muss, Strom auf 3 mA zu senken. Bei einer 3,3-Volt-Versorgung beträgt somit der minimale Gruppenwiderstand 1k1. Dies würde bedeuten, dass Sie ein paar Module auf die Linie setzen könnten und immer noch innerhalb der Spezifikation liegen.



    Dual I2C:

    https://randomnerdtutorials.co…ommunication-arduino-ide/

  • Hallo KaiR,


    danke für deine ausführliche Darstellung.

    Daraufhin habe ich mal nachgemessen.


    Tatsächlich hat das RTC Modul einen 4.7kOhm anstatt eines 10k Widerstandes, was bei den 4 Modulen den Bus entsprechend belastet und natürlich Fehlverhalten durch redeten des Busses hervorruft.


    Da ich momentan keine Lösung für 2 I2C Busse sehe habe ich die Leitung der 4.7k Widerstände am RTC Modul unterbrochen. Damit funktioniert es erst einmal

  • Deine erste Frage lässt sich wie folgt beantworten:

    Kommt drauf an.


    Der Punkt ist der das, wie Du ja schon beschrieben hast, jedes Breakout Pullupwiderstände hat. Diese liegen am I2C Bus parallel zueinander. Das heißt, je mehr Breakouts am Bus hängen, desto kleiner wird der Gesamtwiderstand der Pullups.


    Nun werden die Leitungen (SDA/SCL) dadurch auf LOW gebracht, indem diese i.d.R. über einen Transistor/Fet im Controller/Breakout mit GND verbunden werden. Der Transistor/Fet arbeitet als Schalter der jedoch einen Innenwiderstand hat, an dem eine Spannung abfällt. Dadurch wird im I2C Bus LOW nie = 0V sein sondern immer ein wenig darüber liegen.


    Je geringer der Gesamtwiderstand der Pullups ist, desto mehr Strom wird durch den jeweiligen Transistor/Fet fließen. Mit steigendem Strom steigt auch die Spannung an seinem Innenwiderstand. Dadurch steigt die LOW Spannung weg von fast Null in Richtung Betriebsspannung. Das heißt, "LOW wird immer weniger LOW".


    Bei I2C darf der LOW Pegel nur max. 0,4V betragen. Es sollten nur max. 3mA Strom fließen. Daraus lässt sich ermitteln, wie viele Breakouts du anschließen kannst:


    (VCC - 0,4) / 3mA = minimal zulässiger Gesamtwiderstand.


    Da Du geschrieben hast einen ESP32 zu benutzen, gehe ich mal von einer Betriebsspannung von 3,3V aus:

    (3,3V-0,4V) / 3*10-3 A ≈ 967Ω ist der (Gesamt-)Pullupwiderstand der mindestens vorhanden sein muss.


    Da Du ebenfalls geschrieben hast, dass jedes deiner Breakouts 10kΩ Widerstände hat und 10 * 10 kΩ parallel 1 kΩ entsprechen, kannst du im Prinzip 10 Breakouts anschließen. Um auf Nummer sicher zu gehen, geh auf acht. Dann hast Du noch 1,25 kΩ Gesamtwiderstand und damit etwas Sicherheitspuffer. Fünf Breakouts sollten in diesem Punkt keinerlei Probleme machen.


    Bei 5V Betriebsspannung liegt die Grenze des Gesamtwiderstandes bei ca. 1,53 kΩ. Da hättest Du bei sechs Breakouts einen Gesamtwiderstand von 1,67V, was noch ausreichend ist.


    Blöd ist es, wenn ein Breakout dazwischen ist, welches nur 4,7 kΩ oder gar nur 2,2 kΩ Pullups hat. Da ja bekanntlich der Gesamtwiderstand parallel geschalteter Widerstände kleiner ist als der kleinste in der Parallelschaltung vorhandene Widerstand, kann sich die Zahl der maximal koppelbaren Breakouts drastisch verkleinern. Bei 5V Betriebsspannung wäre man beispielsweise mit zwei Breakouts á 10 kΩ und einmal 2,2 kΩ (=1,527kΩ) schon an bzw. knapp unter der Grenze von 1,53 kΩ. Da kann es sein, dass es mal funktioniert und mal nicht (je nach Temperatur). Mit 3.3V Betriebsspannung würde es noch reichen.


    Natürlich muss man auch die Länge der Leitung berücksichtigen die man benötigt, um die Breakouts miteinander zu verbinden. Diese sollte so kurz wie möglich sein. Die Gesamtkapazität der Leitungen darf 400 pF nicht überschreiten. Das ist erst einmal ein etwas abstrakter Wert. Man kann aber sagen, mit zunehmender Länge der Leitungen, steigt auch die Kapazität auf dem I2C-Bus. Ist die Leitung zu lang, funktioniert es nicht mehr richtig. Aber es dürfte nichts "kaputt" gehen". Man müsste in dem Fall die Leitung kürzen oder einen I2C Bus Extender (Buffer) Baustein benutzen.


    Die anderen Fragen kann ich Dir so nicht beantworten, weil ich das selber noch nicht durchexerziert habe, ich keine Zeit habe mir das genauer anzuschauen und/oder ich es nicht weiß.


    So nun muss ich weg... schönen Tag noch ;)

  • nach einigen Versuchen mit einem RTC Modul, zwei BME280, einem OLED Display und einerSD Karte an einem I2C Bus kamen mir einige Bedenken was den Abschluss des Busses über Pullup Widerstände angeht. Jedes dieser Module hat einen 10KOhm am SDA und SCL gegen VCC. Es funktioniert zwar aber ich möchte hier nicht unbedingt Gefahr laufen etwas zu beschädigen.


    Deshalb hatte ich über Wege nachgedacht 2 I2C Busse zu verwenden. Kein Problem dachte ich. Arduino bringt ja entsprechend über die Wire Library die Funktion TwoWire mit.

    Im Scan funktioniert das auch wir erwartet. Alle Member des Busses melden sich brav.


    als Ergebnis bekomme ich die gewünschten Adressen im entsprechenden Bus

    Code
    1. 2C scanner. Scanning bus 0...
    2. Found address: 76
    3. Found address: 77
    4. I2C scanner. Scanning bus 1...
    5. Found address: 3c
    6. Found address: 57
    7. Found address: 68
    8. I2C device check DONE.


    Ok, dann versuch ichmal Display und RTC am Wire2 zum laufen zu bringen, leider mit bescheidenem Erfolg ;(Das Datum wird zuerst ausgelesen und wechselt dann ständig .



    mit einer anderen Library habe ich schon gespielt, leider mit ähnlichem Erfolg



    Jetzt habe ich einige Fragen:


    1. wieviele Member kann ich gefahrlos in den Bus hängen?


    2. gibt es eine funktionierende Library für RTC (DS3231) wo ich SDA und SCL Pin zuweisen kann?


    3. gibt es eine solche für BME280?


    4. Hab ich einen Denkfehler im Code?


    5. kann man das auch anders lösen