Hi, I'm trying to work out how to improve the screen update performance of my 3D printer (running the Marlin firmware: GitHub - ErikZalm/Marlin: Reprap FW with look ahead. SDcard and LCD support. It works on Gen6, Ultimaker, RAMPS and Sanguinololu ).
I've modified the graphical drawing routines to display more interesting info but guess I've gone too far and now it's causing the printer to pause while the screen is being updated. So I'm looking for info on what I can do to optimize it. The OLED 128x96 screen I'm using is connected by I2C (was this a bad choice?) and the screen update routine call a number of text, drawBox and drawBitmapP methods. Screen update is only called once a second.
The bitmaps I'm using for animation are mostly small, none bigger than 24x16. I could be drawing these with a number of the drawBox/Line/Point method calls but assumed that would be slower than just using the one drawBitmapP call.
Is calling drawBitmapP once on a bigger 128x20 bitmap more efficient than calling it 4 times for 4 different smaller bitmaps?
Thanks for any guidance,
Some years back, one member of the 3d printer community contacted me because of the idea to add GLCD support to these 3D printers. They already selected u8glib as GLCD library. We both started on optimizing the u8glib code for speed so that screen updates do not affecting printer operation. At some time i stopped following all the tricks and optimization that had been invented by that person. He really debugged the lines and low level interface to do most agressive optimization. However this work was only done for the ST7920 SPI interface. A lot of the code has been put back into u8glib. So finally, i can say that the ST7920 SPI interface is the most optimized connection inside U8glib. And unfortunately, I2C is much slower compared to this.
One more problem is, that I2C is in general more slower than SPI. Upper speed limit is 100KHz, which is much slower than SPI.
All in all: I nither have the knowledge nor the equipment to do a similar optimization for an I2C OLED.
And i can confirm, that the 3D printer community has spent a lot of effort to make the GLCD run nicely with the 3D printer.
you could try to run the I2C-display at 400Khz, it could work. in practice 400KHz is 2.5-3x faster than 100KHz
add this line to setup()
TWBR = 12; // 400KHz
// TWBR = 72; // 100 Khz;
Thanks Rob for the TWBR tip - that has improved the update speed a lot and almost (but no quite) got rid of the printing stutter it was causing.
Olikraus, that's great back ground info - thanks. I did wonder why everyone was using the SPI interface with their 3D printers.
I assume that the drawBitmapP instruction needs to send more data to the screen than e.g. a drawBox.
If I put time stamps either side of the calls, will that actually give me the arduino time spent spending the instruction to the screen?
I am not sure whether it makes sense to compare drawBitmapP with drawBox. They both perform different operations.
For measurement, you can use millis() before and after the statement. However, you should execute the draw operation several times to get a more accurate result:
start = millis();
for( i = 0; i < 1000; i++ )
delta = millis()-start;