TCA9548A (I2C Multiplexer) funzt mit ESP32 aber nicht mit Arduino pro Micro?

Hallo Leute,

ich konnte folgende Schaltung nachbauen und funktioniert soweit mit dem ESP32


(quelle: TCA9548A I2C Multiplexer: ESP32, ESP8266, Arduino | Random Nerd Tutorials)

Mit dem Arduino pro micro kann ich immer nur auf einen Display zugreifen. Ein zweiter Display lässt sich mit dieser Logik nicht initieren - bekomme bei folgender Codezeile einen Fehler.

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) 

Gesamter Code

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/tca9548a-i2c-multiplexer-esp32-esp8266-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Select I2C BUS
void TCA9548A(uint8_t bus){
  Wire.beginTransmission(0x70);  // TCA9548A address
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
  Serial.print(bus);
}
 
void setup() {
  Serial.begin(115200);

  // Start I2C communication with the Multiplexer
  Wire.begin();

  // Init OLED display on bus number 2
  TCA9548A(2);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display.clearDisplay();

  // Init OLED display on bus number 3
  TCA9548A(3);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display.clearDisplay();

  // Init OLED display on bus number 4
  TCA9548A(4);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display.clearDisplay();

  // Init OLED display on bus number 5
  TCA9548A(5);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display.clearDisplay();

  // Write to OLED on bus number 2
  TCA9548A(2);
  display.clearDisplay();
  display.setTextSize(8);
  display.setTextColor(WHITE);
  display.setCursor(45, 10);
  // Display static text
  display.println("1");
  display.display(); 

  // Write to OLED on bus number 3
  TCA9548A(3);
  display.clearDisplay();
  display.setTextSize(8);
  display.setTextColor(WHITE);
  display.setCursor(45, 10);
  // Display static text
  display.println("2");
  display.display(); 
  
  // Write to OLED on bus number 4
  TCA9548A(4);
  display.clearDisplay();
  display.setTextSize(8);
  display.setTextColor(WHITE);
  display.setCursor(45, 10);
  // Display static text
  display.println("3");
  display.display(); 
  
  // Write to OLED on bus number 5
  TCA9548A(5);
  display.clearDisplay();
  display.setTextSize(8);
  display.setTextColor(WHITE);
  display.setCursor(45, 10);
  // Display static text
  display.println("4");
  display.display(); 
}
 
void loop() {
  
}

Wie gesagt, am ESP32 läuft das tadelos. Was braucht der Arduino pro Micro da noch zusätzlich?

Danke für eure Hilfe

Sehen Sie

"SSD1306 allocation failed"

??

könnte ein Speicherproblem sein (nicht genug, um die 4 Bildschirme zu unterstützen).

Ändern Sie die Ausdrucke so, dass sie Ihnen sagen, welche fehlschlagen
mit #2, #3, #4 und #5

  // Init OLED display on bus number 2
  TCA9548A(2);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("#2 SSD1306 allocation failed"));
    for (;;);
  }
1 Like

Für die Displays benötigen Sie 4 Objekte:

Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display3(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display4(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Dafür braucht man natürlich genügend Speicher.

Der 3.3V-Ausgang des Pro Micro board hat nicht genug Leistung für die Displays. Die Displays haben einen 3.3V I2C Bus und das Pro Micro Board hat einen 5V I2C Bus.

Sie müssen sich die Leistung, die Spannungen und die Pullup-Widerstände sowie die Spannungspegelverschiebungsfunktion des I2C-Multiplexers ansehen.

(Via Google Translate)

1 Like

Da sie über den TCA9548A gemultiplext werden, ist dies nicht wirklich notwendig, aber es lohnt sich zu überprüfen, ob ein viermaliger Aufruf von begin() ein Problem verursacht.

Die power kann in der Tat eine Herausforderung sein, ebenso wie I2C-Pullup-Widerstände. Auch das ist gut zu erkunden.

1 Like

Eure Tipps waren sehr hilfreich.

Hab jetzt eine "workaround" gefunden :innocent: Eventuell hat mal wer das gleiche Problem

Ich hab jetzt also eine externe Spannungsquelle dazu genommen. Die Pull-up Widerstände braucht es nicht.

Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display3(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display4(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

Im Setup gehe ich dann die Displays einzeln durch. Schreibe einen Text und setzte das Object auf NULL und gehe zum nächsten Display.


  TCA9548A(0);
  if (!display1.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("Could not connect display 1");
    while (1);
  }
  display1.clearDisplay();

display1.setTextSize(8);
display1.setTextColor(WHITE);
display1.setCursor(45, 10);
display1.println("my fancy TEXT");
display1.display();

  display1 = NULL;

//weiter mit display2....

Danke nochmal an euch für die Inputs!!!!

Viele grüße

Wie willst Du dann später auf das Display zugreifen, wenn Du es auf NULL setzt?

Gruß Tommy

In diesem Fall habe ich Glück, da ich danach nicht mehr darauf zugreifen muss... Die OLEDs haben jeweils eine statische Grafik drauf.

Nachtrag: Was mir noch einfällt, ich kann auch im späteren Verlauf einfach das Display neu überschreiben... Also einfach display1 wieder neu initieren und ab gehts! Ich weiß, schön geht anders :smiley: