Skip to content

Proper way to use Arduino_H7_Video with ArduinoGraphics.h on Giga Display Shield #936

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
KurtE opened this issue Aug 13, 2024 · 6 comments
Closed
Assignees
Labels

Comments

@KurtE
Copy link

KurtE commented Aug 13, 2024

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.

@KurtE
Copy link
Author

KurtE commented 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:

void show_updated_startup_status() {
    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);

    if (g_devices_started & SD_DRIVE) {
        Display.text("SD Started", 100, 100);
    }

    if (g_devices_started & USB_DRIVE) {
        Display.text("USB Started", 100, 200);
    }

    Display.endDraw();

}

@leonardocavagnis
Copy link
Member

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:

  Display.beginDraw();
  // draw something
  Display.endDraw();

Note: The beginDraw function 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:

  Display.beginDraw();
  fillScreen(0, 0, 0xff, false);
  Display.textFont(Font_5x7);
  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();
  fillScreen(0, 0, 0xff, false);
  Display.textFont(Font_5x7);
  Display.setTextSize(5);
  Display.stroke(0xff, 0, 0);
  Display.background(0, 0, 0xff);
  Display.text("Waiting for SD or USB", 0, 0);
  Display.text("SD Started", 100, 100); // new element
  Display.endDraw();

  delay(2000);

  Display.beginDraw();
  fillScreen(0, 0, 0xff, false);
  Display.textFont(Font_5x7);
  Display.setTextSize(5);
  Display.stroke(0xff, 0, 0);
  Display.background(0, 0, 0xff);
  Display.text("Waiting for SD or USB", 0, 0);
  Display.text("SD Started", 100, 100);
  Display.text("USB Started", 100, 200); // new element
  Display.endDraw();

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:

    Display.beginDraw();
    Display.beginText(100, 300);
    Display.print("Here is some Text");
    Display.textScrollSpeed(100);
    Display.endText(SCROLL_LEFT);
    Display.endDraw();

Could you please provide more details and attach some pictures?

@KurtE
Copy link
Author

KurtE commented Aug 30, 2024

I tested the scrolled text example (with the appropriate primitives) and I didn’t encounter the issue you mentioned:

Display.beginDraw();
Display.beginText(100, 300);
Display.print("Here is some Text");
Display.textScrollSpeed(100);
Display.endText(SCROLL_LEFT);
Display.endDraw();

Could you please provide more details and attach some pictures?

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...

    Display.beginDraw();
    Display.stroke(0xff, 0, 0);
    Display.background(0, 0, 0xff);
    Display.beginText(100, 300);
    Display.print("Here is some Text");
    Display.textScrollSpeed(100);
    Display.endText(SCROLL_LEFT);
    Display.endDraw();

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
Copy link
Member

Note: I have a related Pull request/Issue over on the ArduinoGraphics github library.
arduino-libraries/ArduinoGraphics#45

Yes, I reviewed it. Thanks

Note: the calls here to beginDraw/endDraw are sort of overdone by the scroll text code...

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 :)

Also wondered about, if the beginDraw() should clear the buffer to black? Or should potentially respect the background color setting?

beginDraw restores the buffer to a "clean state". We defined the "clean state" as a black background.

@KurtE
Copy link
Author

KurtE commented Sep 2, 2024

Feel free to close...

beginDraw restores the buffer to a "clean state". We defined the "clean state" as a black background.
The document for the library:
https://reference.arduino.cc/reference/en/libraries/arduinographics/begindraw/
Just says:
Begins a drawing operation.
The endDraw has a bit more description:
Ends a drawing operation, any drawing operations after beginDraw() is called will be displayed to the screen.

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
Copy link
Member

Feel free to open as many PRs you want to improve mbed and Giga :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants