Fixed
I have fixed my problem, there was an issue in by bit definition/color implementation.
Description
I designed a ui in squareline studio and I am trying to render it on my display. I am having issues with my flush not properly displaying the ui. The UI is only rendering in the top fifth of my display, and the ui is showing up three times, with one in the left, center and right. There are streaks going down my display.
Because squareline can only go down to 16 bits for color, I am also converting the color from 16bit to B/W in my flush function too
What MCU/Processor/Board and compiler are you using?
I am using an ESP 32 Feather V2
Waveshare 7.5in V2 Monochromatic B/W display
Arduino IDE
What LVGL version are you using?
9.2.2
What do you want to achieve?
render UI
What have you tried so far?
I’ve tried a variety of different things, but I don’t really understand how flushing works so I’vev really just been bashing my head in.
List item
Code to reproduce
Here is my display flush function
void my_disp_flush(lv_display_t* disp, const lv_area_t* area, uint8_t* pixelmap) {
Serial.println("Flush called");
if (!pixelmap || !disp) {
Serial.println("Error: Null pixelmap or display");
lv_disp_flush_ready(disp);
return;
}
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
// Ensure that bitmap size matches the full display (800x480)
size_t bitmap_size = ((w * h + 7) / 8); // Round up to nearest byte
if (bitmap_size == 0) {
Serial.println("Invalid bitmap size");
lv_disp_flush_ready(disp);
return;
}
uint8_t* bitmap = (uint8_t*)malloc(bitmap_size);
if (!bitmap) {
Serial.println("Failed to allocate bitmap");
lv_disp_flush_ready(disp);
return;
}
memset(bitmap, 0, bitmap_size); // Clear the bitmap initially
// Convert the 16-bit color pixelmap to monochrome (1-bit) bitmap
for (uint32_t y = 0; y < h; y++) {
for (uint32_t x = 0; x < w; x++) {
size_t pixel_index = (y * w + x);
if (pixel_index < (w * h)) {
// Read the 16-bit color value
lv_color_t color = ((lv_color_t*)pixelmap)[pixel_index];
// Calculate luminance using the formula (same as before)
uint16_t luminance = (color.red * 299 + color.green * 587 + color.blue * 114) / 1000;
// Set pixel as white (1) for light pixels, black (0) for dark pixels
size_t byte_index = pixel_index / 8;
size_t bit_position = 7 - (pixel_index % 8); // MSB
if (luminance > 127) { // Light pixel -> white (1)
bitmap[byte_index] |= (1 << bit_position);
} else { // Dark pixel -> black (0)
bitmap[byte_index] &= ~(1 << bit_position);
}
}
}
}
// Set the full screen window (800x480)
display.setFullWindow(); // Set the full window for the update
display.firstPage(); // Only call firstPage once
do {
// Draw the full bitmap for the screen
display.drawBitmap(0, 0, bitmap, 800, 480, GxEPD_BLACK);
} while (display.nextPage()); // Only call nextPage once
// Free the dynamically allocated bitmap
free(bitmap);
// Signal that the flush is complete (only once)
lv_disp_flush_ready(disp);
}void my_disp_flush(lv_display_t* disp, const lv_area_t* area, uint8_t* pixelmap) {
Serial.println("Flush called");
if (!pixelmap || !disp) {
Serial.println("Error: Null pixelmap or display");
lv_disp_flush_ready(disp);
return;
}
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
// Ensure that bitmap size matches the full display (800x480)
size_t bitmap_size = ((w * h + 7) / 8); // Round up to nearest byte
if (bitmap_size == 0) {
Serial.println("Invalid bitmap size");
lv_disp_flush_ready(disp);
return;
}
uint8_t* bitmap = (uint8_t*)malloc(bitmap_size);
if (!bitmap) {
Serial.println("Failed to allocate bitmap");
lv_disp_flush_ready(disp);
return;
}
memset(bitmap, 0, bitmap_size); // Clear the bitmap initially
// Convert the 16-bit color pixelmap to monochrome (1-bit) bitmap
for (uint32_t y = 0; y < h; y++) {
for (uint32_t x = 0; x < w; x++) {
size_t pixel_index = (y * w + x);
if (pixel_index < (w * h)) {
// Read the 16-bit color value
lv_color_t color = ((lv_color_t*)pixelmap)[pixel_index];
// Calculate luminance using the formula (same as before)
uint16_t luminance = (color.red * 299 + color.green * 587 + color.blue * 114) / 1000;
// Set pixel as white (1) for light pixels, black (0) for dark pixels
size_t byte_index = pixel_index / 8;
size_t bit_position = 7 - (pixel_index % 8); // MSB
if (luminance > 127) { // Light pixel -> white (1)
bitmap[byte_index] |= (1 << bit_position);
} else { // Dark pixel -> black (0)
bitmap[byte_index] &= ~(1 << bit_position);
}
}
}
}
// Set the full screen window (800x480)
display.setFullWindow(); // Set the full window for the update
display.firstPage(); // Only call firstPage once
do {
// Draw the full bitmap for the screen
display.drawBitmap(0, 0, bitmap, 800, 480, GxEPD_BLACK);
} while (display.nextPage()); // Only call nextPage once
// Free the dynamically allocated bitmap
free(bitmap);
// Signal that the flush is complete (only once)
lv_disp_flush_ready(disp);
}
Screenshot and/or video
what the ui should look like