OLED Display not showing when using multiplexer

Hi there, I am working on a project to display color reading values to an OLED display. I am using an Elegoo uno r3. I have this connected to a TCA9548a multiplexer. Connected to the multiplexer are 2 color readers (TCS3472) and a 0.96inch OLED display.
The display works when I connect it via i2c to just the arduino A4 and A5, and the color readers work as well, both by themselves and at the same time in the multiplexer.
The trouble arises when I have now connected the OLED to the multiplexer as well, and I can't seem to get anything to display on it.
I'll include the whole code of my project, the majority of it is controls to navigate between menu screens on the OLED, and those all work when I tested just the display. But now with the multiplexer no dice. So I'm thinking problems arise around line 134 when I try to begin the display but I'm unsure.

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
#define TCAADDR 0x70
#define SAMPLE_COUNT 50  // Number of samples to take over 5 seconds

float glucoseGValues[SAMPLE_COUNT];
float uricAcidGValues[SAMPLE_COUNT];
float averageGlucoseG = 0;
float averageUricAcidG = 0;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_TCS34725 cs1 = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
Adafruit_TCS34725 cs2 = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

// Button pins
const int btnLeft = 2;
const int btnRight = 4;
const int btnSelect = 8;
const int btnReturn = 10;

enum MenuState {
  WELCOME,
  MAIN_MENU,
  TIME_CHECK,
  LOADING,
  GLUCOSE,
  URIC_ACID
};

MenuState currentState = WELCOME;
int selectedOption = 0;
bool timeCheckAnswer = false;

// glucose bitmap
const unsigned char PROGMEM logo_glucose[] = {
  0x01, 0x80, 0x06, 0x60, 0x18, 0x18, 0x60, 0x06, 0x98, 0x39, 0x86, 0xc1, 0x81, 0x01, 0x91, 0x11,
  0xa1, 0x21, 0x81, 0x45, 0x85, 0x09, 0x89, 0x01, 0x61, 0x06, 0x19, 0x18, 0x05, 0x60, 0x03, 0x80
};
//Uric acid bitmap
const unsigned char PROGMEM logo_uric_acid[] = {
  0x03, 0xc0, 0x0c, 0x20, 0x10, 0x10, 0x13, 0x08, 0x26, 0x08, 0x24, 0x11, 0x40, 0x22, 0x40, 0x3c,
  0x40, 0x3c, 0x40, 0x22, 0x20, 0x11, 0x20, 0x08, 0x10, 0x08, 0x10, 0x10, 0x0c, 0x20, 0x03, 0xc0
};

