The Tiniest Photo Frame From an ESP8266-Powered Internet Clock

by arduinocelentano in Circuits > Gadgets

137 Views, 2 Favorites, 0 Comments

The Tiniest Photo Frame From an ESP8266-Powered Internet Clock

A Tiny Photo Frame from Wi-Fi Clock

This tiny gadget is sold as the "Smart Clock" or "GeekMagic Smart Weather Clock." It's a cute little IoT widget, but the proprietary software is definitely a deal-breaker. No one wants to tolerate an unknown piece of code in their wireless network. Or could we liberate it and make the "Smart Clock" even smarter? Let's find out!

πŸ’‘I used photos from the project collection assembled by jessyratfink for the demo video.
πŸ”— If you are interested in other projects that repurpose pieces of hardware in unexpected ways, such as streaming video or playing games on a text LCD, burning pictures on the optical disk surface, or reusing single use electronic devices, please consider subscribing.

Supplies

clock1.JPG
clock2.JPG

Apparently, there are two versions. The "Pro" version is reported to have a touch button and is powered by ESP32. The cheaper one I used in this project is powered by ESP8266. They can be purchased in different colors.

Project Log

disassembly1.JPG
disassembly2.JPG
disassembly3.JPG
disassembly4.JPG
disassembly5.JPG
disassembly6.JPG

I documented my progress while developing this project. In the attached pictures, you can see the internals of my "Smart Clock."

πŸ’‘You can skip this step if you don't want all the technical details.

✎ So this strange gadget just popped up among other annoying things you didn't ask for. I skimmed through the reviews customers attached and on one of the pictures saw some piece of electronics that looked like one of ESP8266 modules. So for less than 7USD you get a supposedly programmable MCU board with a nice IPS display and a neat tiny enclosure. Let's give it a try!

✎ Few weeks later. The good news is that the board has an embedded USB-TTL chip, wow! I only need a Type-C cable to upload the firmware. It works! All except the display. I sort of bricked it, so now it's a useless ESP8266 board with an unknown display that has an unknown pinout and needs an unknown driver.

✎ Few hours later. I tried to track the display connection with a multimeter. Not as easy as it sounds due to tiny pads size, but manageable. However it tells nothing about the display type, and the role of some pins is still unclear. By the way, I managed to unbrick it by uploading the official firmware. Unfortunately, only binaries are available, so it's more or less useless. Who wants an unknown binary code being executed in their home network? But maybe I could disassemble it and find out missing details?

✎ Few hours later. Forget disassembling! Now I'm nearly sure the display is some sort of ST7789. I found some pictures of similar displays and two possible pinouts. Tried to run standard Arduino examples for ST7789, but no success. Some details are still missing. Maybe I'll need to make a breakout adapter to connect the display to another ESP8266 board to test it separately. The good news is that the stock firmware still works, so I did not destroy the display.

✎ Apparently someone did the rest of the job for me. MichaΕ‚ Kalbarczyk teared down a similar gadget, probably another version of this device. But the connection was the same. Now I finally could control the display with Adafruit ST7735 and ST7789 Library!

✎ To this point I was not sure what I wanted to build with this hardware. I considered porting my recent ESP82866 project, but quickly realized that the TFT display could not be updated as quickly as monochrome OLED with this type of microcontroller.

✎ What about a tiny cute photo frame? The display seems to be suitable for it. I tried using PROGMEM to store images, and it worked pretty well. I discovered the lcd-image-converter, a tool for converting images into PROGMEM arrays. According to people who used it, it appeared to work fine, but... installing Qt seemed to be an overkill for such a simple task and using GUI to manually convert each image was not my cup of tea, so...

✎ I used ffmepeg and imagemagick to convert my images to RGB565 bmp, which is suitable for Adafruit_ST7789. Both of them worked, but ffmpeg generated better results. Maybe some imagemagick command line flags tuning could fix it. BMP headers are easy to process, so I wrote a simple Python script that simply skipped them and extracted raw BMP data in PROGMEM format. Now I can build an automated workflow for converting images, but...

