
CYD Simple Slideshow
A simple SD card JPEG Slideshow for your ESP32 Cheap Yellow Display, aka. "CYD".
Upload this sketch, insert an SD card with JPEG files on it, power up. Enjoy!
Simple Slideshow displays all the JPEG files on the card one-by-one, in sequential or random order.
That's it!
How to use:
Scale your JPEG files to 320 pixels or less (longest side) or 240 pixels or less (shortest side), for best results.
In other words, a 16:9 image should be no wider than 320px and a 4:3 image should be no higher than 240px, for best results.
You can supply images of any size, but larger images will probably not display correctly. Similarly, progressive JPEG files are not supported and will instantly explode your CYD into a million shards, or just show black; whichever is most likely.
You can use Irfanview (Windows) or XnView (Windows/Linux/MacOS) to scale a batch of images in a few clicks. In the shell, convert or mogrify:
mogrify -resize 320x240 *.jpg
(install imagemagick for these tools) works great.
Large SD cards are totally supported. I have tested a 128GB card (formatted to FAT32) and was left with nothing but joy-joy feelings.
I threw 65GB (just over 64GB, see) of movie files onto the newly-formatted 128GB card (these trivial files were ignored by CYD Simple Sideshow), to check that the CYD could access the JPEG files I threw on after. It acted as if the other files simply weren't there; just like I programmed it to; the c**t.
So... The CYD can access a file anywhere on a 128GB (up to 2TB, at least) card without issue. But, WHY???
As the average 320x240 JPEG file is around 20Kb, it would take MANY MANY thousands of such images to fill even a 1GB card. Seriously; how big a slideshow do you need?
NOTE: There is a hard limit of 20,000 files in random order mode. CYD Simple Slideshow will ignore all files beyond this in random order mode.
Besides, it's challenging to put this many files in the root of an SD card without your OS shitting the bed. My Windows desktop gives up around twelve and a half thousand images in. But wait a minute, at one image-per-minute, that's a whole weeks-worth of images. Plenty!
Touchscreen Operation:
The touchscreen is divided into three areas.
At the top and bottom are four "corner" buttons, 1/4 of the screen height; (60px) tall, by a third the width of your screen.
Left side corners control brightness. Right corners control delay time.
As expected, top corners move the value UP and bottom corners DOWN.
In the middle area (1/2 screen height) are three buttons, all three a 1/3 of the screen width (320/3 == hmm).
Tap the centre area to pause / un-pause the slideshow.
NOTE: if you pause, the paused time is ignored when you resume play. In other words, if your delay is 15s and you pause after 5s; on resuming play, 10s will pass before the next image displays. This is by design, like everything else.
Tap the right to advance immediately to the next image. You can do this when the slideshow is paused, effectively switching you to manual advance mode.
Tap the left side "button" to go back to the previous image.
NOTE:
This is a one-time deal. We don't store a list of all the previous images*+ just the one. I sometimes find myself wishing to see the image that just vanished, for a little longer.
This works in both sequential and random mode.
It all "looks" like this:
-------------------------------------- Three rows of buttons: |[T-L button][T-M button][T-R button]| Row 1 |[Middle 1][Middle 2][Middle 3]| Row 2 (one double- |[Middle 1][Middle 2][Middle 3]| Row 2 height button) |B-L button ][B-M Button][B-R button]| Row 3 --------------------------------------
Translated version:
------------------------------------ |[Bright ++ ][Filenames][Delay ++ ]| |----------------------------------| |[ Previous][ Pause / ][ Next ]| |[ Image ][ Resume ][ Image ]| |----------------------------------| |[Bright --][ Random ][Delay -- ]| ------------------------------------
Hold touches for rapid changes (where applicable). e.g. hold your pointer at the middle-right of the screen to load NEXT-NEXT-NEXT image as fast as your device can handle (in sequential mode, that is). Note: NEXT image works fine in random mode, but you may need to wait a moment for the image to actually load (if there are many thousands of images).
Note: The brightness control buttons are actually three buttons (each). At the very corner, changes are around 2%, move slightly further in and it doubles, and doubles again as you move your pointer/finger towards the centre of the screen. Each "button", then is 1/9th of the screen width.
You can view images sequentially or in random order; as the ESP32 has gobs of RAM, we store the IDs of previously viewed images so you don't see them again.
Storing the IDs of 20,000 images uses just over 47KiB (39KiB list + 8KiB bitmap). If Simple Slideshow encounters five consecutive ID clashes, it remembers its main purpose; which is to display images; resets the list, and starts again.
Yes, we could use this list to offer infinite "previous image" capability***, but CYD Simple Slideshow is designed to move forward.
Bottom middle button enables Random order. If you are using this, I recommend using no more than 10,000 images, and a decently long delay time (at least ten seconds, but better yet 20 or 30), as it can take over 4s to load a JPEG that is at the end of a list of 10,000. I have no idea why this is. It looks like loadJPEG() needs to iterate the names to get to the file (as the time takes matches that of our initial file scan). Or it may be something in the SD library. I might look into it, but probably not; as the delay applies to every image, the end result is the same, except with a single initial delay.
NOTE: If you switch from random to sequential mode, the new sequential order will begin from whatever image you are viewing right now.
For best results, decide on landscape or portrait, and scale every image's longest side to 320 pixels (squarer images might need the shortest side set to 240). On Windows, Irfanview has a nice batch feature for this**.
Which is to say, "for best results", make no image larger than the actual display size. Examples of /not/ best results include; canvas splitting, postage stamp corner images, and outright device crashing.
Yes, it would be possible to scale images on the ESP32, but I'm not going there. Images scaled on your PC, using a proper downsampling algorithm (Lanczos) look absolutely stunning on a CYD. Images scaled on an ESP32 are not going to look as good as those scaled on a PC. And it doesn't take long.
Simple Slideshow only displays JPEG files. You will need to process these files anyway, so you might as well save them as JPEG.
Info messages are displayed on-screen and even more to the serial console.
Serial Console Control:
You can send some commands down the serial interface. Send '?' or "help7quot; down the serial connexion for the current list of commands. At the time of writing it looks like this:t<*> Set Delay Time. Either an absolute value (t25 or t=25) or nudge up/down a second with t+ or t- b<*> Set Screen Brightness. Either an absolute % value (b50 or b=100) or nudge up/down approx. 4% with b+ or b- .|* Next Image. That's '.' or '*'. Numeric keypad operation is in mind. 0|/ Previous Image. That's '0' or '/'. - Pause / Resume Slideshow r Toggle Random / Sequential viewing order. lLoad specific image ID. (In random mode, IDs are printed to the serial console. Use debug level 6 for a list of all IDs at boot-up) f Toggle show file names. m Toggle message position (top / bottom). n Toggle file name position (top / bottom). sensor Toggle Sensor-controlled backlight ("ldr" also works). tcolor=<*> Change color of boot-up text using RGB565 value, like so: tcolor=0x3D25 ncolor=<*> Change color of file names. (Note: You can also use web hex format for colors, e.g. color=#0x3A87) bcolor=<*> Change the background color. (Short format web hex is fine, too, e.g. color=#0F0, the "#" is optional) mcolor=<*> Change the message color. (All color controls use the same format) NOTES: You MUST use the '=' format to assign colors, if you want it to work. You can send "reset" as your color value, to reset back to your hard-coded color. d Set the debug level. z TEMPORARILY set the debug level. Reverts on reboot. reset Reset the "seen" list (in random mode). uptime Print out ESP32 system uptime. info Print out lots of useful information about the system and software. 'i' also works. wipenvs Wipe NVS (permanent storage) memory. There is NO WARNING. Only use this if you want the NVS totally wiped! help Print out this help screen. '?' also works. reboot Reboots the ESP32 device. 'x' also works. Single character commands with numeric values can optionally use the '=' format; d3 and d=3 both work. "Word" commands with values *must* use the '=' format; color0x03E0 will not work.
NOTE: If you switch from random to sequential mode, the sequence will begin from whatever image you are currently viewing. Similarly, if you load image 1000 using the 'l' command, when you resume play (the 'l' command always pauses the slideshow), the sequence begins from that image, so you would see image 1001 next, and so on.
So there you have it.
Eight bucks + this sketch gets you a slideshow appliance you can power and slap on a wall somewhere. People will love it. Family and friends can tap away to their heart's delight, and one after another come the memories, and talking points. Or whatever.
** On Windows/Linux/Mac, XNView can sort images by aspect ratio: good to know.
This code is joyfully placed in the Public Domain.
Have fun! ❤
* A note about SD cards..
Format cards with a FAT (aka. "FAT16") or FAT32 file system; not exFAT. I recommend FAT32, which can store more files than FAT16.
HUGE SD cards are supported fine, but pointless. Images scaled to 320x240 are rarely over 40KiB, more like 10KiB. Filling even a 1GB SD card with small JPEGs will be a challenge on most operating systems. 10,000 images is around 320MiB, at most.
Yes, if you have a 128GB micro SD card, and throw some JPEGs on it; even if it's almost full of /other/ files; Simple Slideshow will play it just fine. But if you are buying cards specifically to play slideshows on your CYD, anything over 2GB is a waste of money.
Cheap old 1GB/2GB micro SD cards, such as one might find on eBay in lots, are ideal for working with the CYD. Class-Nada cards are fast enough for what we are doing, and can be had for a couple o' quid.
Then you just copy over your files and stick a wee bit masking tape on it; "Mix", "LScape", "NKD" or whatever on the label and you have a nice cheap selection of slideshows for your amusement/inspiration/titillation/whatever.
The humble CYD can keep these old cards out of landfill!
** Most operating systems will default to FAT32 formatting for this size of storage, which is just what we want. I use a 16KiB allocation size.
* A note about forward/backwards logic.
Oh wait, did I say my logic was backwards? What I mean is the way Simple Slideshow handles forwards/backwards instructions..
Let's say there are ten images. You are viewing image 4. You tap left to see the previous image you just missed. You are now viewing image 3. You pause.
If you go to the NEXT image, either manually or automatically, you will be viewing image 5, as 5 comes after 4, which was the current image before you progressed to 5. Basic arithmetic, right?
If you want to linger on image /4/ right now, tap the left side to view the /previous/ image, as 4 comes before 5; the current image.
There is always a way to get to any image in the previous-current-next cluster.
But wherever you currently are, you can only ever go back maximum ONE image.
*+
Well, okay, technically we do exactly that, but only to prevent repetition in random mode. I am philosophically opposed to my slideshow moving backwards.
***
But just in case you aren't that way inclined, I have included a couple of ready-made functions you can use to help turn this appliance to the dark side; may God have mercy upon your soul!
**BUGS**
I love to hear about bugs in my code. Fixing bugs is one of my favourite things and why I often start projects whilst inebriated.
But PLEASE first check that it isn't a FEATURE, described and documented right here in the sketch itself.