Repository navigation
Proper way to use Arduino_H7_Video with ArduinoGraphics.h on Giga Display Shield #936
Description
Sorry, I am trying to understand, how the code integration of these two classes is supposed to work.
Background, I am playing with an Image viewer sketch (BMP, PNG, JPEG), that I use as part of testing of different display libraries I work with... Including for the fun of it on the GIGA Display Shield. I was first using the Adafruit GFX which worked, but wondered about lower overhead version, so thought I would try this approach.
A version of it is up at: https://github.com/KurtE/Arduino_GIGA-stuff/tree/main/sketches/tft_picture_view_sd_giga_shield_24Bit
I am mainly trying to understand the expectations of calls to these two methods:
void Arduino_H7_Video::beginDraw() {
ArduinoGraphics::beginDraw();
dsi_lcdClear(0);
}
void Arduino_H7_Video::endDraw() {
ArduinoGraphics::endDraw();
dsi_drawCurrentFrameBuffer();
}
I understand:
If I call beginDraw() it sets the entire screen to black.
And if I call endDraw() - it sends the current frame buffer to display.
Now suppose at startup of the sketch I may want to write three lines of text on the screen as the sketch checks to see if
an SDCard or USB Drive are ready... This can take over several seconds, so how do I incrementally write the text to the screen?
Simpler sketch to demonstrate:
#include <elapsedMillis.h>
#include "Arduino_H7_Video.h"
#include "ArduinoGraphics.h"
REDIRECT_STDOUT_TO(Serial)
Arduino_H7_Video Display(800, 480, GigaDisplayShield);
void fillScreen(uint8_t r, uint8_t g, uint8_t b, bool begin_end = true) {
if (begin_end) Display.beginDraw();
Display.background(r, g, b);
Display.clear();
if (begin_end) Display.endDraw();
}
//****************************************************************************
// Setup
//****************************************************************************
void setup(void) {
Serial.begin(115200);
while (!Serial && millis() < 3000)
Serial.println("*** start up display ***");
Display.begin();
//tft.setRotation(1);
fillScreen(0xff, 0, 0, true); // experiment going direct
//tft.fillScreen(RED);
delay(500);
fillScreen(0, 0xff, 0, true);
//tft.fillScreen(GREEN);
delay(500);
fillScreen(0, 0, 0xff, true);
//tft.fillScreen(BLUE);
delay(500);
Display.beginDraw();
fillScreen(0, 0, 0xff, false);
Display.textFont(Font_5x7);
//Display.textSize(5, 5);
Display.setTextSize(5);
Display.stroke(0xff, 0, 0);
Display.background(0, 0, 0xff);
Display.text("Waiting for SD or USB", 0, 0);
Display.endDraw();
delay(2000);
//Display.beginDraw();
Display.text("SD Started", 100, 100);
Display.endDraw();
delay(2000);
// Display.beginDraw();
Display.text("USB Started", 100, 200);
Display.endDraw();
delay(2000);
fillScreen(0xff, 0, 0, true);
Display.beginText(100, 300);
Display.print("Here is some Text");
Display.textScrollSpeed(100);
Display.endText(SCROLL_LEFT);
}
void loop() {
}
The first line comes out fine: Waiting for SD or USB
Now if it finds the SD and I display: SD Started
If first I call beginDraw
Only the new text is displayed and rest of the screen is black.
If I don't call beginDraw, the new text is the only text on screen, and the background is red.
Now if I then try to output the third line: USB Started
Again if I call beginDraw - it is the only thing on screen with background black.
If I don't call beginDraw: both the first line (Waiting...) and this line are displayed with Red bacground, but not 2nd line.
Pretty sure: double buffering (two buffers that alternate).
The last part of this test sketch tried the beginText, write, endText to see if an update to an enahancement to the ArduinoGraphics library to allow the font to be scaled works.
arduino-libraries/ArduinoGraphics#45
It appears to, however the code in endText for scrolling like the left that I tried:
if (scrollDirection == SCROLL_LEFT) {
int scrollLength = _textBuffer.length() * textFontWidth() + _textX;
for (int i = 0; i < scrollLength; i++) {
beginDraw();
int const text_x = _textX - i;
text(_textBuffer, text_x, _textY);
scaledBitmap(_font->data[0x20], text_x - 1, _textY, 1, _font->height, _textsize_x, _textsize_y);
endDraw();
delay(_textScrollSpeed);
}
Appears like it maybe relies on screen being erased? Otherwise when the code draws it one pixel farther
to the left, it would leave a smear with the pixels that were on the right hand edge... Sort of like this
library assumes only one thing on it at a time.
So at a minimum I would think that if beginDraw is going to erase the screen it should do so to
the currently selected background color.
Sorry I hope this all makes sense.
Activity
KurtE commentedon Aug 13, 2024
Note: in my own sketch mentioned above, I have locally updated it to have a helper function which outputs the display the current startup status:
leonardocavagnis commentedon Aug 30, 2024
Dear @KurtE,
The screens built with the ArduinoGraphics library are not designed to be "incrementally" modified. Each screen is independent of the previous one and must be enclosed by the following primitives:
Note: The
beginDrawfunction clears the image buffer and sets the background to black (dsi_lcdClear(0), where 0 corresponds to black).In your example, if you want to update the screen incrementally, you need to redraw the entire previous screen each time, adding the new elements to it:
I understand this isn't the most efficient approach, but this library is designed for drawing simple and static screens. If you need to create more complex screens, I recommend using one of the third-party libraries compatible with the Arduino H7 Video library (LVGL or emWin).
I tested the scrolled text example (with the appropriate primitives) and I didn’t encounter the issue you mentioned:
Could you please provide more details and attach some pictures?
KurtE commentedon Aug 30, 2024
Suppose I want the text to scroll on a blue background? With Red text? I believe the sketch mentioned had higher up in it
Note: I have a related Pull request/Issue over on the ArduinoGraphics github library.
arduino-libraries/ArduinoGraphics#45
Which added support to scale the text up to some size you can actually see on the display...
Note: the calls here to beginDraw/endDraw are sort of overdone by the scroll text code...
Understand that this library is really basic... Just thought some of it should be documented, like the dual buffers.
Also wondered about, if the beginDraw() should clear the buffer to black? Or should potentially respect the background color setting?
Anyway I am just playing. Was curious about how well the display would look if I sent it images with 24 bit colors... Most of the GFX like libraries are mostly setup around 16 bit color (RGB565), so I went down to this level. Mostly I am playing with other
displays (ILI948x, RA8876, NT35510, ...) on Teensy 4.x (including some custom variants).
And thought it might be good to document the things I ran into.
leonardocavagnis commentedon Sep 2, 2024
Yes, I reviewed it. Thanks
Sure, scrolled text already uses beginDraw()/endDraw() inside the endText() function. It should be redesigned to be compliant with the H7 Video library. Feel free to propose your fix :)
beginDraw restores the buffer to a "clean state". We defined the "clean state" as a black background.
KurtE commentedon Sep 2, 2024
Feel free to close...
Neither describe, what happens to other stuff that might have been on the screen before...
As for what is a "clean state", your description works, alternative might be to clear the screen to the currently defined background color... As this would keep users from having the overhead of clearing the whole screen buffer twice. But probably not a high priority thing. There are many other things with the Arduino and MBED and GIGA that I wish would be improved. LIke, with the program I am playing with, why is reading an image off of an SDCard several times faster than reading it off of a USB Host memory stick? Buffered output on Serial ports, ...
Thanks again
Kurt
leonardocavagnis commentedon Sep 2, 2024
Feel free to open as many PRs you want to improve mbed and Giga :)