TL;DR: I’m trying to set up buffers, displays, and screens on an Arduino Giga, but I am getting crashes on upload, and I am not sure how to fix it.
I’m using an Arduino Giga R1 WiFi and a Giga Display Shield for this project, and this is the first time that I have ever worked with LVGL. I had the code working with a combination of Arduino_GigaDisplay_GFX.h and lvgl.h (v9.2.2), but I was having some weird crashes related to initializing the USB-A to connect a flash drive using Arduino_USBHostMbed5.h (either the USB-A would disconnect after 20–30 seconds with newer flash drives, or the Arduino simply crash with older flash drives that would stay connected long enough to progress through the menus, and I would get error -22 when verifying the USB connection with any of the drives, though it would still write a file).
For example of a crash, I have it so the user progresses through some menus to make selections with radio buttons and enter numbers with a button matrix, then show a summary with a couple buttons on the screen. Depending on what options the user had made, one of the buttons on the summary screen would act appropriately or simply crash, even though that code had nothing to do with the USB. In case you are wondering, I haven’t seen memory fragmentation above 2%, the heap stays relatively small, and there is still lots of memory left.
I decided to go back and restart with the LVGL and Arduino_H7_Video.h. I switched from outputting text with GFX to LVGL, and I am going to try using a display and separate screens as the foundation rather than whatever is the default active screen to see if I can get around the crashing problem.
I am trying to set up a buffer for flushing the screen to use for the screen updates and for loading screens. I don’t know if I really need the buffer (let alone two) as my screens are mostly static except for one that has a running update that changes every second, and another that flashes different colours if the user pauses things or if there is a fault somewhere, other than the button widgets of course. Also, the menus and the like seemed to load fine before without a buffer, an explicitly created display, or explicitly creating screens. I’m trying a few different things though to see if I can get rid of the crashes that are happening.
After implementing an explicit display, I had the code working more or less, though I was also having some new issues with white text not showing up on the black screen and crashes during the menus (though I hadn’t set up separate screens yet), but now that I am trying to add a buffer, the upload crashes as soon as it finishes and before the Arduino confirms a successful upload. I’ve tried figuring it out myself, I’ve talked with a few friends who are more familiar with Arduino than I am (though they aren’t familiar with the Giga and LVGL), and I have tried talking with ChatGPT’s Code Copilot to see if I can figure it out (though the latter keeps reverting to LVGL v8). I have been having trouble finding tutorials and examples for these things.
Because of a cover image at the start, the program memory space is 81% (normally 42% without the image), and the dynamic memory is 56% (normally 21% without the display buffers).
I’ve included the code below. Does anyone have any ideas about what is going on and where I am going wrong?
Description
What MCU/Processor/Board and compiler are you using?
Arduino Giga R1 WiFi with a Giga Display Shield, Arduino IDE 2.3.4
What do you want to achieve?
Get a display, screens, and buffer working.
What have you tried so far?
Reading the LVGL Documentation 9.0, searching forums, talking with friends, and asking ChatGPT Code Copilot if it can spot the problem.
Code to reproduce
As far as I remember, this is the code that was changed since the uploads last worked (the full code is several thousand lines long, so I don’t want to overwhelm people).
// Libraries
#include <Arduino_H7_Video.h>
#include <lvgl.h>
#include "cover_img.h"
// Definitions
#ifndef MY_DISP_HOR_RES
#define MY_DISP_HOR_RES 800
#endif
#ifndef MY_DISP_VER_RES
#define MY_DISP_VER_RES 480
#endif
#define BYTES_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_RGB565))
// Instances
Arduino_H7_Video DisplayAHV(MY_DISP_HOR_RES, MY_DISP_VER_RES, GigaDisplayShield);
Arduino_GigaDisplayTouch touchDetector;
// Global variables
lv_display_t * display = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES);
static uint8_t buf1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10 * BYTES_PER_PIXEL];
static uint8_t buf2[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10 * BYTES_PER_PIXEL];
void setup() {
// Variables for self-test startup screen
int yPosition = 10; // Initial Y-coordinate for the first line of text for startup screen
const int lineSpacing = 20; // Space between lines of text
// Initialize the display
DisplayAHV.begin();
// Initialize LVGL
lv_init();
lv_display_set_buffers(display, buf1, buf2, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_flush_cb(display, my_disp_flush);
// Optionally set it as the default display
lv_disp_set_default(display);
cover_image();
screen_black = lv_scr_act();
lv_obj_set_style_bg_color(screen_black, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_bg_opa(screen_black, LV_OPA_COVER, LV_PART_MAIN);
// Create a label with white text
lv_obj_t *label_startup = lv_label_create(screen_black);
lv_obj_set_style_text_font(label_startup, &lv_font_montserrat_14, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_color(label_startup, lv_color_white(), LV_PART_MAIN);
lv_obj_align(label_startup, LV_ALIGN_TOP_LEFT, 10, yPosition);
lv_label_set_text(label_startup, "LVGL screen initialized");
lv_refr_now(NULL);
yPosition += lineSpacing;
}
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *color_p) {
// Cast the buffer to lv_color_t for proper interpretation
lv_color_t *color_map = (lv_color_t *)color_p;
// Start drawing to the framebuffer
DisplayAHV.beginDraw();
// Loop through the area and set pixels
for (int32_t y = area->y1; y <= area->y2; y++) {
for (int32_t x = area->x1; x <= area->x2; x++) {
// Extract RGB565 from lv_color_t
uint16_t color = *((uint16_t *)color_map);
// Convert RGB565 to R, G, B components
uint8_t r = (color >> 11) & 0x1F; // Extract 5 bits for red
uint8_t g = (color >> 5) & 0x3F; // Extract 6 bits for green
uint8_t b = color & 0x1F; // Extract 5 bits for blue
// Scale to 8-bit values (0-255)
r = (r * 255) / 31;
g = (g * 255) / 63;
b = (b * 255) / 31;
// Set the pixel color
DisplayAHV.set(x, y, r, g, b);
// Advance to the next color in the buffer
color_map++;
}
}
// End drawing operation
DisplayAHV.endDraw();
lv_display_flush_ready(disp);
}
void cover_image() {
LV_IMG_DECLARE(cover_img);
lv_obj_t * img1 = lv_img_create(lv_scr_act());
lv_img_set_src(img1, &cover_img);
lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(img1, 800, 480);
lv_timer_handler();
delay(2000);
}
Screenshot and/or video
N/A as it is crashing before anything is shown on the screen