Skip to content

Commit a616a09

Browse files
authored
Merge pull request #3099 from adafruit/quad_eink
quad color eInk demos
2 parents e4690a4 + fc5f339 commit a616a09

File tree

8 files changed

+404
-0
lines changed

8 files changed

+404
-0
lines changed

Quad_Color_eInk_Demos/Arduino_Quad_Color_ImageReader/.uno.test.only

Whitespace-only changes.
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
// Adafruit_ImageReader test for Adafruit E-Ink Breakouts.
6+
// Demonstrates loading images from SD card or flash memory to the screen,
7+
// to RAM, and how to query image file dimensions.
8+
// Requires BMP file in root directory of QSPI Flash:
9+
// blinka.bmp.
10+
11+
#include <Adafruit_GFX.h> // Core graphics library
12+
#include "Adafruit_ThinkInk.h"
13+
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
14+
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
15+
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
16+
17+
// Comment out the next line to load from SPI/QSPI flash instead of SD card:
18+
#define USE_SD_CARD
19+
20+
#define EPD_DC 10
21+
#define EPD_CS 9
22+
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
23+
#define SRAM_CS 6
24+
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
25+
#define EPD_SPI &SPI // primary SPI
26+
#define SD_CS 5 // SD card chip select
27+
28+
// 2.13" Quadcolor EPD with JD79661 chipset
29+
ThinkInk_213_Quadcolor_AJHE5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
30+
EPD_SPI);
31+
32+
#if defined(USE_SD_CARD)
33+
SdFat SD; // SD card filesystem
34+
Adafruit_ImageReader_EPD reader(SD); // Image-reader object, pass in SD filesys
35+
#else
36+
37+
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
38+
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
39+
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
40+
PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
41+
#else
42+
#if (SPI_INTERFACES_COUNT == 1 || defined(ADAFRUIT_CIRCUITPLAYGROUND_M0))
43+
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
44+
#else
45+
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
46+
#endif
47+
#endif
48+
Adafruit_SPIFlash flash(&flashTransport);
49+
FatVolume filesys;
50+
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
51+
#endif
52+
53+
Adafruit_Image_EPD img; // An image loaded into RAM
54+
int32_t width = 0, // BMP image dimensions
55+
height = 0;
56+
57+
void setup(void) {
58+
59+
ImageReturnCode stat; // Status from image-reading functions
60+
61+
Serial.begin(115200);
62+
while(!Serial); // Wait for Serial Monitor before continuing
63+
64+
display.begin();
65+
display.setRotation(3);
66+
67+
// The Adafruit_ImageReader constructor call (above, before setup())
68+
// accepts an uninitialized SdFat or FatVolume object. This MUST
69+
// BE INITIALIZED before using any of the image reader functions!
70+
Serial.print(F("Initializing filesystem..."));
71+
// SPI or QSPI flash requires two steps, one to access the bare flash
72+
// memory itself, then the second to access the filesystem within...
73+
#if defined(USE_SD_CARD)
74+
// SD card is pretty straightforward, a single call...
75+
if(!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
76+
Serial.println(F("SD begin() failed"));
77+
for(;;); // Fatal error, do not continue
78+
}
79+
#else
80+
// SPI or QSPI flash requires two steps, one to access the bare flash
81+
// memory itself, then the second to access the filesystem within...
82+
if(!flash.begin()) {
83+
Serial.println(F("flash begin() failed"));
84+
for(;;);
85+
}
86+
if(!filesys.begin(&flash)) {
87+
Serial.println(F("filesys begin() failed"));
88+
for(;;);
89+
}
90+
#endif
91+
Serial.println(F("OK!"));
92+
93+
// Load full-screen BMP file 'blinka.bmp' at position (0,0) (top left).
94+
// Notice the 'reader' object performs this, with 'epd' as an argument.
95+
Serial.print(F("Loading blinka.bmp to canvas..."));
96+
stat = reader.drawBMP((char *)"/blinka.bmp", display, 0, 0);
97+
reader.printStatus(stat); // How'd we do?
98+
display.display();
99+
100+
// Query the dimensions of image 'blinka.bmp' WITHOUT loading to screen:
101+
Serial.print(F("Querying blinka.bmp image size..."));
102+
stat = reader.bmpDimensions("blinka.bmp", &width, &height);
103+
reader.printStatus(stat); // How'd we do?
104+
if(stat == IMAGE_SUCCESS) { // If it worked, print image size...
105+
Serial.print(F("Image dimensions: "));
106+
Serial.print(width);
107+
Serial.write('x');
108+
Serial.println(height);
109+
}
110+
111+
delay(30 * 1000); // Pause 30 seconds before continuing because it's eInk
112+
113+
}
114+
115+
void loop() {
116+
117+
}
Binary file not shown.

