FastEPD
repository·main·Indexed 41 days ago
https://github.com/bitbank2/fastepdA C++ library for driving parallel e-ink displays on ESP32 hardware and Raspberry Pi. It features a modern API with optimizations for compressed fonts and graphics, and includes support for hardware like EPDiy V7, M5Stack PaperS3, and Inkplate. The ecosystem includes JPEGDEC, an optimized JPEG decoder for MCUs, and the fontconvert tool for generating C header files from TTF fonts.
What's inside FastEPD
- FastEPD is a complete solution designed for driving parallel e-ink displays (similar to Kindle displays) on ESP32-based hardware. It is designed as a clean, maintainable alternative to existing libraries like EPDiy, offering a simplified API and specialized features such as compressed fonts and graphics, as well as flexible display update mechanisms.
Overview of JPEGDEC features
mainJPEGDEC is an optimized JPEG decoder designed for microcontrollers (MCUs) with as little as 20K of RAM (e.g., Cortex-M0+). It is optimized for speed and provides several key features:
- Flexible Data Sources: Supports JPEG data from memory (FLASH/RAM), SDCard, or custom media via callbacks.
- Fast Downscaling: Includes built-in options for 1/2, 1/4, and 1/8 scaling.
- Exif Support: Option to detect and decode embedded Exif thumbnails.
- Dithering: Supports Floyd-Steinberg error diffusion dithering to 1, 2, or 4-bpp grayscale output, which is ideal for e-paper displays.
- Portability: The core C code is portable and has no external dependencies.
Implement Callback functions for JPEGDEC
mainJPEGDEC uses a callback-based design to isolate decoding logic from hardware-specific I/O and display drivers. The functions you must implement depend on your data source:
1. Decoding from Memory (RAM/FLASH)
If your JPEG data is already in memory, you only need to provide one callback:
- Draw function: A function to receive and draw (or store) each block of image pixels emitted by the library.
2. Decoding from External Media (e.g., SDCard)
If you are reading from an external source, you must provide five callback functions:
- Draw function: To handle pixel blocks.
- open: To open the file.
- close: To close the file.
- read: To read data from the file.
- seek: To move the file pointer.
Architecture Note for ESP32/ESP8266
On Harvard Architecture MCUs like ESP32 or ESP8266, when decoding from memory, you must use the specific open function corresponding to your storage:
openRAMoropenFLASH.How show_img handles image bit depth and panel selection
mainThe tool automatically manages image conversion and panel selection based on the input image and configuration:
- Image Conversion: Images with 2 or more bits per pixel are automatically converted to either 2-bit grayscale or b/w/r/y depending on the chosen display. Images larger than the panel resolution will cause an error.
- Panel Selection: For black/white panels, if both
panel_1bitandpanel_2bitare defined in the configuration,show_imgselects the appropriate one based on the input image. - Update Modes:
- 1-bit mode: Supports
fastandpartialupdates. - 2-bit mode: Grayscale mode does not support
fastorpartialupdates; it defaults tofullupdates. - Automatic Fallback: All update modes (including
fastandpartial) automatically becomefullwhen displaying images that require more than 1-bit per pixel.
- 1-bit mode: Supports
Run the WiFi image download and JPEG render example
mainThis example demonstrates downloading a JPEG image via WiFi and rendering it to an e-paper display using the Bitbank2 JPEG decoder (
jpegdec). This method is optimized for speed by copying decoded rows directly into the 4 BPP e-paper framebuffer in PSRAM, bypassing per-pixel drawing at the cost of software rotation and gamma correction.Prerequisites
Because this example uses the Bitbank2 JPEG decoder as an external component, you must initialize the submodules before building:
git submodule update --init --recursiveThis will place the decoder in
components/jpegdec.git submodule update --init --recursiveConfigure WiFi and display settings for the image example
mainBefore building the example, you must configure your network credentials and display dimensions in the
main/settings.hfile.Edit
main/settings.hwith the following parameters:ESP_WIFI_SSID: Your WiFi network name.ESP_WIFI_PASSWORD: Your WiFi password.EPD_WIDTH: The width of your e-paper display.EPD_HEIGHT: The height of your e-paper display.IMG_URL: The URL of the image to download. The default usesloremflickr.comwith dimensions interpolated from yourEPD_WIDTHandEPD_HEIGHT.
// Edit the file: main/settings.h // WiFi configuration #define ESP_WIFI_SSID "WIFI NAME" #define ESP_WIFI_PASSWORD "" // Add your display dimensions: #define EPD_WIDTH 1200 #define EPD_HEIGHT 825 // This is then also used here: #define IMG_URL "https://loremflickr.com/" STR(EPD_WIDTH) "/" STR(EPD_HEIGHT)Enable I2C on Raspberry Pi
mainFastEPD requires the I2C interface to be enabled on your Raspberry Pi. You can enable this using the
raspi-configutility by following these steps:- Run
sudo raspi-configin your terminal. - Navigate to Interface Options.
- Select I2C and enable it.
sudo raspi-config- Run
Convert TTF fonts using fontconvert
mainThe
fontconverttool is used to generate C header files (.h) from TrueType Font (.ttf) files. This process allows you to specify the font size and the specific range of character codes to include in the output.Character ranges typically used:
- 32 to 127: Standard ASCII set.
- 128 to 255: Extended ASCII set (Microsoft's CP1252), which includes symbols and accented characters for European Latin languages.
Note: The strings passed to FastEPD must be in ASCII or UTF-8 format.
./fontconvert <source.ttf> <output.h> <size> <start> <end> # Example: Create an 80pt Roboto-Black font with full ASCII and extended ASCII (32-255) ./fontconvert Roboto-Black.ttf Roboto_Black_80.h 80 32 255Configure SPI0 Chip Select for IT8951 HAT on Raspberry Pi
mainTo use the IT8951 HAT with this code on a Raspberry Pi, you must modify the SPI0 configuration to change or disable the default CE0 (chip select0) line. This is required because the IT8951 HAT uses BCM 27 for chip select instead of the default pin.
- Open
/boot/firmware/config.txton your Raspberry Pi. - Add the following line to the configuration:
dtoverlay=spi0-1cs,cs0_pin=27
Failure to apply this change will prevent the code from working.
dtoverlay=spi0-1cs,cs0_pin=27- Open
Configure SPI0 Chip Select for IT8951 on Raspberry Pi
mainTo use the IT8951 HAT with a Raspberry Pi, you must reconfigure the SPI0 chip select (CE0) line. By default, CE0 is used by the system, but the IT8951 HAT requires it to be moved to BCM 27 (an unused pin) to function correctly.
- Open
/boot/firmware/config.txton your Raspberry Pi. - Add the following line to the configuration:
dtoverlay=spi0-1cs,cs0_pin=27 - This configuration disables the default CE0 and assigns the chip select to BCM 27.
Note: The code will not work without this specific change.
dtoverlay=spi0-1cs,cs0_pin=27- Open
Install necessary libraries on Linux using setup.sh
mainTo run FastEPD on a Raspberry Pi, you must first install the required system libraries. Execute the provided
setup.shscript to automate this process../setup.shHow to provide JPEG data from memory
mainTo use JPEG images stored in your program's FLASH or RAM, you must convert the binary JPEG files into C arrays.
- Use a tool like
image_to_corxxdto convert the binary file into a C-style byte array. - Ensure you use the
const(andPROGMEMif applicable to your architecture) modifier so the data is stored in FLASH rather than consuming RAM.
Example of a data array structure:
const uint8_t my_jpeg_data[] = { 0xFF, 0xD8, ... };- Use a tool like