How to cycle images on
the GC9A01 with
batch conversion
What You Need
Hardware
Software & Files
- Arduino IDE with ESP32 board support
Arduino_GFX_Libraryby Moon On Our Nation- Python 3 + Pillow - image converter
- Multiple PNG images prepared and converted to
.hfiles
Batch Convert
If all your images are in one folder, convert them all at once with a shell loop. Each .h file is named after its source image automatically.
Copy and paste into terminal
for f in ~/Downloads/myimages/*.png; do name=$(basename "$f" .png); python3 ~/image_to_rgb565.py "$f" "$name"; done Replace ~/Downloads/myimages/ with the path to your images folder.
The .h files land in the same folder as your images. Move them all into your Arduino sketch folder alongside the .ino file.
Flash Memory
Each 240x240 image takes 115KB of flash. The ESP32 default partition gives the app 1MB total - shared with the compiled sketch and libraries. With multiple images you will likely hit that limit.
In Arduino IDE go to Tools → Partition Scheme → Huge APP (3MB No OTA / 1MB SPIFFS) before compiling. That gives the app 3MB, comfortably fitting around 25 images.
| Images | Flash used | Partition needed |
|---|---|---|
| 1-4 | up to ~460KB | Default (1MB) - ok |
| 5+ | 500KB+ | Huge APP (3MB) |
| ~25 | ~2.9MB | Huge APP (3MB) - limit |
The Sketch
All your edits are in one block at the top - add your #include lines and update the images[] array. NUM_IMAGES counts itself automatically. Everything below that block stays untouched. Swap interval is in milliseconds - 5000 = 5 seconds.
/*
* We stand on the shoulders of giants when we build
* with knowledge gained from others' efforts.
* That doesn't make us giants. Be humble.
* Create with care. Open source is the way.
*
* GC9A01 Cycling Multiple Images
* -------------------------------
* Cycles through multiple custom RGB565 images on a GC9A01
* 240x240 round IPS TFT display via SPI using Arduino_GFX_Library.
* Images are pre-converted from PNG using image_to_rgb565.py.
*
* Board: ESP32 Dev Board (38-pin)
* Library: Arduino_GFX_Library by Moon On Our Nation
*
* Partition: Tools -> Partition Scheme -> Huge APP (3MB No OTA)
*
* Wiring:
* VCC -> 3.3V or 5V GND -> GND
* SCL -> GPIO 18 SDA -> GPIO 23
* DC -> GPIO 27 CS -> GPIO 5
* RST -> GPIO 4
*
* Open source - MIT Licence
* Full guide:
* https://electroniczoology.com/guides/how-to-cycle-images-gc9a01-esp32
*
* Electronic Zoology - field notes from the garage
*/
#include <Arduino_GFX_Library.h>
// ---- your images - edit here ----
#include "face1.h"
#include "face2.h"
#include "face3.h"
const uint16_t* images[] = { face1, face2, face3 };
#define NUM_IMAGES (sizeof(images) / sizeof(images[0])) // auto-counts
// ----------------------------------
#define SWAP_MS 5000 // swap interval in milliseconds
#define TFT_DC 27
#define TFT_CS 5
#define TFT_RST 4
Arduino_DataBus *bus = new Arduino_HWSPI(TFT_DC, TFT_CS);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, TFT_RST, 0, true);
uint8_t idx = 0;
unsigned long lastSwap = 0;
void setup() {
Serial.begin(115200);
gfx->begin();
gfx->fillScreen(0x0000);
gfx->draw16bitRGBBitmap(0, 0, (uint16_t*)images[0], 240, 240);
lastSwap = millis();
}
void loop() {
if (millis() - lastSwap >= SWAP_MS) {
lastSwap = millis();
idx = (idx + 1) % NUM_IMAGES;
gfx->draw16bitRGBBitmap(0, 0, (uint16_t*)images[idx], 240, 240);
}
} Troubleshooting
Compile error - sketch too large / not enough flash
- Go to Tools → Partition Scheme → Huge APP (3MB No OTA / 1MB SPIFFS) and recompile
- Each image is 115KB - check how many you have included and whether it exceeds the flash partition size
Only the first image shows - display stops cycling
- Check
NUM_IMAGESmatches the number of entries in yourimages[]array - Check
SWAP_MS- if set very high it may just look like it's not cycling - Open Serial Monitor - a crash on draw will stop the loop silently
Wrong colours on one or more images
- Rerun the converter on that image and replace the
.hfile - Make sure each image was exported as RGB (not RGBA) - flatten in GIMP before converting
Compile error - variable already defined
- Each
.hfile must have a unique variable name - check all your headers don't share a name - Rename by rerunning the converter with a different varname argument