Skip to content

Issue with Sunton dotclockframebuffer display and bitmapsaver #36

@DJDevon3

Description

@DJDevon3

Ran into an issue where bitmapsaver was throwing an error when using it with a dotclockframebuffer display. Sunton ESP32S3 8048S070.

# SPDX-FileCopyrightText: 2025 DJDevon3
# SPDX-License-Identifier: MIT
# Coded for Circuit Python 9.2.3
# Sunton ESP32S3 8048S070 Example
import os
import board
import time
import math
import digitalio
import adafruit_sdcard
import sdcardio
import storage
import adafruit_imageload
import terminalio
import displayio
import busio
import dotclockframebuffer
from framebufferio import FramebufferDisplay
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
from adafruit_bitmapsaver import save_pixels
displayio.release_displays()

fb = dotclockframebuffer.DotClockFramebuffer(**board.TFT_PINS, **board.TFT_TIMINGS)
display = FramebufferDisplay(fb, auto_refresh=True)
# print(f"display: {board.DISPLAY}")
# print(f"TFT Timings: {board.TFT_TIMINGS}")

DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 480

# Quick Colors for Labels
TEXT_BLACK = 0x000000
TEXT_BLUE = 0x0000FF
TEXT_CYAN = 0x00FFFF
TEXT_GRAY = 0x8B8B8B
TEXT_GREEN = 0x00FF00
TEXT_LIGHTBLUE = 0x90C7FF
TEXT_MAGENTA = 0xFF00FF
TEXT_ORANGE = 0xFFA500
TEXT_PINK = 0xFF007F
TEXT_PURPLE = 0x800080
TEXT_RED = 0xFF0000
TEXT_WHITE = 0xFFFFFF
TEXT_YELLOW = 0xFFFF00


Arial_16 = bitmap_font.load_font("/fonts/Arial-16.bdf")
GoodTimes_121 = bitmap_font.load_font("/fonts/GoodTimesRg-Regular-121.bdf")

# Load Bitmap to tile grid first (Background layer)
DiskBMP = displayio.OnDiskBitmap("/images/Astral_Fruit_800x480-24bit.bmp")
wallpaper = displayio.TileGrid(
    DiskBMP,
    pixel_shader=DiskBMP.pixel_shader,
    tile_width=DISPLAY_WIDTH,
    tile_height=DISPLAY_HEIGHT,
)

hello_label = label.Label(Arial_16)
hello_label.anchor_point = (0.5, 1.0)
hello_label.anchored_position = (DISPLAY_WIDTH/2, 30)
hello_label.scale = (1)
hello_label.color = TEXT_WHITE

temp_label = label.Label(GoodTimes_121)
temp_label.anchor_point = (0.5, 1.0)
temp_label.anchored_position = (DISPLAY_WIDTH/2, DISPLAY_HEIGHT/2)
temp_label.scale = (1)
temp_label.color = TEXT_MAGENTA

main_group = displayio.Group()
wallpaper_group = displayio.Group()
text_group = displayio.Group()
wallpaper_group.append(wallpaper)
text_group.append(hello_label)
text_group.append(temp_label)
main_group.append(wallpaper_group)
main_group.append(text_group)
display.root_group = main_group

def time_calc(input_time):
    """Converts seconds to minutes/hours/days. Whole numbers rounded down."""
    # Attribution: Elpekenin, Updated 7/8/2024
    if input_time < 60.0:
        return f"{math.floor(input_time)} seconds"
    if input_time < 3600.0:
        return f"{math.floor(input_time / 60.0)} minutes"
    if input_time < 86400.0:
        return f"{math.floor(input_time / 3600.0)} hours"
    return f"{math.floor(input_time / 86400.0)} days"

hello_label.text = "Sunton ESP32-S3 8048S070 Dotclock Display"
temp_label.text = "hello"
print("Board Uptime: ", time_calc(time.monotonic())) # example for board uptime
if isinstance(display, displayio.Display):
    print("true")
else:
    print("false")
TAKE_SCREENSHOT = False  # Set to True to take a screenshot
if TAKE_SCREENSHOT:
    # Initialize SD Card & Mount Virtual File System
    sdcard = sdcardio.SDCard(board.SPI(), board.SD_CS)
    vfs = storage.VfsFat(sdcard)
    storage.mount(vfs, "/sd")  # /sd is root dir of SD Card
    print("Taking Screenshot...")
    save_pixels("/sd/Screenshot.bmp", display)
    print("Screenshot Saved")
    storage.umount(vfs)
    print("SD Card Unmounted")  # Do not remove SD card until unmounted
Taking Screenshot...
Traceback (most recent call last):
  File "<stdin>", line 105, in <module>
  File "adafruit_bitmapsaver.py", line 181, in save_pixels
ValueError: Second argument must be a Bitmap or Display

In discord dan instructed me to delete lines 175-181. These were the lines deleted.

if isinstance(pixel_source, Bitmap):
        if not isinstance(palette, Palette) and not isinstance(palette, ColorConverter):
            raise ValueError(
                "Third argument must be a Palette or ColorConverter for a Bitmap save"
            )
    elif not isinstance(pixel_source, Display):
        raise ValueError("Second argument must be a Bitmap or Display")

That worked past the error but the colors are obviously incorrect. I'm not sure if it's a simple swapping issue. The bmp I used is a 800x480 24-bit as a wallpaper background. During the process of trying to figure out the issue I switched to using sdcardio, unsure if that has any bearing.

Image

I have absolutely no idea what the cause or potential fix is for this. My knowledge of dotclock displays is today years old.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions