From f3505a24440785054888f1a31db156d7184c1a16 Mon Sep 17 00:00:00 2001 From: Mark McGookin Date: Mon, 24 Nov 2025 12:47:34 +0000 Subject: [PATCH 1/2] Updates to the image gallery script to show a bit more information to make debugging easier, and rectify some issues with opening images. (Also added jpeg to the image filter for usability) --- examples/image_gallery.py | 115 +++++++++++++++++++++++++++++++------- 1 file changed, 95 insertions(+), 20 deletions(-) diff --git a/examples/image_gallery.py b/examples/image_gallery.py index 55985ec..ae722e2 100644 --- a/examples/image_gallery.py +++ b/examples/image_gallery.py @@ -1,20 +1,21 @@ -# ICON photo-library +# ICON [[(-6.0, 2.0), (14.0, 2.0), (7.1, -7.0), (2.5, -1.0), (-0.6, -5.0), (-6.0, 2.0)], [(-8.0, 10.0), (-8.77, 9.93), (-10.0, 9.49), (-10.81, 8.88), (-11.53, 7.91), (-11.87, 7.04), (-12.0, 6.05), (-12.0, -18.0), (-11.72, -19.5), (-11.15, -20.47), (-10.47, -21.14), (-9.78, -21.58), (-8.86, -21.91), (-8.05, -22.0), (16.0, -22.0), (16.82, -21.92), (18.02, -21.44), (18.51, -21.07), (19.42, -20.05), (19.83, -19.17), (20.0, -18.05), (20.0, 6.0), (19.7, 7.54), (19.37, 8.16), (18.65, 8.99), (17.36, 9.77), (16.05, 10.0), (-8.0, 10.0)], [(-8.0, 6.0), (16.0, 6.0), (16.0, -18.0), (-8.0, -18.0), (-8.0, 6.0)], [(-16.0, 18.0), (-16.73, 17.94), (-17.83, 17.58), (-18.81, 16.88), (-19.26, 16.35), (-19.79, 15.31), (-20.0, 14.05), (-20.0, -14.0), (-16.0, -14.0), (-16.0, 14.0), (12.0, 14.0), (12.0, 18.0), (-16.0, 18.0)], [(-8.0, -18.0), (-8.0, -18.0)]] # NAME Photo Frame # DESC A touch enabled image gallery -""" +''' An image gallery demo to turn your Pimoroni Presto into a desktop photo frame! - Create a folder called 'gallery' on the root of your SD card and fill it with JPEGs. - The image will change automatically every 5 minutes - You can also tap the right side of the screen to skip next image and left side to go to the previous :) -""" +''' import os import time import jpegdec import machine +import plasma import sdcard import uos from presto import Presto @@ -45,7 +46,7 @@ j = jpegdec.JPEG(display) # Where our images are located -directory = "gallery" +directory = 'gallery' # Stores the total number of images in the user gallery total_image_count = 0 @@ -71,18 +72,26 @@ def display_error(text): try: + print('Setting up SD card') # Setup for SD Card sd_spi = machine.SPI(0, sck=machine.Pin(34, machine.Pin.OUT), mosi=machine.Pin(35, machine.Pin.OUT), miso=machine.Pin(36, machine.Pin.OUT)) sd = sdcard.SDCard(sd_spi, machine.Pin(39)) + print('Mounting SD Card') # Mount the SD to the directory 'sd' uos.mount(sd, "/sd") - # if the gallery folder exists on the SD card we want to use the images in there! - if os.stat("sd/gallery"): - directory = "sd/gallery" + # ADD THIS - Give the SD card time to settle + time.sleep(1) -except OSError: + # if the gallery folder exists on the SD card we want to use the images in there! + if os.stat('sd/gallery'): + print('Found SD Gallery') + directory = 'sd/gallery' + else: + print('Did not find SD Card Gallery') +except OSError as error: + print(f'Error setting up SD Card - {repr(error)}') pass @@ -95,12 +104,12 @@ def numberedfiles(k): try: - files = [file for file in sorted(os.listdir(directory), key=numberedfiles) if file.endswith(".jpg")] + files = list(file for file in sorted(os.listdir(directory), key=numberedfiles) if file.endswith('.jpg') or file.endswith('.jpeg')) except OSError: display_error("Problem loading images.\n\nEnsure that your Presto or SD card contains a 'gallery' folder in the root") total_image_count = len(files) - 1 - +print(f'Found {total_image_count} files') def return_point(): global lfsr @@ -126,7 +135,7 @@ def fizzlefade(): while True: - for _ in range(2000): + for i in range(2000): x, y = return_point() if x > -1 and y > -1: display.pixel(x, y) @@ -137,13 +146,29 @@ def fizzlefade(): if lfsr == 1: break +def reinit_sd(): + """Reinitialize SD card to recover from SPI errors""" + global sd_spi, sd + try: + # Give the SD card a moment to reset + time.sleep(0.1) + # Reinitialize the SPI and SD card + sd_spi = machine.SPI(0, sck=machine.Pin(34, machine.Pin.OUT), mosi=machine.Pin(35, machine.Pin.OUT), miso=machine.Pin(36, machine.Pin.OUT)) + sd = sdcard.SDCard(sd_spi, machine.Pin(39)) + time.sleep(0.1) + return True + except: + return False + def show_image(show_next=False, show_previous=False): + + print(f'show_image called') + global current_image global total_image_count # Get the next image in the gallery - # If we're at the end of the gallery, loop back and start from 1. if show_next: if current_image < total_image_count: current_image += 1 @@ -155,24 +180,38 @@ def show_image(show_next=False, show_previous=False): else: current_image = total_image_count - # Open the index file and read lines until we're at the correct position + print(f'image index {str(current_image)}/{str(total_image_count)}') + try: img = f"{directory}/{files[current_image]}" - - j.open_file(img) + + print(f'reading {img} into memory') + + # Read the entire JPEG file into memory first + with open(img, 'rb') as f: + jpeg_data = f.read() + + print(f'read {len(jpeg_data)} bytes, opening with jpegdec') + + # Now open from RAM instead of file + j.open_RAM(jpeg_data) + + print(f'opened {img}') img_height, img_width = j.get_height(), j.get_width() img_x = 0 img_y = 0 - # if the image isn't exactly 240x240 then we'll try to centre the image if img_width < WIDTH: img_x = (WIDTH // 2) - (img_width // 2) if img_height < HEIGHT: img_y = (HEIGHT // 2) - (img_height // 2) + print(f'img_x: {img_x}') + print(f'img_y: {img_y}') + display.set_layer(0) display.set_pen(BACKGROUND) display.clear() @@ -180,15 +219,14 @@ def show_image(show_next=False, show_previous=False): fizzlefade() - # Now draw the current image to Layer 1 display.set_layer(1) - # Decode the JPEG j.decode(img_x, img_y, jpegdec.JPEG_SCALE_FULL, dither=True) - except OSError: + except OSError as e: + print(f"OSError details: {e}") display_error("Unable to find/read file.\n\nCheck that the 'gallery' folder in the root of your SD card contains JPEG images!") except IndexError: - display_error("Unable to read images in the 'gallery' folder.\n\nCheck the files are present and are in JPEG format.") + display_error(f"Unable to read images in the '{directory}' folder.\n\nCheck the files are present and are in JPEG format.") def clear(): @@ -198,6 +236,42 @@ def clear(): display.set_layer(1) display.clear() +# Test SD card access before showing images +print("\n=== SD Card Diagnostic Test ===") +try: + test_files = os.listdir('sd/gallery') + print(f"✓ Can list directory: {len(test_files)} files") + + test_file = f'sd/gallery/{test_files[0]}' + print(f"Testing file: {test_file}") + + # Try opening with standard Python file operations + with open(test_file, 'rb') as f: + test_data = f.read(1000) + print(f"✓ Can read with open(): {len(test_data)} bytes") + + # Now try with jpegdec + print(f"Testing jpegdec.open_file()...") + j.open_file(test_file) + print(f"✓ jpegdec opened successfully!") + print(f" Image size: {j.get_width()}x{j.get_height()}") + +except Exception as e: + print(f"✗ Test failed: {type(e).__name__}: {e}") + # The jpegdec test failed and corrupted SPI - reinitialize! + print("Reinitializing SD card after failed jpegdec test...") + reinit_sd() + time.sleep(0.5) + +print("=== End Diagnostic ===\n") + +# Store the last time the screen was updated +last_updated = time.time() + +# Show the first image on the screen so it's not just noise :) +clear() +show_image() +presto.update() # Store the last time the screen was updated last_updated = time.time() @@ -249,3 +323,4 @@ def clear(): while touch.state: touch.poll() time.sleep(0.02) + From 43eb11fe4ab55f0b698d4180a7128ce9d3991dd5 Mon Sep 17 00:00:00 2001 From: Mark McGookin Date: Mon, 24 Nov 2025 14:05:21 +0000 Subject: [PATCH 2/2] removed icon vector stuff and updated to be a bit more like the latest version --- examples/image_gallery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/image_gallery.py b/examples/image_gallery.py index ae722e2..985adaf 100644 --- a/examples/image_gallery.py +++ b/examples/image_gallery.py @@ -1,4 +1,4 @@ -# ICON [[(-6.0, 2.0), (14.0, 2.0), (7.1, -7.0), (2.5, -1.0), (-0.6, -5.0), (-6.0, 2.0)], [(-8.0, 10.0), (-8.77, 9.93), (-10.0, 9.49), (-10.81, 8.88), (-11.53, 7.91), (-11.87, 7.04), (-12.0, 6.05), (-12.0, -18.0), (-11.72, -19.5), (-11.15, -20.47), (-10.47, -21.14), (-9.78, -21.58), (-8.86, -21.91), (-8.05, -22.0), (16.0, -22.0), (16.82, -21.92), (18.02, -21.44), (18.51, -21.07), (19.42, -20.05), (19.83, -19.17), (20.0, -18.05), (20.0, 6.0), (19.7, 7.54), (19.37, 8.16), (18.65, 8.99), (17.36, 9.77), (16.05, 10.0), (-8.0, 10.0)], [(-8.0, 6.0), (16.0, 6.0), (16.0, -18.0), (-8.0, -18.0), (-8.0, 6.0)], [(-16.0, 18.0), (-16.73, 17.94), (-17.83, 17.58), (-18.81, 16.88), (-19.26, 16.35), (-19.79, 15.31), (-20.0, 14.05), (-20.0, -14.0), (-16.0, -14.0), (-16.0, 14.0), (12.0, 14.0), (12.0, 18.0), (-16.0, 18.0)], [(-8.0, -18.0), (-8.0, -18.0)]] +# ICON photo-library # NAME Photo Frame # DESC A touch enabled image gallery