Quad_Color_eInk_Demos/Arduino_Quad_ThinkInk/.uno.test.only

Whitespace-only changes.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
/***************************************************
6+
Adafruit invests time and resources providing this open source code,
7+
please support Adafruit and open-source hardware by purchasing
8+
products from Adafruit!
9+
10+
Written by Limor Fried/Ladyada for Adafruit Industries.
11+
MIT license, all text above must be included in any redistribution
12+
****************************************************/
13+
14+
#include "Adafruit_ThinkInk.h"
15+
16+
#ifdef ARDUINO_ADAFRUIT_FEATHER_RP2040_THINKINK // detects if compiling for
17+
// Feather RP2040 ThinkInk
18+
#define EPD_DC PIN_EPD_DC // ThinkInk 24-pin connector DC
19+
#define EPD_CS PIN_EPD_CS // ThinkInk 24-pin connector CS
20+
#define EPD_BUSY PIN_EPD_BUSY // ThinkInk 24-pin connector Busy
21+
#define SRAM_CS -1 // use onboard RAM
22+
#define EPD_RESET PIN_EPD_RESET // ThinkInk 24-pin connector Reset
23+
#define EPD_SPI &SPI1 // secondary SPI for ThinkInk
24+
#else
25+
#define EPD_DC 10
26+
#define EPD_CS 9
27+
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
28+
#define SRAM_CS 6
29+
#define EPD_RESET 8 // can set to -1 and share with microcontroller Reset!
30+
#define EPD_SPI &SPI // primary SPI
31+
#endif
32+
33+
// 2.13" Quadcolor EPD with JD79661 chipset
34+
ThinkInk_213_Quadcolor_AJHE5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
35+
EPD_SPI);
36+
37+
void setup() {
38+
Serial.begin(115200);
39+
while (!Serial) {
40+
delay(10);
41+
}
42+
Serial.println("Adafruit EPD full update test in red/yellow/black/white");
43+
display.begin(THINKINK_QUADCOLOR);
44+
}
45+
46+
void loop() {
47+
Serial.println("Banner demo");
48+
display.clearBuffer();
49+
display.setTextSize(3);
50+
display.setCursor((display.width() - 144) / 2, (display.height() - 24) / 2);
51+
String text = "QuadColor";
52+
uint16_t colors[] = {EPD_BLACK, EPD_RED, EPD_YELLOW};
53+
54+
for (int i = 0; i < text.length(); i++) {
55+
// Change color for every character (0: BLACK, 1: RED, 2: YELLOW, 3: BLACK, etc.)
56+
display.setTextColor(colors[i % 3]);
57+
display.print(text.charAt(i));
58+
}
59+
display.display();
60+
61+
delay(15000);
62+
63+
Serial.println("Color quadrant demo");
64+
display.clearBuffer();
65+
// Top-left quadrant - EPD_BLACK
66+
display.fillRect(0, 0, display.width() / 2, display.height() / 2, EPD_BLACK);
67+
// Top-right quadrant - EPD_RED
68+
display.fillRect(display.width() / 2, 0, display.width() / 2, display.height() / 2, EPD_RED);
69+
// Bottom-left quadrant - EPD_YELLOW
70+
display.fillRect(0, display.height() / 2, display.width() / 2, display.height() / 2, EPD_YELLOW);
71+
// Bottom-right quadrant - assume you have a 4th color like EPD_WHITE or another color
72+
display.fillRect(display.width() / 2, display.height() / 2, display.width() / 2, display.height() / 2, EPD_WHITE);
73+
74+
display.display();
75+
76+
delay(15000);
77+
78+
Serial.println("Text demo");
79+
// large block of text
80+
display.clearBuffer();
81+
display.setTextSize(1);
82+
testdrawtext(
83+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur "
84+
"adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, "
85+
"fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor "
86+
"neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet "
87+
"ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a "
88+
"tortor imperdiet posuere. ",
89+
EPD_BLACK);
90+
display.display();
91+
92+
delay(15000);
93+
94+
display.clearBuffer();
95+
for (int16_t i = 0; i < display.width(); i += 4) {
96+
display.drawLine(0, 0, i, display.height() - 1, EPD_BLACK);
97+
}
98+
for (int16_t i = 0; i < display.height(); i += 4) {
99+
display.drawLine(display.width() - 1, 0, 0, i, EPD_RED);
100+
}
101+
for (int16_t i = 0; i < display.width(); i += 4) {
102+
display.drawLine(display.width()/2, display.height()-1, i, 0,
103+
EPD_YELLOW);
104+
}
105+
106+
display.display();
107+
108+
delay(15000);
109+
}
110+
111+
void testdrawtext(const char *text, uint16_t color) {
112+
display.setCursor(0, 0);
113+
display.setTextColor(color);
114+
display.setTextWrap(true);
115+
display.print(text);
116+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
"""Blinka EPD Demo for the Quad Color eInk"""
4+
import board
5+
import digitalio
6+
from PIL import Image, ImageDraw, ImageFont
7+
8+
from adafruit_epd.epd import Adafruit_EPD
9+
from adafruit_epd.jd79661 import Adafruit_JD79661
10+
11+
# create the spi device and pins we will need
12+
spi = board.SPI()
13+
ecs = digitalio.DigitalInOut(board.CE0)
14+
dc = digitalio.DigitalInOut(board.D25)
15+
srcs = None
16+
rst = digitalio.DigitalInOut(board.D27) # can be None to not use this pin
17+
busy = digitalio.DigitalInOut(board.D17) # can be None to not use this pin
18+
19+
display = Adafruit_JD79661(122, 250, spi,
20+
cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs,
21+
rst_pin=rst, busy_pin=busy)
22+
23+
display.rotation = 3
24+
width = display.width
25+
height = display.height
26+
image = Image.new("RGB", (width, height))
27+
28+
WHITE = (0xFF, 0xFF, 0xFF)
29+
YELLOW = (0xFF, 0xFF, 0x00)
30+
RED = (0xFF, 0x00, 0x00)
31+
BLACK = (0x00, 0x00, 0x00)
32+
33+
# clear the buffer
34+
display.fill(Adafruit_EPD.WHITE)
35+
36+
# Get drawing object to draw on image.
37+
draw = ImageDraw.Draw(image)
38+
# empty it
39+
draw.rectangle((0, 0, width, height), fill=WHITE)
40+
41+
# Draw an outline box
42+
draw.rectangle((1, 1, width - 2, height - 2), outline=BLACK, fill=WHITE)
43+
44+
# Draw some shapes.
45+
# First define some constants to allow easy resizing of shapes.
46+
padding = 5
47+
shape_width = 30
48+
top = padding
49+
bottom = height - padding
50+
# Move left to right keeping track of the current x position for drawing shapes.
51+
x = padding
52+
# Draw an ellipse.
53+
draw.ellipse((x, top, x + shape_width, bottom), outline=YELLOW, fill=WHITE)
54+
x += shape_width + padding
55+
# Draw a rectangle.
56+
draw.rectangle((x, top, x + shape_width, bottom), outline=RED, fill=BLACK)
57+
x += shape_width + padding
58+
# Draw a triangle.
59+
draw.polygon(
60+
[(x, bottom), (x + shape_width / 2, top), (x + shape_width, bottom)],
61+
outline=BLACK,
62+
fill=RED,
63+
)
64+
x += shape_width + padding
65+
# Draw an X.
66+
draw.line((x, bottom, x + shape_width, top), fill=YELLOW)
67+
draw.line((x, top, x + shape_width, bottom), fill=YELLOW)
68+
x += shape_width + padding
69+
70+
# Load default font.
71+
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 20)
72+
73+
draw.text((x, top), "Hello", font=font, fill=YELLOW)
74+
draw.text((x, top + 20), "World!", font=font, fill=YELLOW)
75+
76+
# Display image.
77+
display.image(image)
78+
79+
display.display()
7.87 KB
Loading

0 commit comments

Comments
 (0)