Hi! I have two ST7789 displays with SPI interface. I want to make a speedometer for my e-bike and display some info on them like speed, time, distance, throttle gauge, etc. When composing all this data I was executing functions one by one like:
But it's causing a lot of flickering display is updating after each function and adding text/figures one at a time. Is there any way to "pre-make" a 128x160 canvas (like, make an image of everything above) on arduino, and then send it as a bitmap to display? I have UNO, Nano, ESP32-CAM, ESP32-WROVER, ESP8266
Sorry, I made a mistake: flickering because display is updating after each function. I wonder if it's possible to make it work like SSD1306 when you call everything you want to display and then send the whole buffer with display.display()
I’m not familiar with that part, but it sounds like it will solve your flickering problem. You didn’t mention which Arduino you’re using, so I assume you may be low on RAM. There are 32K x 8 FRAM modules available for just a few dollars, and they operate at processor speed. Both SPI and I2C versions are available.
Sorry, there is not enough information here to give a complete answer, like
what libraries are you using? The Adafruit one? Guessing... Did you set a font or are
you using the default font or set a specific one, etc... How many colors are you using?
Also would help to see an image of your actual output.
But will mention a few approaches.
Anytime you redraw a display, that starts off with: tft.fillScreen(ST77XX_BLACK);
It will typically flicker a lot...
Approaches:
Using some form of Framebuffer - with the Adafruit libraries you can use their
Canvas objects. If you are only two colors, you could use the GFXcanvas1, which
only uses 1 bit per pixel. But even that would take about 2.5K for the buffer so UNO
with 2k would not work. The Adafruit GFX library has a demo app for using Canvas.
Do smarter updates of the screen. That is, if all you are wanting to do is
to output updated speed, and lets say that is your value at 75, 75.
You could simply just update that portion of the display.
a) if Adafruit and default font and things not overly packed on screen, you could
use Opaque text output, where the bits of the character being output that are not
in the actual character they will be drawn in the background color. Only caveat, is
if the new output is shorter than previous output... But if enough room and
output is still left justified you can do something like:
void update_speed(int speed) {
tft.setTextColor(ST77XX_BLUE, ST77XX_BLACK); // assuming text in blue and background black.
tft.setCursor(75, 75);
tft.print(speed); // output new speed.
tft.print(" "); // print a couple of blanks to cover any previous data.
}
Warning typed on fly so could have issues.
You also have lots of options on how these numbers are output. I showed quick and
dirty left justified. You could instead do right justified, by computing how many
characters will be output, and proceed by the number of blanks needed. ...
b) if you are not using system font, and don't have opaque capability, you could eiath
b1) do a fillRect of an area sufficient to take care of your previous output number. note: don't need to output blank characters.
b2) like b1) except use something like tft.getTextBounds to know exact area your previous
output was drawn and only clear that amount.
b3) use a Canvas object just big enough for one text field, and do your output for that updated value into canvas and then draw the canvas data to the screen at the position
of the value.