TCA9548A and Arrays

Hello,

I am trying to display similar information over 4 i2c oled displays with a TCA9548A.
Everything work smooth but I was wondering if I could shrink my code, which is very repetitive, with arrays.

Selecting the TCA9548A channels with the arrays is not a problem but I get stucked when I need to send commands to the single displays as, for each one, I should write a specif command with the name of the specific display.

#include <Wire.h> // Wire Library for I2C
#include <Adafruit_GFX.h> // Include graphics library for the display
#include <Adafruit_SSD1306.h>// Include graphics library for the display

#define OLED_RESET 4 // Reset pins not used but needed for the libraries

Adafruit_SSD1306 display0(OLED_RESET);  // Create an object for each OLED Display
Adafruit_SSD1306 display1(OLED_RESET);  // Create an object for each OLED Display
Adafruit_SSD1306 display2(OLED_RESET);  // Create an object for each OLED Display
Adafruit_SSD1306 display3(OLED_RESET);  // Create an object for each OLED Display

#define TCAADDR 0x70 // TCA9548A

int displayindex[4] = {0, 1, 2, 3}; //TCA9548A index for the channels

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

/* This is just an incomplete draft
void displaysetup(int displayindex){
  TCA9548A(displayindex);
}*/


void
setup (void){
  display0.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display2.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display3.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

void
loop (void){
  
}

So I am wondering if I could put in an array, somehow, the first part of each command (which would be “display0”, “display1”, “display2”, “display3”) and then append it to the rest (i.e. display0.begin(SSD1306_SWITCHCAPVCC, 0x3C); ).

I tried to google but probably I am posing the question without a proper terminology.

Thank you very much!

Alessandro

presumably you would like to use a single routine to display thing (text or graphics) on different displays depending on the display.

presumably (?) you can create an array of “pointers” to display objects and pass a pointer to some display function.

Adafruit_SSD1306  *displays [] = { & display0, & display1,  & display2, & display3 };

and you can pass a display pointer using an index and displays

Thank you very much gcjr, you are becoming my angel... :-)

I tried to add the line you suggested but the compiler tells me that "display0" "was not declared in this scope" (highlighting in red the line you wrote).

Shall I make an additional declaration for all the instances of this array? If so, which type of variable may I declare?

I really feel like I have "right intuitions" when writing my code but a huge gap of knowledge. Regardless of the books I've read (and that I keep beside me) I was never able to find all these constructs. Have you got any book to suggest me? Something where all these cases are explained so that I can consult it when I get stucked?

Many many thanks!

Alessandro

You may also be able to do it like this (although I can’t see why you had problems with the previous suggestion):

#define OLED_RESET 4 // Reset pins not used but needed for the libraries

// Adafruit_SSD1306 display0(OLED_RESET);  // Create an object for each OLED Display
// Adafruit_SSD1306 display1(OLED_RESET);  // Create an object for each OLED Display
// Adafruit_SSD1306 display2(OLED_RESET);  // Create an object for each OLED Display
// Adafruit_SSD1306 display3(OLED_RESET);  // Create an object for each OLED Display

Adafruit_SSD1306 displayArray[4] = { Adafruit_SSD1306(OLED_RESET), Adafruit_SSD1306(OLED_RESET), Adafruit_SSD1306(OLED_RESET), Adafruit_SSD1306(OLED_RESET) } ;

. . .
. . .
setup() {
. . .
   for ( uint8_t i = 0 ; i < 4 ; i++ ){
       displayArray[ i ].begin(SSD1306_SWITCHCAPVCC, 0x3C);
   }
. . .
}

and here is an example which shows the above construct could even be simplified:
https://www.includehelp.com/cpp-tutorial/array-of-objects-initialization-with-constructors-in-cpp.aspx

Ale_V: I tried to add the line you suggested but the compiler tells me that "display0" "was not declared in this scope" (highlighting in red the line you wrote).

i was able to do this in my code

#include "SSD1306Wire.h"
...
SSD1306Wire  display(0x3c, 21, 22);
...
SSD1306Wire *d = & display;

you still need the declarations you had

Adafruit_SSD1306 display0(OLED_RESET);  // Create an object for each OLED Display
Adafruit_SSD1306 display1(OLED_RESET);  // Create an object for each OLED Display
Adafruit_SSD1306 display2(OLED_RESET);  // Create an object for each OLED Display
Adafruit_SSD1306 display3(OLED_RESET);  // Create an object for each OLED Display
...
Adafruit_SSD1306  *displays [] = { & display0, & display1,  & display2, & display3 };

Hello everyone,

I am terribly sorry for my late reply but I’ve had a busy week at work.

Thank you all for the codes, I have tried 6v6gt suggested firstly and it worked, I’ll also try now what gcjr has written.

One more question: I wanted to use, at the same time, some 128x32 oled displays and some 128x64.
Right now I am using Adafruit GFX Library (v 1.7.5) and Adafruit SSD1306 Wemos Mini Oled Library (v1.1.2).
The problem I am encoutering is that text displayed on the 128x64 seems to be simply the stretched version (vertically) of the 128x32.
I’ve tried to look in the code where I could describe which type of oled I am using but I couldn’t understand where it happens.
I’ve also looked at the library (SSD1306) and I’ve seen this bit of code:

/*=========================================================================
    SSD1306 Displays
    -----------------------------------------------------------------------
    The driver is used in multiple displays (128x64, 128x32, etc.).
    Select the appropriate display below to create an appropriately
    sized framebuffer, etc.

    SSD1306_128_64  128x64 pixel display

    SSD1306_128_32  128x32 pixel display

    SSD1306_96_16

    -----------------------------------------------------------------------*/
//   #define SSD1306_64_48
//   #define SSD1306_128_64
   #define SSD1306_128_32
//   #define SSD1306_96_16
/*=========================================================================*/

Is it normal that “// #define SSD1306_128_64” is set as comment?

Thank you very much!

I’ve just looked at the SSD1306 library on Github: https://github.com/adafruit/Adafruit_SSD1306/blob/master/Adafruit_SSD1306.h

It now looks like this:

#ifndef _Adafruit_SSD1306_H_
#define _Adafruit_SSD1306_H_

// ONE of the following three lines must be #defined:
//#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
#define SSD1306_128_32   ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16  ///< DEPRECATED: old way to specify 96x16 screen
// This establishes the screen dimensions in old Adafruit_SSD1306 sketches
// (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH
// AND HEIGHT ARGUMENTS).

#if defined(ARDUINO_STM32_FEATHER)
  typedef class HardwareSPI SPIClass;
#endif

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

Maybe check that you have the latest library installed and then look at an example which comes with the new library. It appears now possible to specify the screen size in the constructor. This avoids having to hack the library.

Fantastic, works beautifully!

Many thanks!