Trouble separating data to be shown on two I2C displays

I am still trying to get two displays to work properly. Steps taken and things learned so far:

Devices:

Particle Photon
0.91 in 128x64 I2C OLED displays (2x)

  1. I bought two new displays and, on one, moved the resistor on the back to change its address.

  2. I run I2C scanner and see:

I2C device found at address 0x3C !
I2C device found at address 0x3D !

  1. I am running my sketch on a Particle Photon, which should have enough memory to handle two displays using the Adafruit SSD1306 library.
#include <Adafruit_SSD1306.h>

// LEFT DISPLAY WITH I2C
// Display SDA  -> Photon D0
// Display SLC  -> Photon D1
#define OLED_RESET_left -1
#define OLED_RESET_right -1
Adafruit_SSD1306 display_left(OLED_RESET_left);
Adafruit_SSD1306 display_right(OLED_RESET_right);

void setup() {

  Serial.begin(9600);
  //Serial.println("Start setup");

  // Start the displays, show a confirmation text.
  display_left.begin(SSD1306_SWITCHCAPVCC, 0x3C);     // I2C
  display_right.begin(SSD1306_SWITCHCAPVCC, 0x3D);   // I2C

  display_left.clearDisplay();
  display_left.setRotation(0);
  display_left.setCursor(0, 20);
  display_left.setTextSize(2);
  display_left.setTextColor(WHITE);

  display_left.println("Setup:");
  display_left.println("LEFT");
  display_left.display();
  

  display_right.clearDisplay();
  display_right.setRotation(0);
  display_right.setCursor(0, 20);
  display_right.setTextSize(2);
  display_right.setTextColor(WHITE);

  display_right.println("Setup:");
  display_right.println("RIGHT");
  display_right.display();

  delay(2000);

  display_left.clearDisplay();
  display_left.display();

  display_right.clearDisplay();
  display_right.display();

}

void loop() {

  // -------- LEFT DISPLAY ----------- //

  display_left.setCursor(0, 20);
  display_left.setTextSize(1);
  display_left.setTextColor(WHITE);

  display_left.print("Loop: LEFT.");
  
  display_left.display();


  // -------- RIGHT DISPLAY ---------- //
  
  display_right.setCursor(0, 30);
  display_right.setTextSize(1);
  display_right.setTextColor(WHITE);

  display_right.print("Loop: RIGHT.");
  
  display_right.display();

}
  1. When I upload the sketch, the displays correctly show “Setup: LEFT” on the left, and “Setup: RIGHT” on the right. Good.

Setup code running:

  1. When it gets to the loop, however, both “Loop: LEFT” and “Loop: RIGHT” display on both displays.

Loop code running:

I don’t understand what the difference is - why the code in the Setup works as expected, but the code in the loop doesn’t.

-FWIW, I had been experimenting with different mixes of SPI and I2C, before the newest displays arrived, and had the same problem. Seems like I’m missing / misunderstanding something basic.

Thanks for any help!

Hi,
Could you try to put

display_left.clearDisplay();

and

display_right.clearDisplay();

right after

display_left.display();

and

display_right.display();

in your loop :thinking:

I’m not sure but looks like i2c buffer is not clean before start talking to 2-nd display

I doubt it’s the I2C buffer, but rather the static screen buffer of the library

static uint8_t buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8]

You can always clear the buffer or you use this library instead.
It uses a dynamically allocated screen buffer for each individual display.

3 Likes

Thanks ScruffR
I knew that “bells are rings somewhere but i didn’t know where” :slight_smile:

Thank you again, for a very fast response! I really appreciate it!

I seem to have two issues with this, though, and a third that isn’t related and should probably be a different thread, so ignore that one (below) if it breaks the forum rules.

  1. I looked at the ADAFRUIT_SSD1306_RK library example briefly, and it looked like it was basically the same on the front end, so I put it in my sketch and removed the Adafruit_SSD1306.h line to see what would happen.

When I compile it I get a bunch of errors from the library’s code (not mine).

Errors:

I’m not sure what to do about that, since they are in the library, not in my code? Here’s the _RK library code - I think - for the first error, for example:

166 Adafruit_SSD1306::Adafruit_SSD1306(uint8_t w, uint8_t h, TwoWire *twi,
167  int8_t rst_pin, uint32_t clkDuring, uint32_t clkAfter) :
168  Adafruit_GFX(w, h), spi(NULL), wire(twi ? twi : &Wire), buffer(NULL),
169  mosiPin(-1), clkPin(-1), dcPin(-1), csPin(-1), rstPin(rst_pin),
170   wireClk(clkDuring), restoreClk(clkAfter) {
171 }
  1. When I delete the include line for the ADAFRUIT_SSD1306_RK.h and try to go back to the Adafruit_SSD1306.h library (to try to figure out what you mean by “you can always clear the buffer”) I still get errors that mention the ADAFRUIT_SSD1306_RK library, even though it is not included in my sketch any more.

