[solved] Running four OLED (I2C) displays at once?

Howdy!

I'm developing a project in which I want to use 4 OLED displays (the cheap I2C ones, as found here: Amazon.com ) to display unique messages. I'm working off of an Arduino UNO, and I am using a multiplexer (found here: DssCircuits.com is for sale | HugeDomains ) to send a unique I2C signal to each of the four screens. You can see my actual setup in the photos I've attached below (don't judge me too hard for the shoddy soldering job).

As I have it currently set up, power is going from the Arduino to the multiplexer, as well as to all four screens. The SDA/SCL lines are fed from the Arduino's A4/A5 pins to the multiplexer's input pins, and then SDA0/SCL0 through SDA3/SCL3 are sent to their respective screens. On each screen, a 4.7k resistor is placed between the VCC line and both the SDA and SCL lines. My code is a modified version of the sample sketch you can download from the multiplexer's product page, and additionally uses the u8glib to process fonts/text. I'll paste it at the bottom.

My issue is this: When I run the code, only the first screen lights up with the correct message, but the other three stay dark. At first I thought it was an issue with the multiplexer, but if I disconnect the two I2C lines from the working screen and replace them with any other screen's I2C lines, the proper message for that new line is displayed ("second", "third", "fourth"). This is the case no matter what screen begins with the first I2C lines coming from the mux (SDA0/SCL0), so it isn't an issue with how they are wired for power, either.

Can anyone help out with this? I've been beating my head against a wall for quite a while now, for a task that shouldn't be all that unusual to do. Thanks in advance!

P.S. for background on how I started out, see the post I made a couple weeks ago on the "networking" board: Sending unique information to 4 OLED displays with I2C? - Networking, Protocols, and Devices - Arduino Forum

aaaaaaand, here's my code:

#include "Wire.h"
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);	// I2C / TWI 

#define MUX         0x70  //Multiplexer Address
#define DISPLAY     0x3C  //OLED Display Address

void draw(char str[]) {
  
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_fur17);
  u8g.drawStr( 5, 40, str);
}

void setup()
{
  /* U8G portion */
 // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
  
  /* MUX Example portion */
  Wire.begin();
  Serial.begin(115200);
  mux(0);  //select Display on channel 0
  initializeDISP(DISPLAY);
  mux(1);  //select Display on channel 1
  initializeDISP(DISPLAY);
  mux(2);  //select Display on channel 2
  initializeDISP(DISPLAY);
  mux(3);  //select Display on channel 3
  initializeDISP(DISPLAY);
  mux(0xFF);  //disable all channels. This is not required
}

void loop()
{
  if (screen == 1) {
      mux(0);
      sendDISP(DISPLAY, "first");
      mux(1);
      sendDISP(DISPLAY, "second");
      mux(2);
      sendDISP(DISPLAY, "third");
      mux(3);
      sendDISP(DISPLAY, "fourth");
      mux(0xFF);
  }
  delay(3000);
}

/********************************************************
* When selecting a channel bit2 of the control register
* must be set to a logic 1 to enable channel selection.
* If bit2 is a logic zero then all channels will be disabled.
* If 0xFF is the selected channel it will disable all channels.
********************************************************/
void mux(byte channel)
{
  byte controlRegister = 0x04;  
  controlRegister |= channel;
  Wire.beginTransmission(MUX);
  if (channel == 0xFF){Wire.write(0x00);} //deselect all channels
  else {Wire.write(controlRegister);}     //set to selected channel
  Wire.endTransmission();
}

void initializeDISP(uint8_t address)
{
  Serial.println("Initiating Quick Start");
  Wire.beginTransmission(DISPLAY);
  Wire.write(0x06);
  Wire.write(0x40);
  Wire.write(0x00);
  Wire.endTransmission();  
}

void sendDISP(int _disp, char rootStr[])
{
  /* Not sure what these lines are for... */
  Wire.beginTransmission(_disp);
  Wire.write(0x04);
  Wire.endTransmission();
  
  // picture loop
  u8g.firstPage();  
  do {
    draw(rootStr);
  } while( u8g.nextPage() );
}

Hi

The problem is, that the other three displays do not receive the init code.
You need to call u8g.begin() for each of the attached OLEDs manually. u8g.begin() is called automatically if only one OLED is used, but in your case you need to switch to the four OLEDs and call u8g.begin() for each of the OLEDs.

I remember that we discussed a similar question recently here in the forum (with two OLEDs).

Oliver

Edit: Problem was discussed here (however, not sure whether this fits here): Multiple OLED SSD1306 Displays using 2IC - Displays - Arduino Forum

In your code i See only 1 adressed oled beneath the MUX adress ?
P.S. olikraus war schneller :wink:

Hi Oliver,

Brilliant! I simply added u8g.begin(); right before the picture loop in my code, and all seems to be working great.

Thanks so much!

Good to see it works.
However, for speed up do this call only once per OLED.

Oliver

olikraus:
Good to see it works.
However, for speed up do this call only once per OLED.

Oliver

Ah, that would make a lot of sense. I moved u8g.begin() from loop() to the initialiseDISP method in my code, and sure enough, it's much faster when I switch messages on the screens. Thanks again!

Im running 5 oleds with the adafruit library and it runs perfect until I want to display a logo that was working with u8glib and single oled screen. I would like to know if you can post the complete code so I can review it and get it working in my project so I can see if this library display the logo in a good shape. Thanks in advance

Hi Guys,

This is just what I have been looking for. I am currently running a dual 0.96'' OLED with selectable addresses and now I have a need to add two more OLED's.
I currently have a TCA9548A I2C Multiplexer on order and just getting all the code together for the project.

One question as to the OLED's, do I need the non-selectable OLED's or can this multiplexer work with any version of 0.96'' OLED and do they need to be all the same?

Thanks in advance..
Lance.

If you have selectable addresses, just use that pin as a ChipSelect. No problem with the 6-pin and 7-pin modules. Configure for I2C. Use the DC pin as I2C select address pin.

Ok, you end up with using almost as many GPIO pins as if you had N SPI devices. SPI would be faster than I2C anyway.

David.