I have a DFRobot 0.96" 128x64 Pixel Display (DFR0650). I hadn't realised that these displays were so slow and was investigating ways to speed things up. I'm using 4-wire SPI instead of I2C and I've checked that hardware SPI is set to the maximum clock speed on an UNO (8 MHz).
I'm using the U8g2 library and as expected the U8x8 character only mode is faster than page mode in U8g2.
What is confusing me is that software SPI is approximately 7 times faster than hardware SPI. I was not expecting that. Does anyone know why this might be the case?
In case I have made some stupid programming mistake I have included the test sketch below. The only change between software and hardware SPI is the u8x8 constructor.
I tested the SSD1306Ascii library. It works differently to u8g2 and u8x8 but using software SPI I got a loop frequency of around 25 Hz (so faster than u8g2 page mode but slower than u8x8, which is a better comparison).
I then tried your suggestion regarding setCursor() instead of clear() and you are correct, it is much faster, the loop cycle frequency increases to 100 Hz.
15 Hz refresh rate in u8g2 page mode should be a good value for the Arduino Uno.
What is confusing me is that software SPI is approximately 7 times faster than hardware SPI.
For u8g2 or u8x8? How did you measure this?
Actually I have never seen that SW SPI is faster than HW SPI on a proper configured Arduino Environment. Do you use any custom Environment with your Uno@8Mhz?
Hi Oliver - thanks for the quick response and for writing the library!
I haven't made any changes to the UNO environment. The comparison is for u8x8. I measured it using the sketch in the original post, results shown on the OLED display. The only thing I change is the constructor.
The SPI bus is only used to write to the display ? Could I can run it in a simulation that does not have a SPI display ? If so, then I can confirm that software SPI is slower.
I tried the sketch in the original post in Wokwi simulation, and the hardware SPI was faster for a 16MHz Uno.
Then I reduced the sketch, and once again, the hardware SPI was faster.
// For: https://forum.arduino.cc/t/oled-display-using-u8x8-library-hardware-vs-software-spi/1053666/
// This Wokwi project: https://wokwi.com/projects/348382129617371731
#include <SPI.h>
#include <U8g2lib.h>
#define MOSI 11
#define DC 9
#define SCK 13
#define CS 14
#define SAMPLE_TIME 1000 // 1 second = 1000 ms
U8X8_SSD1306_128X64_NONAME_4W_HW_SPI u8x8(CS, DC);
// U8X8_SSD1306_128X64_NONAME_4W_SW_SPI u8x8(SCK, MOSI, CS, DC);
// U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE);
// U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(SCL, SDA, U8X8_PIN_NONE);
unsigned int loopCounter = 0;
unsigned long startTime;
void setup(void) {
Serial.begin(115200);
u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r);
startTime = millis();
}
void loop(void) {
unsigned long currentTime = millis();
loopCounter++;
// speed test by writing text to the display
u8x8.drawString(0, 0, "Hello World");
// one second millis timer
if (currentTime - startTime >= SAMPLE_TIME) {
startTime = currentTime;
Serial.println( loopCounter);
loopCounter = 0;
}
}
Those numbers make perfect sense and are what is expected.
A software I2C bus can be faster than a hardware I2C on a Arduino Uno with optimized code and reduced overhead and ignoring some I2C timing, but it is according to the speed tests that I did in the past.
Thanks guys - I would expect hardware SPI to be quicker than software.
Interesting that you get different results runninng the same sketch. I think my UNO is a clone, I'll see if I can find a genuine Arduino in my collection.