Need basic help using TCA9548A Multiplexer with multiple I2C displays

  • Project: Analog Midi Controller. A series of rotary encoders send midi data. There is one small OLED display for each rotary encoder to indicate the current value of the parameter (a circle with a segment simulates the position of a potentiometer).

  • Device: Arduino MEGA

  • Current status of the program: it is working fine with one single rotary encoder and one single display (connected directly to the Arduino I2C, not to the Multiplexer). I include the sketch here as an attached file (disclaimer: I am a beginner; I’ve made that program cannibalizing small parts from different sources and using many hours of trial-and-error)

I have connected the I2C displays to the multiplexer and I have run the test script from Adafruit to verify that the multiplexer is detecting the I2C displays:

TCAScanner ready!
TCA Port #0
Found I2C 0x3D
TCA Port #1
Found I2C 0x3C …

So far so good! I know that the multiplexer detects the displays, but I am stacked here. I don’t know how to print to the different I2C displays from my program.

If someone could kindly provide a sample sketch showing how to use multiple i2C with the TCA9548A multiplexer I would be very grateful :slight_smile:

Is there some basic example for printing “Hello World 1”, “Hello World 2”, etc on multiple displays using the TCA9548A?

Thank you!

AxeAnalog_C10.ino (10.2 KB)

Why are you trying to use a mulitplexer?

I2C is a bus and can have many devices on it - provided that they have different I2C address.

Mark

I am using a multiplexer because those displays only have the possibility of 2 different addresses (selected with a soldered jumper), and I need a total of 10 displays

According to the datasheet you select the channel you wish to talk on buy sending the channel id to the multiplexer on its I2C address - thing of it as an additional I2C device.

After you have set the channel you procced as normal for I2C.

Mark

Thank you for the information, Mark.

I have prepared this sketch, but it is only writing at the display on port 1, not on port 0 and port 2

#include "Wire.h"
#include <U8glib.h>
extern "C" { 
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}
#define TCAADDR 0x70 // TCA9548A Encoder address
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_FAST);  // Fast I2C / TWI 
 
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}


void setup(){
Serial.begin(9600);
}

void loop(){

    tcaselect(0);
  u8g.firstPage();  
  do {
      u8g.setFont(u8g_font_unifont);
      u8g.drawStr(0, 13, "I am at Port 0");
  } while( u8g.nextPage() );

delay(500);
  
  tcaselect(1);
  u8g.firstPage();  
  do {
      u8g.setFont(u8g_font_unifont);
      u8g.drawStr(0, 13, "I am at Port 1");
  } while( u8g.nextPage() );

delay(500);

    tcaselect(2);
  u8g.firstPage();  
  do {
      u8g.setFont(u8g_font_unifont);
      u8g.drawStr(0, 13, "I am at Port 2");
  } while( u8g.nextPage() );
  
delay(500);

}

Try the scanner code here Wiring & Test | Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout | Adafruit Learning System does it show all the displays you have?.

Mark

Yes, all displays are recognized when running the test. Now I have 7 displays connected from ports 0 to 6

TCAScanner ready!
TCA Port #0
Found I2C 0x3C
TCA Port #1
Found I2C 0x3C
TCA Port #2
Found I2C 0x3C
TCA Port #3
Found I2C 0x3C
TCA Port #4
Found I2C 0x3C
TCA Port #5
Found I2C 0x3C
TCA Port #6
Found I2C 0x3C
TCA Port #7
done

I have discovered a strange behavior when I was uploading the code several times:

#include "Wire.h"
#include <U8glib.h>
extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}
#define TCAADDR 0x70 // TCA9548A Encoder address
char tmp_string[8];    //Temp. to convert numeric values to string before print to OLED display
int n=0;
uint8_t t=0;
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_FAST);  // Fast I2C / TWI
 
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission(); 
}


void setup(){
}

void draw(void) {
 
         u8g.setFont(u8g_font_ncenB10);
         u8g.drawStr(0, 13, "Port =");
         itoa(t, tmp_string, 10);  
         u8g.drawStr(50, 13, tmp_string);
        
         u8g.drawStr(0, 50, "n =");
         itoa(n, tmp_string, 10);  
         u8g.setFont(u8g_font_ncenB18);
         u8g.drawStr(25, 50, tmp_string);

}

void loop(){

    for (t=0; t<7; t++) {
      tcaselect(t);
 

  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  delay(100);
        }      

n=n+1;
delay(500);

}

When I upload the program for the first time, only one display is working.
As I keep uploading the program more times, more displays are appearing (one by one, but sometimes it requires to upload it more than one time to make the nxt display to appear) :o
After having uploaded the program 10 or 15 times, all the 7 displays are working.
When resetting power to the Arduino, only one display is working. Then the program needs to be uploaded again 10 or 15 times in order to make all the displays to work.

There must be something wrong with that code. :confused:

Here is the pic of the thing. Just for fun

SOLVED! :slight_smile:

It is necessary to call the u8g.begin() init code for each display.

I’ve found the answer here: http://forum.arduino.cc/index.php?topic=254945.0

Here is the corrected code for testing the displays:

#include "Wire.h"
#include <U8glib.h>
#define TCAADDR 0x70 // TCA9548A Encoder address

char tmp_string[8];  //Temp string to convert numeric values to string before print to OLED display
int n=0;             // Loop counter, to verify that data is updated at the display
uint8_t t=0;         // Port selection (0...7)

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_FAST);  // Fast I2C / TWI
 
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission(); 
}

void setup(){
  DisplayInit();
}

void draw(void) {

         u8g.setFont(u8g_font_ncenB10);
         u8g.drawStr(0, 13, "Port =");
         itoa(t, tmp_string, 10);  
         u8g.drawStr(50, 13, tmp_string);
        
         u8g.drawStr(0, 50, "n =");
         itoa(n, tmp_string, 10);  
         u8g.setFont(u8g_font_ncenB18);
         u8g.drawStr(25, 50, tmp_string);
}

void DisplayInit(){
    for (t=0; t<7; t++) {
      tcaselect(t);
                u8g.firstPage();  
                do {
                    u8g.begin();  // Initialize display
                   } while( u8g.nextPage() );
        }      
}

void loop(){

    for (t=0; t<7; t++) {
      tcaselect(t);

  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
 delay(50);
        }      

n=n+1;
delay(500);
}