OLED Display SSD1306 very slow

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
hok
 
Posts: 2
Joined: Thu Mar 14, 2019 5:42 pm

OLED Display SSD1306 very slow

Post by hok »

I'm trying to use a SSD1306 128x64 monochrome OLED connected to an Arduino Uno via I2C to display graphics for a game.

However, the display is way too slow. It takes 330 ms for a call to display() even when nothing is drawn on it.

Attached below is a small sketch, which does nothing except calling display() and measuring the time.

The serial monitor shows 330 for each loop. I get the same result when I display a few rectangles and text, so it's independent of the contents.

I'd understand if transferring data to the screen takes some time, but since nothing is displayed there is nothing to transfer.

I don't know much about the internals of I2C. But it supports speeds around 100kbit/s and more, so even sending the entire screen of 128x64 bits shouldn't take more than 1/10th of a second.

Is it a flaw in the library, or is speed limited by the diplay?

Any help is welcome, thanks!

Code: Select all

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4 // not used
Adafruit_SSD1306 display(OLED_RESET);

long tstart = 0;
long tstop = 0;

void setup()   {                

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  
  Serial.begin(9600);
  tstart = millis();
}

void loop() {

  display.display();

//  delay(10);

  tstop = millis();
  String text = "";
  text.concat(tstop-tstart);
  Serial.println(text);
  tstart = tstop;
}

User avatar
adafruit_support_carter
 
Posts: 29150
Joined: Tue Nov 29, 2016 2:45 pm

Re: OLED Display SSD1306 very slow

Post by adafruit_support_carter »

The display command writes out the entire contents of the buffer regardless of its contents:
https://github.com/adafruit/Adafruit_SS ... 6.cpp#L919
So it will take the same time regardless.

The bottle neck is generally as you expected - the time it takes to write all this out. I2C is not super fast. You can try changing the clock:
https://www.arduino.cc/en/Reference/WireSetClock
to see if a simple speed up might help.

User avatar
oesterle
 
Posts: 806
Joined: Tue Sep 17, 2013 11:32 pm

Re: OLED Display SSD1306 very slow

Post by oesterle »

Hi, hok!

Since your code indicates that you are not using an OLED_RESET pin, you should set that to -1.
You'll also want to pass in the dimensions of the display you're using.

Try this (untested code):

Code: Select all

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
If I read correctly, the Adafruit_SSD1306 library already sets the Wire clock to 400KHz (when possible) during calls. I think this would override a Wire.setClock().

I'd also consider increasing the Serial speed to avoid that slowing down your loop() (probably minimal). In your setup(), try this:

Code: Select all

Serial.begin(115200);
In the Arduino IDE's Serial Monitor, be sure to change the baud rate to match (lower right corner of Serial Monitor window).

Another user had a similar issue recently with a third-party SSD1306 breakout, and this seemed to work well for them. Let me know if this works for you.

What are you making?

Cheers,

Eric

User avatar
hok
 
Posts: 2
Joined: Thu Mar 14, 2019 5:42 pm

Re: OLED Display SSD1306 very slow

Post by hok »

Hi Eric,

thanks a lot for your hint. Using the correct constructor for Adafruit_SSD1306 did the trick.

The time for a loop is now down to 37 msec, which gives me a whopping 27 FPS (minus my code).

The problem was that I had copied old code from the web which used a legacy constructor, without really looking into it. In retrospect I should have suspected something was wrong because I had to tweak the screen dimensions in Adafruit_SSD1306.h.

In fact, &Wire and -1 are the default anyway, so passing the screen dimension is enough:

Code: Select all

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

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT);
Changing the Wire clock as suggested by adafruit_support_carter doesn't change anything.
oesterle wrote:Another user had a similar issue recently with a third-party SSD1306 breakout, and this seemed to work well for them. Let me know if this works for you.
Oh, it's the same issue. Odd that I didn't find that topic when I searched before posting my own. My bad.
oesterle wrote:What are you making?
Image

Pong! It's my first attempt at an arduino project. Will add a shiny box soon.
It's amazing how easy the arduino makes tinkering. Some hardware, some wires, some coding and you're done. And the community is right there to help.
Cheers,
Heiko

User avatar
adafruit_support_carter
 
Posts: 29150
Joined: Tue Nov 29, 2016 2:45 pm

Re: OLED Display SSD1306 very slow

Post by adafruit_support_carter »

Glad you got it working.

The GFX library and lots of display libs have received some recent updates. And tweaks are ongoing. Does indeed look like you were using a deprecated constructor here:

Code: Select all

Adafruit_SSD1306 display(OLED_RESET);
https://github.com/adafruit/Adafruit_SS ... 306.h#L129

In fact, &Wire and -1 are the default anyway, so passing the screen dimension is enough:
Yep:
https://github.com/adafruit/Adafruit_SS ... 306.h#L118
and sounds like that did the trick.

The I2C clock settings also seem to know be auto changed under the hood via the new clkDuring and clkAfter parameters:
https://github.com/adafruit/Adafruit_SS ... 6.cpp#L146

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”