I am porting an old project from a 16MHz Nano to an 8MHz ATMega328P on a breadboard and just hit an odd behaviour on everything related to time (I guess), but that compromises OLED performance most.
I am using Adafruit_SSD1306 lib latest (2.5.1) and everything looks fines except everything is slow, like in half speed. Did some dirty check on I2C clock and it looks low (around 35KHz).
A double checked on lfuse value returns 0xE2, giving us 8MHz clk with 1:1 prescaler (CKDIV8 unprogrammed). So it looks alright.
I also loaded a clean code to test the OLED alone with the same poor speed.
As stated by others in the forum, I'd tried to fiddle with the TWFR values but it seems not straight forward because of the new SSD1306 constructors.
Are you using the graphics? If not try the SSD1306Ascii library by Bill Geirman. It is only character based but reasonably fast in an 8Meg.
I don't use the adafruit GFX but I would guess it is written to go as fast as the processor will allow. Now you are using an 8Mhz clock vs a 16Mhz clock, so running at 1/2 the speed is expected.
You are right about Adafruit's been written to top speed. All specs, lib and M328 points it is OK to run I2C @ 400KHz with a 8MHz cpu_clk. This is what every documentation I've found states.
I am fiddling some simple benchmarks and should return soon.
Hi there, @gilshultz. That sure makes sense but let me share some thoughts.
I've just checked a weird behaviour. Take a look at this snippet and comments:
// Benchmark OLED write time and delay time
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.print(F("Clear: "));
display.println(millis()); // our t0 ref; got ~54
display.display();
delay(500);
display.print(F("delay: "));
display.println(millis());
display.println(F("Wait 10 secs!"));
display.display(); // shows something near a 500ms eval time (~593)
for (byte i=0; i<10; i++) { // now, this loop is showing a 2x timing issue
display.print(F("."));
display.display();
delay(1000);
} // should print 10 dots in 10 secs, but it takes 20!!! I measured with a chronometer oO
So, I do believe there is some hw/sw issue related to the cpu_clk being 8MHz and I2C/delay functions behaviour. Seem that invoking display and looping affects the delay function somehow.
I was using VSCode w Arduino ext to upload my code and after your question did some checks:
VSCode is using board Arduino Nano w/ M328 @ 16MHz);
Code is programmed with "Upload using programmer" command;
In this context we get the behaviour I shared here with the 10sec loop taking double time;
So, moving to Arduino IDE, could select Arduino on a Breadboard M328 8MHz trying to follow your clues, and now we have a twist as OLED performance is terrible but the loop runs at the correct speed and completes in 10 secs o.O
One important remark here is that I am using no bootloader and upload directly through Arduino as ISP programmer.
Here's the content of boards.txt file for the selected board/processor in Arduino IDE:
So, I guess I've got two issues to resolve:
a) why this happens even when using Arduino IDE where all recommended settings are available;
b) why VSCode Arduino cannot find the M328BB hardware options, even sourcing the Arduino IDE paths;
For now, let's focus on item "a" and get timing right.
It shows 1811 bytes used. And I notice no random pixels.
Also I have very few nested function calls, say, three levels deep but pass no params. So stack is not abused. Most of function calls are one level.
The sketch animates a splash screen (64x64) and then all display activity is text based.
Update: sorry about typo in this response! Sketch uses 811 bytes RAM
I found the solution!
After checking the Arduino IDE end-to-end I noticed I was using Adafruit SSD1306 latest version (2.5.1) but the Arduino core libs where outdated. So I decided to give it a kick and installed all new from scratch and voilá: timing is all good, even at 8MHz the display is smooth both on splash animation and text performance. My rational is that the latest SSD_1316 lib depends on recent Wiring versions and they probably were having an argument =]
Still can't select the M328 Breadboard option in VSCode but it is ok to use Arduino IDE until I get this issue resolved.
Thank you all for your contributions that helped me find the solution and tune the sketch up.