Ony writing the data that is updated sounds best to me.
However you decide to code it. do yourself (and us) a favour and use the Auto Format tool in the IDE to indent the code which makes it so much easier to read.
You only need to set the color and orientation once so you could move those calls to setup().
You could also try what UKHeliBob suggests. Do that by first drawing the graphics and any fixed text in setup(). Then in your loop, instead of clearing the screen each time, move the cursor to the locations where you want to update text and first write spaces, then move the cursor back and write the text.
But since the clear screen and straight line graphics all occur in sram and the update over SPI happens in total whether you change the screen a little or a lot it's probably not worth it.
jboyton:
It's not enough to simply pad with spaces; the bits in sram that represent the pixels of the previously drawn characters have to be set to zero.
Usually characters are built out of an array of bytes that include 1s and 0s. Padding with spaces would imply that those 0s are there. It depends on the logic implemented by the display.
coincidentally, I'm working on the ardafruit 1.7 inch tft right now! These things are slow all right. If you look at the libraries, afaict everything you do uses tft.drawPixel. Consequently, the fewer the pixels you draw, the faster it draws. BUT, there is the time it takes to lookup the pixels that have to be drawn.
So I would love to see you give it a try: try tft.drawRectangles and then try re-writing the data in black and let us know which is faster.
I'll go test how fast it takes to fill the screen on mine. Please let us know what you figure out.
The screen can be configured for use in two ways. One is to use an Arduino's hardware SPI interface. The other is to declare all the pins manually. There is no difference in the functionality of the screen between the two methods, but using hardware SPI is significantly faster.
Well, that's a lot of replies. And good feedback from all, thank you
First of all, I'm using Notepad++ to edit the code and auto format is not working. I'll try to put it in the Arduino IDE before posting next time.
It looks everyone is agree with the idea of refreshing only the changing part.
I can't put the basic display in setup() because I have different ones, but I guess I can make an display_init() to initialize the display and keep only the update in the actual function.
I can make some tests with blank char, black rect and black identical char to see what is the quickest way to erase the screen.
But my main goal is to learn to optimize code in a global way, which include speed if possible. Every display time is not a time the Arduino can use to really work
I'm also using Hardware SPI, previously I was using software and the refresh speed is 3 or 4 times faster with hardware SPI.
But my main goal is to learn to optimize code in a global way, which include speed if possible. Every display time is not a time the Arduino can use to really work
Does it matter how fast it is? If it isn't fast enough then you already have some suggestions regarding how to address that, but it sounds like you're going down the path of premature optimization and looking for better performance before you know whether you need it.
Optimized code can be less clear than the simpler stuff it replaced. It's not inevitable of course, but it has that tendency and then you're scratching your head six months later trying to figure out what on earth you did & why.
Sometimes your project really needs more speed & optimization can get it for you but I'd suggest you're better off getting it working first.
Don't ignore the simple solution of upgrading to faster hardware either.
Of course I've ignored the piece about your goal being learning about optimizing, so in that light, have fun. The issues with optimizing & when to do it are explored nicely in Jon Bentley's Programming Pearls.
KenF:
Usually characters are built out of an array of bytes that include 1s and 0s. Padding with spaces would imply that those 0s are there. It depends on the logic implemented by the display.
This display memory for this device is not readable when connected via I2C or SPI interface. So the library keeps the entire pixel map in the microprocessor RAM (1K for the 128x64). Nothing is actually sent to the display until the display() method is called, at which point the entire pixel map is transmitted. Since the library supports text and graphics it only writes the pixels that are part of the character, by default.
There is a way to do what you're talking about though. The default is to draw transparent characters so that graphics and text can share the same 5x7 text box non-destructively. But this can be overridden by changing the background color from WHITE to BLACK. Then the character drawing method will write to every "pixel". In the case of characters larger than 5x7 each pixel is actually a rectangle that is drawn. So drawing every pixel in the character is expensive.
The other way is to keep track of the previously written values and overwrite them with a BLACK foreground as was suggested earlier.
The third way is to do what M4vrick is doing now.
I tried all three (Uno R3, OLED 1306 128x64, hardware SPI interface):
31.1 ms - M4vrick's current method of erasing and redrawing everything each time
46.0 ms - Drawing the fixed part once and erasing the characters by using a BLACK foreground
57.1 ms - Fixed part once, erasing the characters with a BLACK background on each update
jboyton:
I tried all three (Uno R3, OLED 1306 128x64, hardware SPI interface):
31.1 ms - M4vrick's current method of erasing and redrawing everything each time
46.0 ms - Drawing the fixed part once and erasing the characters by using a BLACK foreground
57.1 ms - Fixed part once, erasing the characters with a BLACK background on each update
Interesting. It looks like no optimization is necessary -- any "improvements" just slows things down?
Drawing everything every time also gives the cleanest and easiest to follow code, and should therefore be the easiest to maintain.
I used the Adafruit_GFX and Adafruit_SSD1306 libraries straight out of the box.
When I timed just doing a display() update it took only a few milliseconds. A screen clear should be even faster. So that means the vast majority of the time is spent drawing characters in the buffer.
Drawing scaled characters takes a lot of time. The 90 degree orientation probably adds to this since the characters don't fit into the bytes as evenly. Since most of what you're doing is drawing these characters, doing it twice (first erase, then draw) increases the time. The straight lines probably are drawn faster than the characters.
You should check it yourself though. I sometimes do stupid things.