Library API
Highlevel API
High-level API for drawing to e-paper displays.
The functions in this library provide a simple way to manage updates of e-paper display. To use it, follow the steps below:
First, we declare a global object that manages the display state.
EpdiyHighlevelState hl;
Then, the driver and framebuffers must be initialized.
epd_init(EPD_LUT_1K); hl = epd_hl_init(EPD_BUILTIN_WAVEFORM);
Now, we can draw to the allocated framebuffer, using the draw and text functions defined in
epdiy.h
. This will not yet update the display, but only its representation in memory.That’s it! For many application, this will be enough. For special applications and requirements, have a closer look at the// A reference to the framebuffer uint8_t* fb = epd_hl_get_framebuffer(&hl); // draw a black rectangle EpdRect some_rect = { .x = 100, .y = 100, .width = 100, .height = 100 }; epd_fill_rect(some_rect, 0x0, fb); // write a message int cursor_x = 100; int cursor_y = 300; epd_write_default(&FiraSans, "Hello, World!", &cursor_x, &cursor_y, fb); // finally, update the display! int temperature = 25; epd_poweron(); EpdDrawError err = epd_hl_update_screen(&hl, MODE_GC16, temperature); epd_poweroff();
epdiy.h
header.
Colors
Since most displays only support 16 colors, we’re only using the upper 4 bits (nibble) of a byte to detect the color.
char pixel_color = color & 0xF0;
Possible colors are 0xF0
(white) through 0x80
(median gray) til 0x00
(black).
Defines
-
EPD_BUILTIN_WAVEFORM
Functions
-
EpdiyHighlevelState epd_hl_init(const EpdWaveform *waveform)
Initialize a state object. This allocates two framebuffers and an update buffer for the display in the external PSRAM. In order to keep things simple, a chip reset is triggered if this fails.
- Parameters:
waveform – The waveform to use for updates. If you did not create your own, this will be
EPD_BUILTIN_WAVEFORM
.
- Returns:
An initialized state object.
-
uint8_t *epd_hl_get_framebuffer(EpdiyHighlevelState *state)
Get a reference to the front framebuffer. Use this to draw on the framebuffer before updating the screen with
epd_hl_update_screen()
.
-
enum EpdDrawError epd_hl_update_screen(EpdiyHighlevelState *state, enum EpdDrawMode mode, int temperature)
Update the EPD screen to match the content of the front frame buffer. Prior to this, power to the display must be enabled via
epd_poweron()
and should be disabled afterwards if no immediate additional updates follow.- Parameters:
state – A reference to the
EpdiyHighlevelState
object used.mode – The update mode to use. Additional mode settings like the framebuffer format or previous display state are determined by the driver and must not be supplied here. In most cases, one of
MODE_GC16
andMODE_GL16
should be used.temperature – Environmental temperature of the display in °C.
- Returns:
EPD_DRAW_SUCCESS
on sucess, a combination of error flags otherwise.
-
enum EpdDrawError epd_hl_update_area(EpdiyHighlevelState *state, enum EpdDrawMode mode, int temperature, EpdRect area)
Update an area of the screen to match the content of the front framebuffer. Supplying a small area to update can speed up the update process. Prior to this, power to the display must be enabled via
epd_poweron()
and should be disabled afterwards if no immediate additional updates follow.- Parameters:
state – A reference to the
EpdiyHighlevelState
object used.mode – See
epd_hl_update_screen()
.temperature – Environmental temperature of the display in °C.
area – Area of the screen to update.
- Returns:
EPD_DRAW_SUCCESS
on sucess, a combination of error flags otherwise.
-
void epd_hl_set_all_white(EpdiyHighlevelState *state)
Reset the front framebuffer to a white state.
- Parameters:
state – A reference to the
EpdiyHighlevelState
object used.
-
void epd_fullclear(EpdiyHighlevelState *state, int temperature)
Bring the display to a fully white state and get rid of any remaining artifacts.
-
struct EpdiyHighlevelState
- #include <epd_highlevel.h>
Holds the internal state of the high-level API.
Public Members
-
uint8_t *front_fb
The “front” framebuffer object.
-
uint8_t *back_fb
The “back” framebuffer object.
-
uint8_t *difference_fb
Buffer for holding the interlaced difference image.
-
bool *dirty_lines
Tainted lines based on the last difference calculation.
-
const EpdWaveform *waveform
The waveform information to use.
-
uint8_t *front_fb
Complete API
A driver library for drawing to an EPD.
Defines
-
EPD_MODE_DEFAULT
The default draw mode (non-flashy refresh, whith previously white screen).
Enums
-
enum EpdInitOptions
Global EPD driver options.
Values:
-
enumerator EPD_OPTIONS_DEFAULT
Use the default options.
-
enumerator EPD_LUT_1K
Use a small look-up table of 1024 bytes. The EPD driver will use less space, but performance may be worse.
-
enumerator EPD_LUT_64K
Use a 64K lookup table. (default) Best performance, but permanently occupies a 64k block of internal memory.
-
enumerator EPD_FEED_QUEUE_8
Use a small feed queue of 8 display lines. This uses less memory, but may impact performance.
-
enumerator EPD_FEED_QUEUE_32
Use a feed queue of 32 display lines. (default) Best performance, but larger memory footprint.
-
enumerator EPD_OPTIONS_DEFAULT
-
enum EpdDrawMode
The image drawing mode.
Values:
-
enumerator MODE_INIT
An init waveform. This is currently unused, use
epd_clear()
instead.
-
enumerator MODE_DU
Direct Update: Go from any color to black for white only.
-
enumerator MODE_GC16
Go from any grayscale value to another with a flashing update.
-
enumerator MODE_GC16_FAST
Faster version of
MODE_GC16
. Not available with default epdiy waveforms.
-
enumerator MODE_A2
Animation Mode: Fast, monochrom updates. Not available with default epdiy waveforms.
-
enumerator MODE_GL16
Go from any grayscale value to another with a non-flashing update.
-
enumerator MODE_GL16_FAST
Faster version of
MODE_GL16
. Not available with default epdiy waveforms.
-
enumerator MODE_DU4
A 4-grayscale version of
MODE_DU
. Not available with default epdiy waveforms.
-
enumerator MODE_GL4
Arbitrary transitions for 4 grayscale values. Not available with default epdiy waveforms.
-
enumerator MODE_GL16_INV
Not available with default epdiy waveforms.
-
enumerator MODE_EPDIY_WHITE_TO_GL16
Go from a white screen to arbitrary grayscale, quickly. Exclusively available with epdiy waveforms.
-
enumerator MODE_EPDIY_BLACK_TO_GL16
Go from a black screen to arbitrary grayscale, quickly. Exclusively available with epdiy waveforms.
-
enumerator MODE_EPDIY_MONOCHROME
Monochrome mode. Only supported with 1bpp buffers.
-
enumerator MODE_UNKNOWN_WAVEFORM
-
enumerator MODE_PACKING_8PPB
1 bit-per-pixel framebuffer with 0 = black, 1 = white. MSB is left is the leftmost pixel, LSB the rightmost pixel.
-
enumerator MODE_PACKING_2PPB
4 bit-per pixel framebuffer with 0x0 = black, 0xF = white. The upper nibble corresponds to the left pixel. A byte cannot wrap over multiple rows, images of uneven width must add a padding nibble per line.
-
enumerator MODE_PACKING_1PPB_DIFFERENCE
A difference image with one pixel per byte. The upper nibble marks the “from” color, the lower nibble the “to” color.
-
enumerator PREVIOUSLY_WHITE
Assert that the display has a uniform color, e.g. after initialization. If
MODE_PACKING_2PPB
is specified, a optimized output calculation can be used. Draw on a white background
-
enumerator PREVIOUSLY_BLACK
See
PREVIOUSLY_WHITE
. Draw on a black background
-
enumerator MODE_INIT
-
enum EpdRotation
Display software rotation. Sets the rotation for the purposes of the drawing and font functions Use epd_set_rotation(EPD_ROT_*) to set it using one of the options below Use epd_get_rotation() in case you need to read this value
Values:
-
enumerator EPD_ROT_LANDSCAPE
-
enumerator EPD_ROT_PORTRAIT
-
enumerator EPD_ROT_INVERTED_LANDSCAPE
-
enumerator EPD_ROT_INVERTED_PORTRAIT
-
enumerator EPD_ROT_LANDSCAPE
-
enum EpdDrawError
Possible failures when drawing.
Values:
-
enumerator EPD_DRAW_SUCCESS
-
enumerator EPD_DRAW_INVALID_PACKING_MODE
No valid framebuffer packing mode was specified.
-
enumerator EPD_DRAW_LOOKUP_NOT_IMPLEMENTED
No lookup table implementation for this mode / packing.
-
enumerator EPD_DRAW_STRING_INVALID
The string to draw is invalid.
-
enumerator EPD_DRAW_NO_DRAWABLE_CHARACTERS
The string was not empty, but no characters where drawable.
-
enumerator EPD_DRAW_FAILED_ALLOC
Allocation failed.
-
enumerator EPD_DRAW_GLYPH_FALLBACK_FAILED
A glyph could not be drawn, and not fallback was present.
-
enumerator EPD_DRAW_INVALID_CROP
The specified crop area is invalid.
-
enumerator EPD_DRAW_MODE_NOT_FOUND
No such mode is available with the current waveform.
-
enumerator EPD_DRAW_NO_PHASES_AVAILABLE
The waveform info file contains no applicable temperature range.
-
enumerator EPD_DRAW_INVALID_FONT_FLAGS
An invalid combination of font flags was used.
-
enumerator EPD_DRAW_EMPTY_LINE_QUEUE
The waveform lookup could not keep up with the display output.
Reduce the display clock speed.
-
enumerator EPD_DRAW_SUCCESS
-
enum EpdFontFlags
Font drawing flags.
Values:
-
enumerator EPD_DRAW_BACKGROUND
Draw a background.
Take the background into account when calculating the size.
-
enumerator EPD_DRAW_ALIGN_LEFT
Left-Align lines.
-
enumerator EPD_DRAW_ALIGN_RIGHT
Right-align lines.
-
enumerator EPD_DRAW_ALIGN_CENTER
Center-align lines.
-
enumerator EPD_DRAW_BACKGROUND
Functions
-
void epd_init(const EpdBoardDefinition *board, const EpdDisplay_t *display, enum EpdInitOptions options)
Initialize the ePaper display
-
const EpdDisplay_t *epd_get_display()
Get the configured display.
-
int epd_width()
Get the EPD display’s witdth.
-
int epd_height()
Get the EPD display’s height.
-
void epd_set_vcom(uint16_t vcom)
Set the display common voltage if supported.
Voltage is set as absolute value in millivolts. Although VCOM is negative, this function takes a positive (absolute) value.
-
float epd_ambient_temperature()
Get the current ambient temperature in °C, if the board has a sensor.
Get the current ambient temperature in °C, if supported by the board. Requires the display to be powered on.
-
enum EpdRotation epd_get_rotation()
Get the display rotation value
-
void epd_set_rotation(enum EpdRotation rotation)
Set the display rotation: Affects the drawing and font functions
-
int epd_rotated_display_width()
Get screen width after rotation
-
int epd_rotated_display_height()
Get screen height after rotation
-
void epd_deinit()
Deinit the ePaper display
-
void epd_poweron()
Enable display power supply.
-
void epd_poweroff()
Disable display power supply.
-
void epd_clear()
Clear the whole screen by flashing it.
-
void epd_clear_area(EpdRect area)
Clear an area by flashing it.
- Parameters:
area – The area to clear.
-
void epd_clear_area_cycles(EpdRect area, int cycles, int cycle_time)
Clear an area by flashing it.
- Parameters:
area – The area to clear.
cycles – The number of black-to-white clear cycles.
cycle_time – Length of a cycle. Default: 50 (us).
-
void epd_copy_to_framebuffer(EpdRect image_area, const uint8_t *image_data, uint8_t *framebuffer)
Draw a picture to a given framebuffer.
- Parameters:
image_area – The area to copy to.
width
andheight
of the area must correspond to the image dimensions in pixels.image_data – The image data, as a buffer of 4 bit wide brightness values. Pixel data is packed (two pixels per byte). A byte cannot wrap over multiple rows, images of uneven width must add a padding nibble per line.
framebuffer – The framebuffer object, which must be
epd_width() / 2 * epd_height()
large.
-
void epd_draw_pixel(int x, int y, uint8_t color, uint8_t *framebuffer)
Draw a pixel a given framebuffer.
- Parameters:
x – Horizontal position in pixels.
y – Vertical position in pixels.
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to,
-
void epd_draw_hline(int x, int y, int length, uint8_t color, uint8_t *framebuffer)
Draw a horizontal line to a given framebuffer.
- Parameters:
x – Horizontal start position in pixels.
y – Vertical start position in pixels.
length – Length of the line in pixels.
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to, which must be
epd_width() / 2 * epd_height()
bytes large.
-
void epd_draw_vline(int x, int y, int length, uint8_t color, uint8_t *framebuffer)
Draw a horizontal line to a given framebuffer.
- Parameters:
x – Horizontal start position in pixels.
y – Vertical start position in pixels.
length – Length of the line in pixels.
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to, which must be
epd_width() / 2 * epd_height()
bytes large.
-
void epd_fill_circle_helper(int x0, int y0, int r, int corners, int delta, uint8_t color, uint8_t *framebuffer)
-
void epd_draw_circle(int x, int y, int r, uint8_t color, uint8_t *framebuffer)
Draw a circle with given center and radius
- Parameters:
x – Center-point x coordinate
y – Center-point y coordinate
r – Radius of the circle in pixels
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to,
-
void epd_fill_circle(int x, int y, int r, uint8_t color, uint8_t *framebuffer)
Draw a circle with fill with given center and radius
- Parameters:
x – Center-point x coordinate
y – Center-point y coordinate
r – Radius of the circle in pixels
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to,
-
void epd_draw_rect(EpdRect rect, uint8_t color, uint8_t *framebuffer)
Draw a rectanle with no fill color
- Parameters:
rect – The rectangle to draw.
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to,
-
void epd_fill_rect(EpdRect rect, uint8_t color, uint8_t *framebuffer)
Draw a rectanle with fill color
- Parameters:
rect – The rectangle to fill.
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to,
-
void epd_draw_line(int x0, int y0, int x1, int y1, uint8_t color, uint8_t *framebuffer)
Draw a line
- Parameters:
x0 – Start point x coordinate
y0 – Start point y coordinate
x1 – End point x coordinate
y1 – End point y coordinate
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to,
-
void epd_draw_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color, uint8_t *framebuffer)
Draw a triangle with no fill color
- Parameters:
x0 – Vertex #0 x coordinate
y0 – Vertex #0 y coordinate
x1 – Vertex #1 x coordinate
y1 – Vertex #1 y coordinate
x2 – Vertex #2 x coordinate
y2 – Vertex #2 y coordinate
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to,
-
void epd_fill_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color, uint8_t *framebuffer)
Draw a triangle with color-fill
- Parameters:
x0 – Vertex #0 x coordinate
y0 – Vertex #0 y coordinate
x1 – Vertex #1 x coordinate
y1 – Vertex #1 y coordinate
x2 – Vertex #2 x coordinate
y2 – Vertex #2 y coordinate
color – The gray value of the line (see Colors);
framebuffer – The framebuffer to draw to,
-
EpdFontProperties epd_font_properties_default()
The default font properties.
-
void epd_get_text_bounds(const EpdFont *font, const char *string, const int *x, const int *y, int *x1, int *y1, int *w, int *h, const EpdFontProperties *props)
Get the text bounds for string, when drawn at (x, y). Set font properties to NULL to use the defaults.
-
EpdRect epd_get_string_rect(const EpdFont *font, const char *string, int x, int y, int margin, const EpdFontProperties *properties)
Returns a rect with the bounds of the text
- Parameters:
font – : the font used to get the character sizes
string – pointer to c string
x – : left most position of rectangle
y – : top most point of the rectangle
margin – : to be pllied to the width and height
- Returns:
EpdRect with x and y as per the original and height and width adjusted to fit the text with the margin added as well.
-
enum EpdDrawError epd_write_string(const EpdFont *font, const char *string, int *cursor_x, int *cursor_y, uint8_t *framebuffer, const EpdFontProperties *properties)
Write text to the EPD.
-
enum EpdDrawError epd_write_default(const EpdFont *font, const char *string, int *cursor_x, int *cursor_y, uint8_t *framebuffer)
Write a (multi-line) string to the EPD.
-
const EpdGlyph *epd_get_glyph(const EpdFont *font, uint32_t code_point)
Get the font glyph for a unicode code point.
-
void epd_push_pixels(EpdRect area, short time, int color)
Darken / lighten an area for a given time.
- Parameters:
area – The area to darken / lighten.
time – The time in us to apply voltage to each pixel.
color – 1: lighten, 0: darken.
-
enum EpdDrawError epd_draw_base(EpdRect area, const uint8_t *data, EpdRect crop_to, enum EpdDrawMode mode, int temperature, const bool *drawn_lines, const EpdWaveform *waveform)
Base function for drawing an image on the screen. If It is very customizable, and the documentation below should be studied carefully. For simple applications, use the epdiy highlevel api in “epd_higlevel.h”.
- Parameters:
area – The area of the screen to draw to. This can be imagined as shifting the origin of the frame buffer.
data – A full framebuffer of display data. It’s structure depends on the chosen
mode
.crop_to – Only draw a part of the frame buffer. Set to
epd_full_screen()
to draw the full buffer.mode – Specifies the Waveform used, the framebuffer format and additional information, like if the display is cleared.
temperature – The temperature of the display in °C. Currently, this is unused by the default waveforms at can be set to room temperature, e.g. 20-25°C.
drawn_lines – If not NULL, an array of at least the height of the image. Every line where the corresponding value in
lines
isfalse
will be skipped.waveform – The waveform information to use for drawing. If you don’t have special waveforms, use
EPD_BUILTIN_WAVEFORM
.
- Returns:
EPD_DRAW_SUCCESS
on sucess, a combination of error flags otherwise.
-
EpdRect epd_difference_image_cropped(const uint8_t *to, const uint8_t *from, EpdRect crop_to, uint8_t *interlaced, bool *dirty_lines, bool *previously_white, bool *previously_black)
Calculate a
MODE_PACKING_1PPB_DIFFERENCE
difference image from twoMODE_PACKING_2PPB
(4 bit-per-pixel) buffers. If you’re using the epdiy highlevel api, this is handled by the update functions.- Parameters:
to – The goal image as 4-bpp (
MODE_PACKING_2PPB
) framebuffer.from – The previous image as 4-bpp (
MODE_PACKING_2PPB
) framebuffer.crop_to – Only calculate the difference for a crop of the input framebuffers. The
interlaced
will not be modified outside the crop area.interlaced – The resulting difference image in
MODE_PACKING_1PPB_DIFFERENCE
format.dirty_lines – An array of at least
epd_height()
. The positions corresponding to lines whereto
andfrom
differ are set totrue
, otherwise tofalse
.previously_white – If not NULL, it is set to
true
if the considered crop of thefrom
-image is completely white.previously_black – If not NULL, it is set to
true
if the considered crop of thefrom
-image is completely black.
- Returns:
The smallest rectangle containing all changed pixels.
-
EpdRect epd_difference_image(const uint8_t *to, const uint8_t *from, uint8_t *interlaced, bool *dirty_lines)
Simplified version of
epd_difference_image_cropped()
, which considers the whole display frame buffer.See
epd_difference_image_cropped() for details.
-
uint8_t epd_get_pixel(int x, int y, int fb_width, int fb_height, const uint8_t *framebuffer)
Return the pixel color of a 4 bit image array x,y coordinates of the image pixel fb_width, fb_height dimensions
- Returns:
uint8_t 0-255 representing the color on given coordinates (as in epd_draw_pixel)
-
void epd_draw_rotated_image(EpdRect image_area, const uint8_t *image_buffer, uint8_t *framebuffer)
Draw an image reading pixel per pixel and being rotation aware (via epd_draw_pixel)
-
void epd_draw_rotated_transparent_image(EpdRect image_area, const uint8_t *image_buffer, uint8_t *framebuffer, uint8_t transparent_color)
Draw an image reading pixel per pixel and being rotation aware (via epd_draw_pixel) With an optional transparent color (color key transparency)
-
void epd_set_lcd_pixel_clock_MHz(int frequency)
Override the pixel clock when using the LCD driver for display output (Epdiy V7+). This may result in draws failing if it’s set too high!
This method can be used to tune your application for maximum refresh speed, if you can guarantee the driver can keep up.
-
struct EpdRect
- #include <epdiy.h>
An area on the display.
Internals
Internal definitions and auxiliary data types.
Unless you want to extend the library itself (Which you are very welcome to do), you will most likely not need to know about this file.
Defines
-
MINIMUM_FRAME_TIME
minimal draw time in ms for a frame layer, which will allow all particles to set properly.
-
MONOCHROME_FRAME_TIME
Frame draw time for monochrome mode in 1/10 us.
Variables
-
const EpdWaveform epdiy_ED060SC4
-
const EpdWaveform epdiy_ED097OC4
-
const EpdWaveform epdiy_ED047TC1
-
const EpdWaveform epdiy_ED047TC2
-
const EpdWaveform epdiy_ED097TC2
-
const EpdWaveform epdiy_ED060XC3
-
const EpdWaveform epdiy_ED060SCT
-
const EpdWaveform epdiy_ED133UT2
-
struct EpdWaveformPhases
-
struct EpdWaveformMode
-
struct EpdWaveformTempInterval
-
struct EpdWaveform
Public Members
-
uint8_t num_modes
-
uint8_t num_temp_ranges
-
EpdWaveformMode const **mode_data
-
EpdWaveformTempInterval const *temp_intervals
-
uint8_t num_modes
-
struct EpdGlyph
- #include <epd_internals.h>
Font data stored PER GLYPH.
Public Members
-
uint16_t width
Bitmap dimensions in pixels.
-
uint16_t height
Bitmap dimensions in pixels.
-
uint16_t advance_x
Distance to advance cursor (x axis)
-
int16_t left
X dist from cursor pos to UL corner.
-
int16_t top
Y dist from cursor pos to UL corner.
-
uint32_t compressed_size
Size of the zlib-compressed font data.
-
uint32_t data_offset
Pointer into EpdFont->bitmap.
-
uint16_t width
-
struct EpdUnicodeInterval
- #include <epd_internals.h>
Glyph interval structure.
-
struct EpdFont
- #include <epd_internals.h>
Data stored for FONT AS A WHOLE.
Public Members
-
const uint8_t *bitmap
Glyph bitmaps, concatenated.
-
const EpdUnicodeInterval *intervals
Valid unicode intervals for this font.
-
uint32_t interval_count
Number of unicode intervals.
-
bool compressed
Does this font use compressed glyph bitmaps?
-
uint16_t advance_y
Newline distance (y axis)
-
int ascender
Maximal height of a glyph above the base line.
-
int descender
Maximal height of a glyph below the base line.
-
const uint8_t *bitmap
Board-Specific Extensions
Board-specific functions that are only conditionally defined.
Functions
-
void epd_powerdown_lilygo_t5_47()
This is a Lilygo47 specific function
This is a work around a hardware issue with the Lilygo47 epd_poweroff() turns off the epaper completely however the hardware of the Lilygo47 is different than the official boards. Which means that on the Lilygo47 this disables power to the touchscreen.
This is a workaround to allow to disable display power but not the touch screen. On the Lilygo the epd power flag was re-purposed as power enable for everything. This is a hardware thing.
Please use
epd_poweroff() and epd_deinit() whenever you sleep the system. The following code can be used to sleep the lilygo and power down the peripherals and wake the unit on touch. However is should be noted that the touch controller is not powered and as such the touch coordinates will not be captured. Arduino specific code:epd_poweroff(); epd_deinit(); esp_sleep_enable_ext1_wakeup(GPIO_SEL_13, ESP_EXT1_WAKEUP_ANY_HIGH); esp_deep_sleep_start();
Warning
This workaround may still leave power on to epd and as such may cause other problems such as grey screen.
-
void epd_powerdown() __attribute__((deprecated))