Multiple OLED SSD1306 Displays using 2IC

HI all,

I'm very new to Arduino (and C+ programming language for that matter). I have an Arduino UNO running a program I am writing to display information onto a cheap 0.96" OLED (128x64) using the SSD1306 controller on 2IC.

I want to add a second display to load some more information coming in from sensors, what I'm trying to work out is how to communicate with that 2nd display?

Both OLED's have address jumpers so I can address them separately (0x3C and 0x3D). I've test run both the Adafruit lib and the u8glib which I can use to display all my data on a single display, but how do I setup two displays based on the addresses above?

In the Adafruit library for example, there is a field there to specify the address, which is fine, but I really need to run two instances of the library to make that work?

On a side note, i read that it may be easier using SPI, these OLED's I'm using a 4 Pin 2IC, but they claim they can run SPI as well, but there is no indication on the spec or PCB labels on how to wire it, OLED's are something like these here: http://www.ebay.com.au/itm/0-96-I2C-IIC-SPI-Serial-128X64-White-OLED-LCD-LED-Display-Module-fr-Arduino-dwx-/351048340044?pt=AU_B_I_Electrical_Test_Equipment&hash=item51bc1c924c&_uhb=1

Would appreciate any help!

For u8glib, this has been discussed here:

Oliver

Thanks Oliver, that is exactly what I was looking for, don't know how I missed this searching, spent hours looking!

This approach may even work on the adafruit library, I'll be test both tonight and post back with results for anyone else trying to do the same thing.

Cheers, Matt

Hi Oliver,

Thank you very much for your advice, I've run up that code in the other post and I can now address the two displays, the problem I am having now is that I can't address them at the same time within the runtime. For example, I'm just using the HelloWorld example as a test, so if I declare/change the variable at the start of the loop like this:

void loop(void) {
   I2C_SLA = 0x3c*2;   // second display
//     I2C_SLA = 0x3d*2;   // first display
  // picture loop
  u8g.firstPage();  
  do {
    draw();
    } while( u8g.nextPage() );
  
  
  // rebuild the picture after some delay
  delay(500);
}

This will display 'Hello World' on one display, if I then comment out display 2 and uncomment display 1, when I compile and run, 'Hello World' will display on the other display fine.

However if I try and display content on both displays at the same time, it seems to ignore the 2nd display and load everything into the first display. I have tried a few different ways, which include:

Attempt 1:

void loop(void) {
//   I2C_SLA = 0x3c*2;   // second display
//   I2C_SLA = 0x3d*2;   // first display
  // picture loop
  u8g.firstPage();  
  do {
    draw();
    draw2();
    } while( u8g.nextPage() );
  
  
  // rebuild the picture after some delay
  delay(500);
}



void draw(void) {
  I2C_SLA = 0x3c*2;   // second display
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "DISPLAY1");
}

void draw2(void) {
  I2C_SLA = 0x3d*2;   // first display
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "DISPLAY2");
}

Attempt 2:

void loop(void) {
I2C_SLA = 0x3c*2;   // second display
//   I2C_SLA = 0x3d*2;   // first display
  // picture loop
  u8g.firstPage();  
  do {
    draw();
    } while( u8g.nextPage() );

//   I2C_SLA = 0x3c*2;   // second display
I2C_SLA = 0x3d*2;   // first display
  // picture loop
  u8g.firstPage();  
  do {
    draw2();
    } while( u8g.nextPage() );  
  
  // rebuild the picture after some delay
  delay(500);
}


void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "DISPLAY1");
}

void draw2(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "DISPLAY2");
}

I'm new to this library so I could be calling it wrong, could you advise if I'm not using it correctly?

Thanks in advance.

Matt

hmm ok, i did some more thinking on the problem. You might need to use the ".begin()" command before each loops for attempt 2. Like this:

void loop(void) {
I2C_SLA = 0x3c*2;   // second display
//   I2C_SLA = 0x3d*2;   // first display
  u8g.begin();
  // picture loop
  u8g.firstPage();  
  do {
    draw();
    } while( u8g.nextPage() );

//   I2C_SLA = 0x3c*2;   // second display
I2C_SLA = 0x3d*2;   // first display
  u8g.begin();
  // picture loop
  u8g.firstPage();  
  do {
    draw2();
    } while( u8g.nextPage() );  
  
  // rebuild the picture after some delay
  delay(500);
}

Will this work?

Oliver

Hi Oliver,

Getting much closer, this works, but each time it loops it clears the screen and then writes to it again?

So Now i'm getting 'Display 1' on the left display and 'Display 2' on the other which is great.

But the words display 1 and display 2 are flashing on and off as it loops?