I have tried Settings > Clear Cache, but that doesn’t work. I remove ALL library include lines, clear cache, and I get different error messages - the compiler complains about my calls to the library that isn’t there, which is to be expected - but when I re-include the Adafruit_SSD1306.h I get the ADAFRUIT_SSD1306_RK errors again.

I’ve even cleared the cache, closed the Web IDE browser window, and re-opened, and I still get errors for a library I’m not currently including.

Sorry if this is something simple that I have done wrong.

  1. This touches on a separate thing that confuses me: if I manually type:
#include <Adafruit_SSD1306.h>

Then the Web IDE complains it doesn’t know what I’m talking about.

If I use the Web IDE’s Library panel to include the library in my project it generally works…and the line in my code looks identical to what I had typed:

#include <Adafruit_SSD1306.h>

What is magical and necessary about using the Web IDE’s include library functionality? I’d just like to understand to make sure I’m doing things right, and to be as efficient as possible.

I ended up creating a new sketch and copying the code over, and I could get it to compile without any _RK library errors. I still don’t understand what happened, but at least I know a workaround.

Since I can’t get the _RK library to work, I tried to think about your other suggestion, to always clear the buffer. Is this what you meant, just simply:

display_right.clearDisplay();

So I put that in for each screen, and it does indeed fix the problem! Thank you!

If I put this code for each display - just adding that top clearDisplay() - then I get the correct LEFT / RIGHT on the correct display!

  // -------- RIGHT DISPLAY ---------- //
  display_right.clearDisplay();

  display_right.setCursor(0, 30);
  display_right.setTextSize(1);
  display_right.setTextColor(WHITE);

  display_right.print("Loop: RIGHT.");

  display_right.display();

I don’t understand why, when I have set up the displays as separate instances and address them separately, but does that mean it’s a …bug? in the library - and presumably one that the _RK library addresses?

My current understanding: using the _RK library would still be better, since it (correctly?) handles the separate buffers? I just need to figure out why I get the errors when I try to use it.

If you can post a SHARE THIS REVISION link for your project we can have a try with gettint Rick’s library to work.

Haven’t done that before, but I think I got it - is this what you mean?

https://go.particle.io/shared_apps/5e3aeff4c1d2bb0007f52eb0

So that is the version with Rick’s library, with which I get those errors, i.e., not the sketch I used in my last message, with the regular Adafruit library and the new .clearDisplay() lines that also “works”.

Merely removing the #include statement is not enough.
You need to remove the old library from your project via the image symbol next to the library name.

image

Once that library is gone your project compiles fine for me.

1 Like

Ok, so, good to know. I guess I was used to the Arduino IDE, where just the code was what controlled what was included.

…so I remove the old library and it does compile…but as soon as it finishes uploading my Photon starts blinking the red SOS.

I assume I’m still doing something dumb, so I’ll try to start from fresh and get it all straight.

How many slow blinks after the SOS?

5 which means…“usage fault”?

I created a new sketch, copied all of the code except for the include lines, then included only Rick’s library:

https://go.particle.io/shared_apps/5e3af3d4b164d80016812ea0

I never tested my library with 2 I2C SSD1306 displays, but it definitely works with 2 SPI displays:

I also tested 4 SPI displays, which also works surprisingly well.

Good to know! I’ll remember that after I use up the six I2C displays I just ordered. :wink:

I had thought that I2C was ok, even preferable, for me, since it simplified the wiring, and I had read that I could basically have as many I2C devices as I wanted using only two wires.

In the course of working through these problems and learning about the differences between SPI and I2C, I see where it’s not so black and white (and the “as many devices as I want” is still limited to their own somewhat-hardcoded addresses).

I guess it makes sense to have a mix of SPI and I2C displays on hand. Too bad I just bought enough I2C devices to last me a while.

In general I prefer I2C since there are many fewer connections. However, the exception is for multiple displays where SPI is usually better.

Lots of information about these displays here:

1 Like

I assume the two displays use the same framebuffer since they both use one Adafruit_GFX-library and do maybe not reserve their own buffers. That would make sense since it works when you clear the buffer between writing to the displays and sums up if you don’t.

Yes, that was already established in the second reply to the original post :wink:

1 Like

Oh… I honestly just read about this topic in the forum-email and didn’t read the whole thread :man_facepalming:t2:.