[{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/113/original/hero.jpg?1766869544","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eI wanted to make a gift for a family member that should show them animated GIFs, including sounds, of some family moments as a keepsake. I have a ton of family photos and videos and I wanted to allow the recipient to take some of the more memorable ones on-the-go in a little portable battery-powered device that's easy to use.\u003c/p\u003e\n\u003cp\u003eAfter a \u003ca href=\"https://forums.adafruit.com/viewtopic.php?t=221372\" target=\"_blank\"\u003ea lot of back-and-forth help on the Adafruit forums\u003c/a\u003e, I was finally able to settle on the final design which I then \u003ca href=\"https://github.com/skjdghsdjgsdj/noisy-gif-player\" target=\"_blank\"\u003ereleased to GitHub\u003c/a\u003e. It uses the following main components:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5691","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/4682","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3898","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3006","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3923","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/2886","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/1311","metadata":{}},{"element_type":"text","content":"\n        \u003cp\u003eAll the parts are shoved quite densely into a tiny 3D printed enclosure. It's easy to use: press the button to reset the device and a random GIF and WAV start playing. When the GIF is done, the board enters deep sleep, and wakes up again once you reset it.\u003c/p\u003e\n\u003cp\u003eTo load up the GIFs and WAVs in a compatible format, I included a wrapper script for FFmpeg. That guarantees that you can load up media that's compatible. And lastly, I added the ability to hold down one of the buttons to enter a USB mode to transfer GIFs without the need to remove the microSD card.\u003c/p\u003e\n\u003cp\u003eI learned a few important lessons on the way:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eRendering GIFs takes a lot more bandwidth and processing power than you might first think. I had to set the SPI bus speed for the LCD to its highest possible setting, way above the default value. Even a little 240x135 screen would show tearing without this.\u003c/li\u003e\n\u003cli\u003eIO speed was actually a limiting factor, not the CPU for a while. I initially tried to use an SPI-based SD card reader, but ultimately had to go with one that supported SDIO to get the transfer speeds I needed.\u003c/li\u003e\n\u003cli\u003eA design goal was to show the GIF as quickly as possible after pressing the button. I wanted to use CircuitPython, but it turned out to be just too slow at booting up.\u003c/li\u003e\n\u003cli\u003eI wanted to cleverly package the components in a way that took up the least amount of space. Fortunately, all the pins on the SDIO breakout would align perfectly to power, ground, and usable GPIO pins. I could do the same with the data pins on the I2S amplifier, although I needed to solder in extra wires to get power. It got complicated because I repurposed the SPI bus's MISO pin as a normal GPIO pin for the I2S amplifier, but that required initializing SPI without MISO, which isn't how CircuitPython worked by default. That led me down a rabbit hole that ultimately added so much complexity to getting it working in CircuitPython that Arduino ended up being easier.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eI built a prototype on a breadboard first by soldering on the full headers to all the boards, which turned out to be a good idea when I needed to make updates to the wiring and components to make it work. Once I had it working properly on the breadboard, I then built the real thing using a separate set of components I ordered.\u003c/p\u003e\n      ","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/114/original/hero.png?1766870172","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n        \u003cp\u003eSee \u003ca href=\"https://github.com/skjdghsdjgsdj/noisy-gif-player\"\u003ethe project on GitHub\u003c/a\u003e for instructions on building your own!\u003c/p\u003e\n      \n\n\n\n\n\n","metadata":{}}]