I remove the 500 delay which just made it flash faster, I suspect begin is clearing the screen instead of just writing over the top or something like that?

Getting closer though! Thanks!

Fixed!!!

I posted in the original forum post and got some sample code there I could reverse engineer with slight modifications. My complete code is

Updated ug8_com_arduino_ssd_i2c.c file:

//#define I2C_SLA		(0x7A)
uint8_t I2C_SLA = 0x7A;

Sample Sketch (almost identical to the sample post here: http://forum.arduino.cc/index.php?PHPSESSID=1muoka6km36cnvf9f3edlcpmd2&topic=219419.45 other than the 3rd line.

#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);
extern uint8_t I2C_SLA;

boolean redraw_display_one = false;
boolean redraw_display_two = false;

void setup()
{
  I2C_SLA = 0x078;
  u8g.firstPage();
  do
  {
    draw_message_one();
  }
  while(u8g.nextPage());

  delay(10);

  I2C_SLA = 0x07A; 
  u8g.firstPage();
  do
  {
    draw_message_two();
  }
  while(u8g.nextPage());
}

void loop()
{
  if (redraw_display_one)
  {
    I2C_SLA = 0x078;

    u8g.firstPage();
    do
    {
      draw_message_two();
    }
    while(u8g.nextPage());

    redraw_display_one = false;
  }

  if (redraw_display_two)
  {
    I2C_SLA = 0x07A;
    u8g.firstPage(); 
    do
    {
      draw_message_one();
    }
    while(u8g.nextPage());
    redraw_display_two = false;
  }
  
  unsigned long time = millis();
  
  if (time > 5000 && time < 5033)
  {
    redraw_display_one = true;
    redraw_display_two = true;
  }
}

void draw_message_one()
{
  u8g.setFont(u8g_font_fub20);
  u8g.drawStr(12, 28, "Hello");
  u8g.drawStr(12, 58, "World");
}

void draw_message_two()
{
  u8g.setFont(u8g_font_fub20);
  u8g.drawStr(12, 28, "Goodbye");
  u8g.drawStr(12, 58, "World");
}

Works perfectly now and I have complete control over the displays, thanks to your library!

Another idea from my side would have been to call .Begin() once only.
.Begin() will not clear but display the screen for some milliseconds. This will cause the flicker.
But i am glad to see that it is working.

Oliver

Thank you! And what value should be used for the third display? First = 0x07A; Second = 0x078; The third = ????

Hi all.

I have several displays ssd1306 what i bought on AliExpress

And i search method for draw different information on Two displays connected to one Arduino

but modules what i have are slightly different

they do not have a jumper for selecting addresses |469x500

Any solution for me?

I solved the problem

On photo of another Display posted by unixbob ( post here )

We could see that the address switch is due to supply a logic 0 or logic 1 to pin №15 of display flex

But on my Display this pin connected directly to GND (logic 0)

What need todo: 1) unstick display 2) cut path on the PCB from Flex pin #15 to GND 3) solder thin wire from pin 15 to vcc

voila - we have two displays with different addresses

|355x500 |466x500

Hello,

I am looking to use a Adafruit TCA9548A I2C multiplexer to connect 8 oled displays all with the same address

https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout

I am a beginner to Arduino. I am wondering how to go about referring to the different displays in my sketch

Thank you, Jack

Hi, Sand_r

it is Works.

Hi mates! I have the same display and I need to put two of them in the same I2C bus, there are 2 resistors (jumpers) which I suppose determine the I2C address, do you know which address will be if I change them?
Which one you suggest to change? Thank you!

PS: there are two jumpers, so I suppose it can be possible to put in the same bus up to 4 displays, isn’t it?

I came up with a solution for driving multiple displays which use the same address:

Controlling many OLED displays with a few GPIO lines

Thank you for your kind answer, yes this is a way, but it took out resurces from processor and we can loose real time data managing because the CPU will be busy to simulate software the I2C bus.§

I would kindly know from someone if I can change the I2C address by R3 R4 as in the picture.. or as I read somewhere they are used to change bus type, from I2C to SPI, etc. Thank you

GiovanniG11: Hi mates! I have the same display and I need to put two of them in the same I2C bus, there are 2 resistors (jumpers) which I suppose determine the I2C address, do you know which address will be if I change them? Which one you suggest to change? Thank you!

PS: there are two jumpers, so I suppose it can be possible to put in the same bus up to 4 displays, isn't it?

i think R3 and R4 headers are for changing interface default setting is for iic and change it does not help you... there are no pins for other interface

try 'Sand_r' tweak posted upper in this thread.. it works for me...