// Main logo array here
const unsigned char PROGMEM main_logo[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x71, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x05, 0x00, 0x00,
  0x18, 0x0c, 0x7e, 0xff, 0xdf, 0x86, 0x1f, 0x1f, 0x10, 0x10, 0xf8, 0xf8, 0x01, 0x09, 0x00, 0xe0,
  0x1c, 0x0c, 0x60, 0x0c, 0x19, 0x86, 0x30, 0x18, 0x18, 0x11, 0x80, 0xc0, 0x00, 0x82, 0x03, 0xb0,
  0x1c, 0x1c, 0x60, 0x0c, 0x18, 0xc6, 0x20, 0x18, 0x1c, 0x11, 0x00, 0xc0, 0x00, 0x7c, 0x0e, 0x10,
  0x1e, 0x1c, 0x60, 0x0c, 0x18, 0xc6, 0x20, 0x18, 0x14, 0x11, 0x00, 0xc0, 0x00, 0x00, 0x38, 0xd8,
  0x1e, 0x3c, 0x60, 0x0c, 0x19, 0x86, 0x30, 0x18, 0x16, 0x11, 0x80, 0xc0, 0x00, 0x00, 0xe1, 0x28,
  0x1b, 0x2c, 0x60, 0x0c, 0x1f, 0x06, 0x18, 0x18, 0x13, 0x10, 0xe0, 0xc0, 0x00, 0x03, 0x81, 0x2c,
  0x1b, 0x2c, 0x7e, 0x0c, 0x1f, 0x06, 0x0e, 0x1f, 0x11, 0x10, 0x30, 0xf8, 0x00, 0x0e, 0x00, 0xc4,
  0x19, 0xec, 0x60, 0x0c, 0x19, 0x86, 0x03, 0x18, 0x11, 0x90, 0x18, 0xc0, 0x00, 0x38, 0x00, 0x06,
  0x19, 0xcc, 0x60, 0x0c, 0x18, 0xc6, 0x01, 0x18, 0x10, 0xd0, 0x08, 0xc0, 0x00, 0xe3, 0x80, 0x0e,
  0x18, 0x8c, 0x60, 0x0c, 0x18, 0xc6, 0x01, 0x18, 0x10, 0x50, 0x08, 0xc0, 0x03, 0x84, 0x40, 0x38,
  0x18, 0x0c, 0x60, 0x0c, 0x18, 0x46, 0x01, 0x18, 0x10, 0x70, 0x08, 0xc0, 0x0e, 0x04, 0x40, 0xe0,
  0x18, 0x0c, 0x60, 0x0c, 0x18, 0x66, 0x03, 0x18, 0x10, 0x30, 0x18, 0xc0, 0x38, 0x04, 0x43, 0x80,
  0x18, 0x0c, 0x7e, 0x0c, 0x18, 0x66, 0x3e, 0x1f, 0x10, 0x11, 0xf0, 0xf8, 0xe0, 0x03, 0x8e, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x38, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0x00, 0xe0, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x03, 0x80, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x0e, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x38, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'check', 20x20px
const unsigned char PROGMEM check_icon[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x40, 0x00, 0x00, 0xa0, 0x00, 0x01, 0x10, 0x00, 0x02, 0x20, 0x00, 0x04, 0x40, 0x00, 0x08,
  0x80, 0x10, 0x11, 0x00, 0x28, 0x22, 0x00, 0x44, 0x44, 0x00, 0x22, 0x88, 0x00, 0x11, 0x10, 0x00,
  0x08, 0x20, 0x00, 0x04, 0x40, 0x00, 0x02, 0x80, 0x00, 0x01, 0x00, 0x00
};
// 'x', 20x20px
const unsigned char PROGMEM x_icon[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x14, 0x02, 0x80, 0x22, 0x04, 0x40, 0x11,
  0x08, 0x80, 0x08, 0x91, 0x00, 0x04, 0x62, 0x00, 0x02, 0x04, 0x00, 0x01, 0x08, 0x00, 0x01, 0x08,
  0x00, 0x02, 0x04, 0x00, 0x04, 0x62, 0x00, 0x08, 0x91, 0x00, 0x11, 0x08, 0x80, 0x22, 0x04, 0x40,
  0x14, 0x02, 0x80, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

void setup() {
  Wire.begin();
  pinMode(btnLeft, INPUT_PULLUP);
  pinMode(btnRight, INPUT_PULLUP);
  pinMode(btnSelect, INPUT_PULLUP);
  pinMode(btnReturn, INPUT_PULLUP);

  delay(100);  // Add a short delay

  tcaselect(0);
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for (;;)
      ;
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  drawWelcomeScreen();

  tcaselect(1);
  if (!cs1.begin()) {
    // Handle error
  }

  tcaselect(2);
  if (!cs2.begin()) {
    // Handle error
  }
}

void loop() {
  handleButtons();
  if (currentState == LOADING) {
    static unsigned long startTime = millis();
    if (millis() - startTime < 5000) {
      drawLoadingScreen();
    } else {
      currentState = selectedOption == 0 ? GLUCOSE : URIC_ACID;
      drawSubmenu();
    }
  }
  delay(100);
}

void handleButtons() {
  if (digitalRead(btnLeft) == LOW || digitalRead(btnRight) == LOW || digitalRead(btnSelect) == LOW) {
    if (currentState == WELCOME) {
      currentState = MAIN_MENU;
      drawMainMenu();
    } else if (currentState == MAIN_MENU) {
      if (digitalRead(btnLeft) == LOW) selectedOption = 0;
      if (digitalRead(btnRight) == LOW) selectedOption = 1;
      if (digitalRead(btnSelect) == LOW) {
        currentState = TIME_CHECK;
        drawTimeCheck();
      } else {
        drawMainMenu();
      }
    } else if (currentState == TIME_CHECK) {
      if (digitalRead(btnLeft) == LOW) timeCheckAnswer = true;
      if (digitalRead(btnRight) == LOW) timeCheckAnswer = false;
      if (digitalRead(btnSelect) == LOW) {
        if (timeCheckAnswer) {
          currentState = LOADING;
        } else {
          currentState = MAIN_MENU;
          drawMainMenu();
        }
      }
      drawTimeCheck();
    }
  }

  if (digitalRead(btnReturn) == LOW) {
    if (currentState == GLUCOSE || currentState == URIC_ACID || currentState == TIME_CHECK) {
      currentState = MAIN_MENU;
      drawMainMenu();
    } else if (currentState == MAIN_MENU) {
      currentState = WELCOME;
      drawWelcomeScreen();
    }
  }
}

void drawWelcomeScreen() {
  tcaselect(0);
  display.clearDisplay();
  // Draw your 128x48 logo
  display.drawBitmap(0, 0, main_logo, 128, 48, WHITE);

  display.setTextSize(1);

  // Center "Press any button to begin" text
  const char* text1 = "Press any button";
  const char* text2 = "to begin";
  int16_t x1, y1, x2, y2;
  uint16_t w1, h1, w2, h2;

  display.getTextBounds(text1, 0, 0, &x1, &y1, &w1, &h1);
  display.getTextBounds(text2, 0, 0, &x2, &y2, &w2, &h2);

  display.setCursor((SCREEN_WIDTH - w1) / 2, 48);
  display.println(text1);
  display.setCursor((SCREEN_WIDTH - w2) / 2, 56);
  display.println(text2);

  display.display();
}

void drawMainMenu() {
  tcaselect(0);
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(24, 0);
  display.println("Select Analyte");

  // Glucose option
  display.drawBitmap(20, 24, logo_glucose, 16, 16, WHITE);
  display.setTextSize(1);
  display.setCursor(8, 42);
  display.println("Glucose");

  // Uric Acid option
  display.drawBitmap(88, 24, logo_uric_acid, 16, 16, WHITE);
  display.setCursor(70, 42);
  display.println("Uric Acid");

  // Selection box
  if (selectedOption == 0) {
    display.drawRect(0, 18, 56, 40, WHITE);
  } else {
    display.drawRect(64, 18, 64, 40, WHITE);
  }

  display.display();
}

void drawTimeCheck() {
  tcaselect(0);
  display.clearDisplay();

  // Draw title
  display.setTextSize(1);
  display.setCursor(20, 0);
  display.println("Has sample sat");
  display.setCursor(28, 8);
  display.println("for 5 mins?");

  // Draw Yes option
  display.drawBitmap(24, 24, check_icon, 20, 20, WHITE);
  display.setCursor(24, 46);
  display.println("Yes");

  // Draw No option
  display.drawBitmap(88, 26, x_icon, 20, 20, WHITE);
  display.setCursor(94, 46);
  display.println("No");

  // Draw selection box
  if (timeCheckAnswer) {
    display.drawRect(16, 20, 36, 36, WHITE);
  } else {
    display.drawRect(80, 20, 36, 36, WHITE);
  }

  display.display();
}

void drawSubmenu() {
  tcaselect(0);
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 0);

  if (currentState == GLUCOSE) {
    display.println("Glucose Level:");
    display.setTextSize(2);
    display.setCursor(32, 32);
    display.print(averageGlucoseG, 1);
  } else if (currentState == URIC_ACID) {
    display.println("Uric Acid Level:");
    display.setTextSize(2);
    display.setCursor(32, 32);
    display.print(averageUricAcidG, 1);
  }
  display.display();
}


void drawLoadingScreen() {
  unsigned long startTime = millis();
  int sampleIndex = 0;

  while (millis() - startTime < 5000) {
    tcaselect(0);
    display.clearDisplay();
    display.setTextSize(2);
    display.setCursor(4, 24);
    display.println("Reading...");
    display.display();

    // Read from glucose sensor
    tcaselect(1);
    float r, g, b;
    cs1.getRGB(&r, &g, &b);
    glucoseGValues[sampleIndex] = g;

    // Read from uric acid sensor
    tcaselect(2);
    cs2.getRGB(&r, &g, &b);
    uricAcidGValues[sampleIndex] = g;

    sampleIndex++;
    if (sampleIndex >= SAMPLE_COUNT) sampleIndex = 0;

    delay(100);  // Adjust this delay to get about 50 samples over 5 seconds
  }

  // Calculate averages
  averageGlucoseG = 0;
  averageUricAcidG = 0;
  for (int i = 0; i < SAMPLE_COUNT; i++) {
    averageGlucoseG += glucoseGValues[i];
    averageUricAcidG += uricAcidGValues[i];
  }
  averageGlucoseG /= SAMPLE_COUNT;
  averageUricAcidG /= SAMPLE_COUNT;
}

I would appreciate any help if anyone's encountered a similar issue or knows of a solution. I tried looking at similar posts but their code was not helpful unfortunately.
And I've uploaded a schematic of what is set up currently.

Does the TCA9548 seen on the I2c bus with i2c scanner? On which address?

Maybe lack of pullup resistors on the OLED?
Check the voltage on the SD1 and SC1 pins. If not close to 5v, then it needs pullup resistors.

Edit: Make that SD0 and SC0 pins. If not close to 5v, then it needs pullup resistors.

You do not have enough memory, the compiler shows 933 bytes of ram used, the display buffer will use another 1024 bytes at run-time, leaving only 91 bytes for the stack, local variable, etc.

There are other display libraries that take less memory, either the U8g2 library using a page buffer, or the libraries that only display text.

Yep it shows up at 0x70
Then the connected components also show up at their expected addresses.
0: Found i2c 0x3c (oled)
1: Found i2c 0x29 (color reader)
2: Found i2c 0x29

Try one OLED, compile, then two, compile... look for signs.

Hey thanks for the response, I think it has internal pullup resistors. And measured voltage is hovering right around 5v
Regardless, tried a pullup and no dice with that!

This seems to have been the issue! Switched to the U8g2 library and now it works a charm, thanks for the insight!

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