✎ The bad news is the size of BMP data. With 240Γ—240 resolution and two bytes per pixel you have 115200 byte images. With 1Mb sketch partition the photo frame is limited to 5-6 pictures, because the code lives in the same partition.

✎ I looked for similar solutions and found another ESP8266 photo frame by tonyliuguo. It used similar approach with PROGMEM but with a smaller display. Nothing new.

✎ Suppose I'll move my images to SPIFFS. With 4Mb flash, and therefore max 3Mb SPIFFS partition, it gives me a space for about 20+ photos, which is slightly better. It works! And it's painfully slow.

✎ I've just discovered TFT_eSPI library. It works somewhat faster than Adafruit_ST7789. Have to rewrite my display driving code.

✎ Finally it works more or less flawlessly. But maybe I could implement some sort of image compressing? Would this hardware process JPEG?

✎ In fact, it exists. TJpg_Decoder library does exactly what I need. Now I have to rewrite my image conversion scripts to generate JPEG images instead of BMP.

✎ Finally. It works like a charm. Now I could easily store up to 150-200 photos depending on JPEG quality. Without external TF card or hardware modification. A decent photo album. To replace them I just have to place a collection of JPEG files into one directory and run a single command that scales and crops them automatically, so they are ready to uploading into SPIFFS.

✎ I know, you are thinking about uploading images via wireless interface. Well, maybe I'll implement it later. I'm also thinking about other interesting use cases of this hardware. Subscribe and stay tuned if you want to know what I'll do with this tiny gadget.

Preparing the Environment

Screenshot from 2025-05-09 16-06-13.png
Screenshot.png

Go to https://platformio.org/platformio-ide and follow the installation instructions.

In PlatformIO IDE click "Clone GIT repository" and paste the following URL:

https://github.com/arduinocelentano/smartclock-photoframe

PlatformIO should automatically download the project and the libraries it depends on.

Preparing Your Photos

006.JPG

You should convert your photos to JPEG and resize them to 240Γ—240. They should be called 1.jpg, 2.jpg, 3.jpg, etc.

To do this automatically, you can use the following Bash + Imagemagick script. You can change the JPEG_QUALITY constant to accommodate more photos.

#!/bin/bash

# Set the target size
TARGET_SIZE=240
# Set the JPEG quality (1-100)
JPEG_QUALITY=85 # You can change this value as needed

# Initialize a counter for renaming
counter=1

# Loop through all image files in the current directory
for file in *.{jpg,jpeg,png,gif,bmp}; do
# Create the new filename
new_filename="${counter}.jpg"
# Use ImageMagick to resize and crop the image
convert "$file" -resize "${TARGET_SIZE}x${TARGET_SIZE}^" -gravity center -crop "${TARGET_SIZE}x${TARGET_SIZE}+0+0" +repage -quality "$JPEG_QUALITY" "$new_filename"
echo "Saved: $new_filename with quality $JPEG_QUALITY"
# Increment the counter
((counter++))
done

echo "Image processing complete."


Copy the images to the project's data directory and set the IMAGES_COUNT constant in main.cpp. For example, if you have 150 images, it will look like this:

#define IMAGES_COUNT 150

Uploading the Photos

build-fs.png

The pictures are stored in a separate flash partition. Select Build Filesystem Image and Upload Filesystem Image in the PlatformIO tab. This process will take some time, depending on the size of your files.

⚠️ I used the eagle.flash.4m3m.ld build script, which leaves approximately 3048 KB for SPIFFS. If you could not complete this step, your filesystem image might be too large.

Uploading the Firmware

upload.png

If you wish, you can define the timeout between pictures by setting the TIMEOUT constant in main.cpp in milliseconds. For example:

#define TIMEOUT 25000

Press Platformio:Build and then Platformio:Upload button to upload the code.

Enjoy!

002.JPG
005.JPG
003.JPG
004.JPG

Enjoy your new photo frame!