Arduino uno with multiple oled displays

The u8g2.firstPage() function call is not needed when initializing the display.

// Initialize the displays
void DisplayInit() {
  for (int i = 0; i < 2; i++) {
    tcaselect(i);   // Loop through each connected displays on the I2C buses
    //u8g2.firstPage();
    u8g2.begin();  // Initialize display
  }
}
#include "Wire.h"
#include <U8g2lib.h>
#define MUX_Address 0x70  // TCA9548A Encoders address

U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0);

// Initialize I2C buses using TCA9548A I2C Multiplexer
void tcaselect(uint8_t i2c_bus) {
  Wire.beginTransmission(MUX_Address);
  Wire.write(1 << i2c_bus);
  Wire.endTransmission();
}

// Initialize the displays
void DisplayInit() {
  for (int i = 0; i < 2; i++) {
    tcaselect(i);  // Loop through each connected displays on the I2C buses
    u8g2.begin();  // Initialize display
  }
}

void setup() {  //{{
  Serial.begin(9600);
  Serial.println("before DisplayInit");
  DisplayInit();  // Initialize the displays
  Serial.println("After DisplayInit");


  for (int i = 0; i < 2; i++) {
    tcaselect(i);

    u8g2.firstPage();
    do {
      u8g2.setFont(u8g2_font_ncenB10_tr);
      u8g2.drawStr(0, 15, "Hello World!");
    } while (u8g2.nextPage());
    delay(50);
  }
}

There we go, much better now, still doesn't work tho.

Ran an I2C scanner and thats what i got:

Scanning...
Unknown error at address 0x01
Unknown error at address 0x02
Unknown error at address 0x03
Unknown error at address 0x04
Unknown error at address 0x05
Unknown error at address 0x06
Unknown error at address 0x07
Unknown error at address 0x08
Unknown error at address 0x09
Unknown error at address 0x0A
Unknown error at address 0x0B
Unknown error at address 0x0C
Unknown error at address 0x0D
Unknown error at address 0x0E
Unknown error at address 0x0F
Unknown error at address 0x10
Unknown error at address 0x11
.
.
.
Unknown error at address 0x78
Unknown error at address 0x79
Unknown error at address 0x7A
Unknown error at address 0x7B
Unknown error at address 0x7C
Unknown error at address 0x7D
Unknown error at address 0x7E
No I2C devices found

3 dots for simpilfication, also fixed the connection issue.

This is the I2C scanner i used:

#include <Wire.h>

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

  Serial.println("\nI2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for (address = 1; address < 127; address++) {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");

      nDevices++;
    } else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("Done\n");

  delay(5000);  // wait 5 seconds for the next I2C scan
}

Are you soldered the display pins, that pointed by @StefanL38 in post #17 ?

This i2c scanner know nothing about cd4051 multiplexer and can't used with it.

Does your multiplexer board have pull-up resistors for the address pins? Does the I2C scanner detect the multiplexer?

@waokasha_99
Are you test your circuit with two displays through multiplexer or as a single display alone?

I changed to a tca9548a multiplexer.
Also i didn't solder yet but connected them directly to the breadboard.

it doesn't matter, standard I2c scan code can't view display behind the multiplexer. (edited)

Your displays on photo not has a pins, just a holes, you can't connect them to breadboard.

Do you understand that you are wasting the time of those who are trying to help you by not putting together the hardware properly?

I connected pull up resistors, and the I2C scanner does not detect the multiplexer. Still the same issue.

I'll try the I2C scanner without the multiplexer, and the oled screens came with external pins to connect to the breadboard so i used them like so:

I'm kinda new to all arduino so i really appreciate the help.

If these pins are not soldered, they will not make reliable contact. There is no point in testing a project with such a connection.

By the way, how is your multiplexer connected? Are its pins soldered?

According to the picture, no:

I think there is no point in continuing until you solder the pins to the displays and multiplexer.
Good luck for your project.

2 Likes

I second that

Sure this works. I have connected a

  • TMP117 I²C 0,1°C-precise tempereature-sensor on I²C-Bus 0
  • SHT31 I²C temperature and humidity sensor on I²C-Bus1
  • GY21 I²C temperature and humidity sensor on I²C-Bus 2

I used this modified I2C-Scanner adpated to use with an ESP32

// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
// a detailed explanation how these macros work is given in this tutorial
// https://forum.arduino.cc/t/comfortable-serial-debug-output-short-to-write-fixed-text-name-and-content-of-any-variable-code-example/888298

#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval) \
  { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  }

#define dbgc(myFixedText, variableName) \
  { \
    static long lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }

#define dbgcf(myFixedText, variableName) \
  { \
    static float lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  }
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *



// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    https://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>

#define I2C_SDA 21
#define I2C_SCL 22

void TCA9548A(uint8_t p_busNr) {
  Wire.beginTransmission(0x70);  // TCA9548A address is 0x70
  Wire.write(1 << p_busNr);          // send byte to select bus
  Wire.endTransmission();
}

void scanTheI2C_Bus() {
  int nDevices = 0;

  for (byte address = 1; address < 127; ++address) {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    byte error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.print(address, HEX);
      Serial.println("  !");

      ++nDevices;
    } else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0) {
    Serial.println("No I2C devices found\n");
  } else {
    Serial.println("done\n");
  }
}


void setup() {
  //Wire.begin();
  Wire.begin(I2C_SDA, I2C_SCL);

  Serial.begin(115200);
  while (!Serial); // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

void loop() {

  TCA9548A(0);
  Serial.println("Scanning... Bus 0");
  scanTheI2C_Bus();

  TCA9548A(1);
  Serial.println("Scanning... Bus 1");
  scanTheI2C_Bus();

  TCA9548A(2);
  Serial.println("Scanning... Bus 2");
  scanTheI2C_Bus();

  delay(5000); // Wait 5 seconds for next scan
}

and I get this printed to the serial monitor

Scanning... Bus 0
I2C device found at address 0x48  !
I2C device found at address 0x70  !
done

Scanning... Bus 1
I2C device found at address 0x44  !
I2C device found at address 0x70  !
done

Scanning... Bus 2
I2C device found at address 0x40  !
I2C device found at address 0x70  !
done

0x70 is the multiplexer itself
the other adresses are the sensors

I would have been astonished if it would have not worked.
Such a multiplexer must work this way:

connect pins towards the microcontroller to 1 of 8 buses
and then behave like there is no multiplexer.
Otherwise it would not work

best regards Stefan

You write “it works” and then completely refute yourself by showing how you had to rewrite the scanner to make it actually work.

You made a generalised saying "I2C scan code can't be used with multiplexer"

Yes you are partially right. I started with the "standard" I2C scan code. It worked too.
It was just scanning the bus 0. Because this is what the multiplexer is set to as default value after powerup.

The serial printing is

Scanning... Bus 0
I2C device found at address 0x48  !
I2C device found at address 0x70  !
done

Then - like I wrote - I modified the code to switch the multiplexer to the different bus-channels
To me the important thing is: Now it is specified and described how to make it work with a TCA9548A 8 channel I2C-multiplexer.

1 Like

Ok, you are winner :slight_smile:
I just edited my too generalised saying in the post #28.


Boom soldered, still only one screen showing "Hello world" and the do while loop repeating 8 times, while the second screen is off.

I just soldered them, you can see the pics above, still same issues.

Also i tried the I2C scanner you provided and gave me this output:

Scanning... Bus 0
I2C device found at address 0x3C  !
I2C device found at address 0x70  !
done

Scanning... Bus 1
I2C device found at address 0x3C  !
I2C device found at address 0x70  !
done

Scanning... Bus 2
I2C device found at address 0x70  !
done

What does that mean?

It means

EXACTLY

what the serial printing says:

On Bus 0
0x3C OLED-display found at adress 3C
0x70 multiplexer found at adress 70

On Bus 1
0x3C OLED-display found at adress 3C
0x70 multiplexer found at adress 70

On Bus 2
0x70 multiplexer found at adress 70

So the I2C-devices are recognised

This is a unprecise description
to eliminate each and every room for mis-interpretation you should describe the watched behaviour very precise and in detail

You can try to safe time by posting quick
which as you can see will waste time because of asking back for the details

Okay so here are the problems we eliminated:

  1. Wires being loose and not precise
  2. Connections being incorrect
  3. Board not scanning the connected devices
  4. Code being incorrect

Watched behaivior:

  1. Screen on bus 0 not displaying anything
  2. Screen on bus 1 displaying "Hello World!"

Debugging showed that the do while loop is repeating 8 times and then exiting.