Compare commits

..

6 commits

Author SHA1 Message Date
Phillip Burgess
7c8cac018e Some doxy, and starting to implement diffusion dither 2020-11-11 21:45:21 -08:00
Phillip Burgess
4016b1f805 ThinkInk WIP (starting to work, gotta call right constructor/begin combo!) 2020-11-11 19:47:54 -08:00
Phillip Burgess
ca867284d1 ThinkInk WIP still not there 2020-11-11 18:21:50 -08:00
Phillip Burgess
27826c9e79 ThinkInk WIP but still not quite working 2020-11-11 18:01:52 -08:00
Phillip Burgess
63b1a38356 ThinkInk WIP but not working 2020-11-11 16:48:12 -08:00
Phillip Burgess
6744d14d7c WIP for ThinkInk-ready reader class 2020-11-06 16:50:54 -08:00
51 changed files with 864 additions and 1006 deletions

View file

@ -1,22 +0,0 @@
Language: Cpp
BasedOnStyle: Google
IndentWidth: 2
ColumnLimit: 80
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBraces: Attach
DerivePointerAlignment: false
PointerAlignment: Right
SpacesBeforeTrailingComments: 1
IndentCaseLabels: true
SortIncludes: false
AlignTrailingComments: true
MaxEmptyLinesToKeep: 2
SpaceAfterCStyleCast: false
AllowShortBlocksOnASingleLine: false
KeepEmptyLinesAtTheStartOfBlocks: true
AccessModifierOffset: -2
IndentAccessModifiers: false

View file

@ -8,18 +8,17 @@ jobs:
fail-fast: false
matrix:
arduino-platform: ["uno", "leonardo", "mega2560", "esp8266", "esp32",
"zero", "metro_m4", "nrf52840", "pybadge",
"hallowing_m4", "cpb", "cpx_ada", "pyportal",
"feather_rp2040"]
"zero", "metro_m4", "nrf52840", "pybadge", "hallowing_m4",
"cpb", "cpx_ada", "pyportal"]
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v4
- uses: actions/setup-python@v1
with:
python-version: '3.8'
- uses: actions/checkout@v3
- uses: actions/checkout@v3
- uses: actions/checkout@v2
- uses: actions/checkout@v2
with:
repository: adafruit/ci-arduino
path: ci
@ -34,12 +33,12 @@ jobs:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/setup-python@v4
- uses: actions/setup-python@v1
with:
python-version: '3.x'
- uses: actions/checkout@v3
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/checkout@v2
with:
repository: adafruit/ci-arduino
path: ci

View file

@ -214,7 +214,7 @@ void Adafruit_Image::draw(Adafruit_SPITFT &tft, int16_t x, int16_t y) {
often be in pre-setup() declaration, but DOES need initializing
before any of the image loading or size functions are called!
*/
Adafruit_ImageReader::Adafruit_ImageReader(FatVolume &fs) { filesys = &fs; }
Adafruit_ImageReader::Adafruit_ImageReader(FatFileSystem &fs) { filesys = &fs; }
/*!
@brief Destructor.
@ -246,7 +246,7 @@ Adafruit_ImageReader::~Adafruit_ImageReader(void) {
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
completion, other values on failure).
*/
ImageReturnCode Adafruit_ImageReader::drawBMP(const char *filename,
ImageReturnCode Adafruit_ImageReader::drawBMP(char *filename,
Adafruit_SPITFT &tft, int16_t x,
int16_t y, boolean transact) {
uint16_t tftbuf[BUFPIXELS]; // Temp space for buffering TFT data
@ -270,7 +270,7 @@ ImageReturnCode Adafruit_ImageReader::drawBMP(const char *filename,
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
completion, other values on failure).
*/
ImageReturnCode Adafruit_ImageReader::loadBMP(const char *filename,
ImageReturnCode Adafruit_ImageReader::loadBMP(char *filename,
Adafruit_Image &img) {
// Call core BMP-reading function. TFT and working buffer are NULL
// (unused and allocated in function, respectively), X & Y position are
@ -308,7 +308,7 @@ ImageReturnCode Adafruit_ImageReader::loadBMP(const char *filename,
completion, other values on failure).
*/
ImageReturnCode Adafruit_ImageReader::coreBMP(
const char *filename, // SD file to load
char *filename, // SD file to load
Adafruit_SPITFT *tft, // Pointer to TFT object, or NULL if to image
uint16_t *dest, // TFT working buffer, or NULL if to canvas
int16_t x, // Position if loading to TFT (else ignored)
@ -464,9 +464,9 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
}
for (row = 0; row < loadHeight; row++) { // For each scanline...
#ifdef ESP8266
delay(1); // Keep ESP8266 happy
#endif
yield(); // Keep ESP8266 happy
// Seek to start of scan line. It might seem labor-intensive
// to be doing this on every line, but this method covers a
// lot of gritty details like cropping, flip and scanline
@ -529,8 +529,8 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
}
} else { // Canvas is simpler,
file.read(sdbuf, sizeof sdbuf); // just load sdbuf
} // (destidx never resets)
srcidx = 0; // Reset bmp buf index
} // (destidx never resets)
srcidx = 0; // Reset bmp buf index
}
if (depth == 24) {
// Convert each pixel from BMP to 565 format, save in dest
@ -564,7 +564,7 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
}
}
}
} // end pixel loop
} // end pixel loop
if (tft) { // Drawing to TFT?
if (destidx) { // Any remainders?
// See notes above re: DMA
@ -584,11 +584,11 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
img->palette = quantized; // Keep palette with img
}
} // end depth>24 or quantized malloc OK
} // end top/left clip
} // end malloc check
} // end depth check
} // end planes/compression check
} // end signature
} // end top/left clip
} // end malloc check
} // end depth check
} // end planes/compression check
} // end signature
file.close();
return status;
@ -605,7 +605,7 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
completion, other values on failure).
*/
ImageReturnCode Adafruit_ImageReader::bmpDimensions(const char *filename,
ImageReturnCode Adafruit_ImageReader::bmpDimensions(char *filename,
int32_t *width,
int32_t *height) {
@ -628,9 +628,9 @@ ImageReturnCode Adafruit_ImageReader::bmpDimensions(const char *filename,
}
status = IMAGE_SUCCESS; // YAY.
}
file.close();
}
file.close();
return status;
}
@ -643,7 +643,7 @@ ImageReturnCode Adafruit_ImageReader::bmpDimensions(const char *filename,
@return Unsigned 16-bit value, native endianism.
*/
uint16_t Adafruit_ImageReader::readLE16(void) {
#if !defined(ESP32) && !defined(ESP8266) && \
#if !defined(ESP32) && !defined(ESP8266) && \
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
// Read directly into result -- BMP data and variable both little-endian.
uint16_t result;
@ -662,7 +662,7 @@ uint16_t Adafruit_ImageReader::readLE16(void) {
@return Unsigned 32-bit value, native endianism.
*/
uint32_t Adafruit_ImageReader::readLE32(void) {
#if !defined(ESP32) && !defined(ESP8266) && \
#if !defined(ESP32) && !defined(ESP8266) && \
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
// Read directly into result -- BMP data and variable both little-endian.
uint32_t result;

View file

@ -94,20 +94,20 @@ protected:
*/
class Adafruit_ImageReader {
public:
Adafruit_ImageReader(FatVolume &fs);
Adafruit_ImageReader(FatFileSystem &fs);
~Adafruit_ImageReader(void);
ImageReturnCode drawBMP(const char *filename, Adafruit_SPITFT &tft, int16_t x,
ImageReturnCode drawBMP(char *filename, Adafruit_SPITFT &tft, int16_t x,
int16_t y, boolean transact = true);
ImageReturnCode loadBMP(const char *filename, Adafruit_Image &img);
ImageReturnCode bmpDimensions(const char *filename, int32_t *w, int32_t *h);
ImageReturnCode loadBMP(char *filename, Adafruit_Image &img);
ImageReturnCode bmpDimensions(char *filename, int32_t *w, int32_t *h);
void printStatus(ImageReturnCode stat, Stream &stream = Serial);
protected:
FatVolume *filesys; ///< FAT FileSystem Object
File32 file; ///< Current Open file
ImageReturnCode coreBMP(const char *filename, Adafruit_SPITFT *tft,
uint16_t *dest, int16_t x, int16_t y,
Adafruit_Image *img, boolean transact);
FatFileSystem *filesys; ///< FAT FileSystem Object
File file; ///< Current Open file
ImageReturnCode coreBMP(char *filename, Adafruit_SPITFT *tft, uint16_t *dest,
int16_t x, int16_t y, Adafruit_Image *img,
boolean transact);
uint16_t readLE16(void);
uint32_t readLE32(void);
};

View file

@ -6,86 +6,6 @@
#define BUFPIXELS 200 ///< 200 * 5 = 1000 bytes
#endif
/*!
@brief Maps RGB color values to EPD display colors based on display mode.
@param r
Red component of the color (0-255).
@param g
Green component of the color (0-255).
@param b
Blue component of the color (0-255).
@param mode
The display mode (THINKINK_MONO, THINKINK_TRICOLOR,
THINKINK_GRAYSCALE4, THINKINK_QUADCOLOR, etc.) that
determines the available colors and mapping strategy.
@return EPD color constant (EPD_BLACK, EPD_WHITE, EPD_RED, EPD_YELLOW,
EPD_DARK, EPD_LIGHT) appropriate for the display mode.
@note Color mapping thresholds:
- Monochrome: Simple average threshold at 128
- Tricolor: Black < 0x60, Red >= 0x80 (red only), White otherwise
- Grayscale: Black < 0x40, Dark < 0x80, Light < 0xC0, White >= 0xC0
- Quadcolor: Black < 0x60, White >= 0xE0 (all channels),
Yellow >= 0xC0 red + >= 0x80 green, Red >= 0xC0 red + < 0x80
green
*/
uint8_t Adafruit_ImageReader_EPD::mapColorForDisplay(uint8_t r, uint8_t g,
uint8_t b,
thinkinkmode_t mode) {
switch (mode) {
case THINKINK_MONO:
case THINKINK_MONO_PARTIAL:
if ((r + g + b) / 3 < 128) {
return EPD_BLACK;
} else {
return EPD_WHITE;
}
case THINKINK_TRICOLOR:
if ((r < 0x60) && (g < 0x60) && (b < 0x60)) {
return EPD_BLACK;
} else if ((r >= 0x80) && (g < 0x80) && (b < 0x80)) {
return EPD_RED;
} else {
return EPD_WHITE;
}
case THINKINK_GRAYSCALE4: {
uint8_t gray = (r + g + b) / 3;
if (gray < 0x40) {
return EPD_BLACK;
} else if (gray < 0x80) {
return EPD_DARK;
} else if (gray < 0xC0) {
return EPD_LIGHT;
} else {
return EPD_WHITE;
}
}
case THINKINK_QUADCOLOR:
if ((r < 0x60) && (g < 0x60) && (b < 0x60)) {
return EPD_BLACK;
} else if ((r >= 0xE0) && (g >= 0xE0) && (b >= 0xE0)) {
return EPD_WHITE;
} else if ((r >= 0xC0) && (g >= 0x80) && (b < 0x40)) {
return EPD_YELLOW;
} else if ((r >= 0xC0) && (g < 0x80) && (b < 0x40)) {
return EPD_RED;
} else {
return EPD_WHITE;
}
default:
if ((r < 0x60) && (g < 0x60) && (b < 0x60)) {
return EPD_BLACK;
} else if ((r >= 0x80) && (g < 0x80) && (b < 0x80)) {
return EPD_RED;
} else {
return EPD_WHITE;
}
}
}
/*!
@brief Draw image to an Adafruit ePaper-type display.
@param epd
@ -123,16 +43,24 @@ void Adafruit_Image_EPD::draw(Adafruit_EPD &epd, int16_t x, int16_t y) {
} else if (format == IMAGE_8) {
} else if (format == IMAGE_16) {
uint16_t *buffer = canvas.canvas16->getBuffer();
thinkinkmode_t displayMode = epd.getMode();
while (row < y + canvas.canvas16->height()) {
// RGB in 565 format
uint8_t r = (*buffer & 0xf800) >> 8;
uint8_t g = (*buffer & 0x07e0) >> 3;
uint8_t b = (*buffer & 0x001f) << 3;
uint8_t c =
Adafruit_ImageReader_EPD::mapColorForDisplay(r, g, b, displayMode);
uint8_t c = 0;
if ((r < 0x60) && (g < 0x60) && (b < 0x60)) {
c = EPD_BLACK; // try to infer black
} else if ((r < 0x80) && (g < 0x80) && (b < 0x80)) {
c = EPD_DARK; // try to infer dark gray
} else if ((r < 0xD0) && (g < 0xD0) && (b < 0xD0)) {
c = EPD_LIGHT; // try to infer light gray
} else if ((r >= 0x80) && (g >= 0x80) && (b >= 0x80)) {
c = EPD_WHITE;
} else if (r >= 0x80) {
c = EPD_RED; // try to infer red color
}
epd.writePixel(col, row, c);
col++;
@ -160,7 +88,7 @@ void Adafruit_Image_EPD::draw(Adafruit_EPD &epd, int16_t x, int16_t y) {
often be in pre-setup() declaration, but DOES need initializing
before any of the image loading or size functions are called!
*/
Adafruit_ImageReader_EPD::Adafruit_ImageReader_EPD(FatVolume &fs)
Adafruit_ImageReader_EPD::Adafruit_ImageReader_EPD(FatFileSystem &fs)
: Adafruit_ImageReader(fs) {}
/*!
@ -229,7 +157,7 @@ ImageReturnCode Adafruit_ImageReader_EPD::coreBMP(
int16_t y,
Adafruit_Image_EPD *img, // NULL if load-to-screen
boolean transact) { // SD & EPD sharing bus, use transactions
thinkinkmode_t displayMode = epd ? epd->getMode() : THINKINK_TRICOLOR;
ImageReturnCode status = IMAGE_ERR_FORMAT; // IMAGE_SUCCESS on valid file
uint32_t offset; // Start of image data in file
uint32_t headerSize; // Indicates BMP version
@ -241,7 +169,7 @@ ImageReturnCode Adafruit_ImageReader_EPD::coreBMP(
uint16_t *quantized = NULL; // EPD Color palette
uint32_t rowSize; // >bmpWidth if scanline padding
uint8_t sdbuf[3 * BUFPIXELS]; // BMP read buf (R+G+B/pixel)
int16_t epd_col = 0, epd_row = 0;
int16_t epd_col, epd_row;
#if ((3 * BUFPIXELS) <= 255)
uint8_t srcidx = sizeof sdbuf; // Current position in sdbuf
#else
@ -369,14 +297,23 @@ ImageReturnCode Adafruit_ImageReader_EPD::coreBMP(
(quantized = (uint16_t *)malloc(colors * sizeof(uint16_t)))) {
if (depth < 16) {
// Load and quantize color table
thinkinkmode_t displayMode =
epd ? epd->getMode() : THINKINK_TRICOLOR;
for (uint16_t c = 0; c < colors; c++) {
b = file.read();
g = file.read();
r = file.read();
(void)file.read(); // Ignore 4th byte
color = mapColorForDisplay(r, g, b, displayMode);
color = 0;
if ((r < 0x60) && (g < 0x60) && (b < 0x60)) {
color = EPD_BLACK; // try to infer black
} else if ((r < 0x80) && (g < 0x80) && (b < 0x80)) {
color = EPD_DARK; // try to infer dark gray
} else if ((r < 0xD0) && (g < 0xD0) && (b < 0xD0)) {
color = EPD_LIGHT; // try to infer light gray
} else if ((r >= 0x80) && (g >= 0x80) && (b >= 0x80)) {
color = EPD_WHITE;
} else if (r >= 0x80) {
color = EPD_RED; // try to infer red color
}
quantized[c] = color;
}
}
@ -454,8 +391,8 @@ ImageReturnCode Adafruit_ImageReader_EPD::coreBMP(
}
} else { // Canvas is simpler,
file.read(sdbuf, sizeof sdbuf); // just load sdbuf
} // (destidx never resets)
srcidx = 0; // Reset bmp buf index
} // (destidx never resets)
srcidx = 0; // Reset bmp buf index
}
if (depth == 24) {
// Convert each pixel from BMP to 565 format, save in dest
@ -463,7 +400,18 @@ ImageReturnCode Adafruit_ImageReader_EPD::coreBMP(
g = sdbuf[srcidx++];
r = sdbuf[srcidx++];
color = mapColorForDisplay(r, g, b, displayMode);
color = 0;
if ((r < 0x60) && (g < 0x60) && (b < 0x60)) {
color = EPD_BLACK; // try to infer black
} else if ((r < 0x80) && (g < 0x80) && (b < 0x80)) {
color = EPD_DARK; // try to infer dark gray
} else if ((r < 0xD0) && (g < 0xD0) && (b < 0xD0)) {
color = EPD_LIGHT; // try to infer light gray
} else if ((r >= 0x80) && (g >= 0x80) && (b >= 0x80)) {
color = EPD_WHITE;
} else if (r >= 0x80) {
color = EPD_RED; // try to infer red color
}
dest[destidx++] = color;
} else {
// Extract 1-bit color index
@ -490,7 +438,7 @@ ImageReturnCode Adafruit_ImageReader_EPD::coreBMP(
}
}
}
} // end pixel loop
} // end pixel loop
if (epd) { // Drawing to TFT?
if (destidx) { // Any remainders?
uint16_t index = 0;
@ -516,11 +464,11 @@ ImageReturnCode Adafruit_ImageReader_EPD::coreBMP(
img->palette = quantized; // Keep palette with img
}
} // end depth>24 or quantized malloc OK
} // end top/left clip
} // end malloc check
} // end depth check
} // end planes/compression check
} // end signature
} // end top/left clip
} // end malloc check
} // end depth check
} // end planes/compression check
} // end signature
file.close();
return status;

View file

@ -44,13 +44,10 @@ protected:
*/
class Adafruit_ImageReader_EPD : public Adafruit_ImageReader {
public:
Adafruit_ImageReader_EPD(FatVolume &fs);
Adafruit_ImageReader_EPD(FatFileSystem &fs);
ImageReturnCode drawBMP(char *filename, Adafruit_EPD &epd, int16_t x,
int16_t y, boolean transact = true);
static uint8_t mapColorForDisplay(uint8_t r, uint8_t g, uint8_t b,
thinkinkmode_t mode);
private:
ImageReturnCode coreBMP(char *filename, Adafruit_EPD *epd, uint16_t *dest,
int16_t x, int16_t y, Adafruit_Image_EPD *img,

View file

@ -0,0 +1,644 @@
#include "Adafruit_ImageReader_ThinkInk.h"
#ifdef __AVR__
#define BUFPIXELS 24 ///< 24 * 5 = 120 bytes
#else
#define BUFPIXELS 200 ///< 200 * 5 = 1000 bytes
#endif
// KEEP THIS VALUE CURRENT WITH THE LARGEST MAJOR AXIS AMONG ALL PANELS IN
// Adafruit_EPD (currently 400 px from the ThinkInk_420_* panels).
#define EPD_AXIS_MAX 400
// These are error accumulation buffers used for diffusion dithering:
static int8_t vRed[EPD_AXIS_MAX], vGreen[EPD_AXIS_MAX], vBlue[EPD_AXIS_MAX];
static int8_t hRed, hGreen, hBlue;
// Palettes are weird but are needed for error diffusion dithering, and the
// tricolor palette is used in the quantize() function. Values here are the
// perceived RGB565 values corresponding to each ink color (derived from
// the Photoshop palettes used in dither guide).
static const uint8_t
palette_mono[][4] = {{47 >> 3, 36 >> 2, 41 >> 3, EPD_BLACK},
{242 >> 3, 244 >> 2, 239 >> 3, EPD_WHITE}},
palette_tricolor[][4] = {{47 >> 3, 36 >> 2, 41 >> 3, EPD_BLACK},
{242 >> 3, 244 >> 2, 239 >> 3, EPD_WHITE},
{215 >> 3, 38 >> 2, 39 >> 3, EPD_RED}},
palette_grayscale4[][4] = {{47 >> 3, 36 >> 2, 41 >> 3, EPD_BLACK},
{112 >> 3, 105 >> 2, 107 >> 3, EPD_DARK},
{177 >> 3, 175 >> 2, 173 >> 3, EPD_LIGHT},
{242 >> 3, 244 >> 2, 239 >> 3, EPD_WHITE}};
/*!
@brief Quantize RGB565 color to one of the fixed EPD colod indices,
whatever's a closest match for the EPD display type.
@param rgb RGB565 input color.
@param mode One of the thinkinkmode_t types enumerated in
Adafruit_EPD library (e.g. THINKINK_MONO).
@return Color index into palette appropriate for mode. This is the
palette index, NOT the RGB value. The calling function may
or may not want to look up the RGB color on its own (e.g.
when doing error diffusion).
*/
static uint8_t quantize(uint16_t rgb, thinkinkmode_t mode) {
uint8_t r = rgb >> 11;
uint8_t g = (rgb >> 5) & 0x3F;
uint8_t b = rgb & 0x1F;
if (mode == THINKINK_MONO) {
// RGB-to-gray weightings here are fixed-point equivalents to
// R=0.2989, G=0.587, B=0.114, factoring in that green is a 6-bit
// value covering a larger range compared to red and blue's 5 bits.
return (uint8_t)((r * 631 + g * 611 + b * 241) >> 15); // 0 or 1
} else if (mode == THINKINK_GRAYSCALE4) {
// Same deal re: RGB-to-gray weightings
return (uint8_t)((r * 631 + g * 611 + b * 241) >> 14); // 0 to 3
} else { // THINKINK_TRICOLOR
// For the moment, doing a brute-force compare against each color
// in the tricolor palette, returning the index of the closest match
// (using distance in linear RGB space for comparison).
uint8_t i, closest_index = 0;
uint32_t closest_dist = 0xFFFFFFFF;
for (i = 0; i < sizeof palette_tricolor / sizeof palette_tricolor[0]; i++) {
int8_t dr = (r - palette_tricolor[i][0]) * 2; // Red dist
int8_t dg = g - palette_tricolor[i][1]; // Green dist
int8_t db = (b - palette_tricolor[i][2]) * 2; // Blue dist
uint32_t dist = dr * dr + dg * dg + db * db; // Dist^2
if (dist < closest_dist) { // No sqrt needed, because relative compare
closest_dist = dist;
closest_index = i;
}
}
return closest_index;
}
}
/*!
@brief Reset error accumulation buffers prior to diffusion dithering
(before reading BMP or rendering via draw()).
@param rgb If true, display has some colors (not mono or gray).
@return None (void).
*/
static void dither_reset(bool rgb) {
memset(vRed, 0, sizeof vRed);
hRed = 0;
if (rgb) {
memset(vGreen, 0, sizeof vGreen);
memset(vBlue, 0, sizeof vBlue);
hGreen = hBlue = 0;
}
}
/*!
@brief Draw span of pixels from source buffer to EPD display, applying
quantization and dithering as requested. Clipping is already
handled in calling function; coordinates can safely be assumed
fully in-image at this point. This ONLY does a horizontal span,
not a 2D rect. Input data will ALWAYS be 16-bit RGB565 at this
point (bitmaps have been expanded).
@param src Source data; array of pixels in 16-bit RGB565 format.
@param epd Screen to draw to (any Adafruit_EPD-derived class).
@param x Horizontal offset in pixels; left edge = 0,
positive = right. Screen rotation setting is observed.
@param y Vertical offset in pixels; top edge = 0, positive = down.
@param width Width of span to draw, in pixels.
@param mode One of the thinkinkmode_t types enumerated in
Adafruit_EPD library (e.g. THINKINK_MONO).
@param dither One of the dither_t values enumerated in header -
DITHER_NONE, DITHER_ORDERED or DITHER_DIFFUSION.
@return None (void).
*/
static void span(uint16_t *src, Adafruit_EPD *epd, int16_t x, int16_t y,
int16_t width, thinkinkmode_t mode, dither_t dither) {
uint8_t *palette;
if (mode == THINKINK_MONO) {
palette = (uint8_t *)palette_mono;
} else if (mode == THINKINK_GRAYSCALE4) {
palette = (uint8_t *)palette_grayscale4;
} else {
palette = (uint8_t *)palette_tricolor;
}
if (dither == DITHER_NONE) {
while (width--) {
epd->drawPixel(x++, y, palette[quantize(*src++, mode) * 4 + 3]);
}
} else if (dither == DITHER_PATTERN) {
// 4x4 ordered dither goes here
} else { // DITHER_DIFFUSION
while (width--) {
uint16_t rgb = *src++;
uint8_t r = rgb >> 11;
uint8_t g = (rgb >> 5) & 0x3F;
uint8_t b = rgb & 0x1F;
if (mode == THINKINK_TRICOLOR) {
} else {
// See notes in quantize() about the math here
uint16_t gray = r * 631 + g * 611 + b * 241; // 0-65535ish
}
}
}
}
/*!
@brief Draw an image in RAM to an Adafruit ThinkInk display.
@param epd Screen to draw to (any Adafruit_EPD-derived class).
@param x Horizontal offset in pixels; left edge = 0,
positive = right. Value is signed, image will be clipped
if all or part is off the screen edges. Screen rotation
setting is observed.
@param y Vertical offset in pixels; top edge = 0, positive = down.
@param mode One of the thinkinkmode_t types enumerated in
Adafruit_EPD library (e.g. THINKINK_MONO).
@param dither One of the dither_t values enumerated in header -
DITHER_NONE, DITHER_ORDERED or DITHER_DIFFUSION.
@return None (void).
*/
void Adafruit_Image_ThinkInk::draw(Adafruit_EPD &epd, int16_t x, int16_t y,
thinkinkmode_t mode, dither_t dither) {
if ((x >= epd.width()) || (y >= epd.height())) {
return; // Reject off right/bottom
}
if (format == IMAGE_1) {
int x2 = x + canvas.canvas1->width() - 1;
int y2 = y + canvas.canvas1->height() - 1;
if ((x2 < 0) || (y2 < 0)) {
return; // Reject off left/top
}
// Vertical clipping is achieved with an offset into the canvas buffer.
uint8_t *buffer = canvas.canvas1->getBuffer();
if (y < 0) { // Top clip
buffer -= y * ((canvas.canvas1->width() + 7) / 8);
y = 0;
}
if (y2 >= epd.height()) { // Bottom clip
y2 = epd.height() - 1;
}
// Horizontal clipping is peculiar by comparison...because source data
// is bit packed, need to keep track of the initial byte offset (at the
// start of each row) and bit index of the first pixel...
uint16_t initial_offset;
uint8_t initial_bit;
if (x < 0) { // Left clip
initial_offset = -x / 8;
initial_bit = 7 - (-x & 7); // 7 to 0
x = 0;
} else {
initial_offset = initial_bit = 0;
}
if (x2 >= epd.width()) { // Right clip
x2 = epd.width() - 1;
}
epd.startWrite();
if (dither == DITHER_DIFFUSION) {
dither_reset((mode == THINKINK_TRICOLOR));
}
uint16_t epdbuf[BUFPIXELS]; // Temp space for buffering EPD data
uint16_t destidx = 0;
for (; y <= y2; y++) { // For each row...
uint16_t offset = initial_offset;
uint8_t bit = initial_bit;
int span_x = x;
for (int16_t col = x; col <= x2; col++) {
epdbuf[destidx++] = palette[(buffer[offset] >> bit) & 1];
if (bit) {
bit--;
} else {
bit = 7;
offset++;
}
// If last pixel of row, or if epdbuf is full...
if ((col >= x2) || (destidx >= BUFPIXELS)) {
// Pass epdbuf data to span-drawing function...
span(epdbuf, &epd, span_x, y, destidx, mode, dither);
span_x += destidx; // Next span starts here
destidx = 0; // Reset epdbuf
}
}
buffer += (canvas.canvas1->width() + 7) / 8; // Offset to next row
}
} else if (format == IMAGE_8) {
// BMP reader doesn't currently handle palettized images
} else if (format == IMAGE_16) {
int x2 = x + canvas.canvas16->width() - 1;
int y2 = y + canvas.canvas16->height() - 1;
if ((x2 < 0) || (y2 < 0)) {
return; // Reject off left/top
}
uint16_t *buffer = canvas.canvas16->getBuffer();
if (y < 0) { // Top clip
buffer -= y * canvas.canvas16->width(); // Offset to first scanline
y = 0;
}
if (y2 >= epd.height()) { // Bottom clip
y2 = epd.height() - 1;
}
if (x < 0) { // Left clip
buffer += x; // Offset to first column
x = 0;
}
if (x2 >= epd.width()) { // Right clip
x2 = epd.width() - 1;
}
epd.startWrite();
if (dither == DITHER_DIFFUSION) {
dither_reset((mode == THINKINK_TRICOLOR));
}
int16_t width = x2 - x + 1;
for (; y <= y2; y++) { // For each row...
// Call span function, passing pointer into RGB565 image
span(buffer, &epd, x, y, width, mode, dither);
buffer += canvas.canvas16->width(); // Offset to next scanline
}
} // end IMAGE_16
epd.endWrite();
}
// ADAFRUIT_IMAGEREADER_THINKINK CLASS *************************************
// Loads images from SD card to screen or RAM.
/*!
@brief Constructor.
@return Adafruit_ImageReader object.
@param fs
FAT filesystem associated with this Adafruit_ImageReader
instance. Any images to load will come from this filesystem;
if multiple filesystems are required, each will require its
own Adafruit_ImageReader object. The filesystem does NOT need
to be initialized yet when passed in here (since this will
often be in pre-setup() declaration, but DOES need initializing
before any of the image loading or size functions are called!
*/
Adafruit_ImageReader_ThinkInk::Adafruit_ImageReader_ThinkInk(FatFileSystem &fs)
: Adafruit_ImageReader(fs) {}
/*!
@brief Loads BMP image file from SD card directly to Adafruit_ThinkInk
display.
@param filename Name of BMP image file to load.
@param epd Screen to draw to (any Adafruit_EPD-derived class).
@param x Horizontal offset in pixels; left edge = 0,
positive = right. Value is signed, image will be
clipped if all or part is off the screen edges.
Screen rotation setting is observed.
@param y Vertical offset in pixels; top edge = 0,
positive = down.
@param mode One of the thinkinkmode_t types enumerated in
Adafruit_EPD library (e.g. THINKINK_MONO).
@param dither One of the dither_t values enumerated in header -
DITHER_NONE, DITHER_ORDERED or DITHER_DIFFUSION.
@param transact Pass 'true' if TFT and SD are on the same SPI bus,
in which case SPI transactions are necessary. If
separate peripherals, can pass 'false'.
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
completion, other values on failure).
*/
ImageReturnCode Adafruit_ImageReader_ThinkInk::drawBMP(
char *filename, Adafruit_EPD &epd, int16_t x, int16_t y,
thinkinkmode_t mode, dither_t dither, boolean transact) {
uint16_t epdbuf[BUFPIXELS]; // Temp space for buffering EPD data
// Call core BMP-reading function, passing address to EPD object,
// EPD working buffer, and X & Y position of top-left corner (image
// will be cropped on load if necessary). Image pointer is NULL when
// reading to EPD, and transact argument is passed through.
return coreBMP(filename, &epd, epdbuf, x, y, NULL, mode, dither, transact);
}
/*!
@brief BMP-reading function common both to the draw function (to EPD)
and load function (to canvas object in RAM). BMP code has been
centralized here so if/when more BMP format variants are added
in the future, it doesn't need to be implemented, debugged and
kept in sync in two places.
@param filename Name of BMP image file to load.
@param epd Screen to draw to (any Adafruit_EPD-derived class)
if loading to screen, or NULL otherwise.
@param dest Working buffer for loading 16-bit TFT pixel data,
if loading to screen, else NULL.
@param x Horizontal offset in pixels (if loading to screen).
@param y Vertical offset in pixels (if loading to screen).
@param img Pointer to Adafruit_Image_ThinkInk object, if
loading to RAM (or NULL if loading to screen).
@param mode One of the thinkinkmode_t types enumerated in
Adafruit_EPD library (e.g. THINKINK_MONO).
@param dither One of the dither_t values enumerated in header -
DITHER_NONE, DITHER_ORDERED or DITHER_DIFFUSION
(IGNORED if loading image to canvas).
@param transact Use SPI transactions; 'true' is needed only if
loading to screen and it's on the same SPI bus as
the SD card. Other situations can use 'false'.
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
completion, other values on failure).
*/
ImageReturnCode Adafruit_ImageReader_ThinkInk::coreBMP(
char *filename, // SD file to load
Adafruit_EPD *epd, // Pointer to TFT object, or NULL if to image
uint16_t *dest, // EPD working buffer, or NULL if to canvas
int16_t x, // Position if loading to EPD (else ignored)
int16_t y,
Adafruit_Image_ThinkInk *img, // NULL if load-to-screen
thinkinkmode_t mode, dither_t dither,
boolean transact) { // SD & EPD sharing bus, use transactions
ImageReturnCode status = IMAGE_ERR_FORMAT; // IMAGE_SUCCESS on valid file
uint32_t offset; // Start of image data in file
uint32_t headerSize; // Indicates BMP version
int bmpWidth, bmpHeight; // BMP width & height in pixels
uint8_t planes; // BMP planes
uint8_t depth; // BMP bit depth
uint32_t compression = 0; // BMP compression mode
uint32_t colors = 0; // Number of colors in palette
uint16_t *quantized = NULL; // EPD Color palette
uint32_t rowSize; // >bmpWidth if scanline padding
uint8_t sdbuf[3 * BUFPIXELS]; // BMP read buf (R+G+B/pixel)
int16_t epd_col, epd_row;
#if ((3 * BUFPIXELS) <= 255)
uint8_t srcidx = sizeof sdbuf; // Current position in sdbuf
#else
uint16_t srcidx = sizeof sdbuf;
#endif
uint32_t destidx = 0;
uint8_t *dest1 = NULL; // Dest ptr for 1-bit BMPs to img
boolean flip = true; // BMP is stored bottom-to-top
uint32_t bmpPos = 0; // Next pixel position in file
int loadWidth, loadHeight, // Region being loaded (clipped)
loadX, loadY; // "
int row, col; // Current pixel pos.
uint8_t r, g, b, color; // Current pixel color
uint8_t bitIn = 0; // Bit number for 1-bit data in
uint8_t bitOut = 0; // Column mask for 1-bit data out
// If an Adafruit_Image object is passed and currently contains anything,
// free its contents as it's about to be overwritten with new stuff.
if (img)
img->dealloc();
// If BMP is being drawn off the right or bottom edge of the screen,
// nothing to do here. NOT an error, just a trivial clip operation.
if (epd && ((x >= epd->width()) || (y >= epd->height())))
return IMAGE_SUCCESS;
// Open requested file on SD card
if (!(file = filesys->open(filename, FILE_READ))) {
return IMAGE_ERR_FILE_NOT_FOUND;
}
// Parse BMP header. 0x4D42 (ASCII 'BM') is the Windows BMP signature.
// There are other values possible in a .BMP file but these are super
// esoteric (e.g. OS/2 struct bitmap array) and NOT supported here!
if (readLE16() == 0x4D42) { // BMP signature
(void)readLE32(); // Read & ignore file size
(void)readLE32(); // Read & ignore creator bytes
offset = readLE32(); // Start of image data
// Read DIB header
headerSize = readLE32();
bmpWidth = readLE32();
bmpHeight = readLE32();
// If bmpHeight is negative, image is in top-down order.
// This is not canon but has been observed in the wild.
if (bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
planes = readLE16();
depth = readLE16(); // Bits per pixel
// Compression mode is present in later BMP versions (default = none)
if (headerSize > 12) {
compression = readLE32();
(void)readLE32(); // Raw bitmap data size; ignore
(void)readLE32(); // Horizontal resolution, ignore
(void)readLE32(); // Vertical resolution, ignore
colors = readLE32(); // Number of colors in palette, or 0 for 2^depth
(void)readLE32(); // Number of colors used (ignore)
// File position should now be at start of palette (if present)
}
if (!colors)
colors = 1 << depth;
loadWidth = bmpWidth;
loadHeight = bmpHeight;
loadX = 0;
loadY = 0;
if (epd) {
// Crop area to be loaded (if destination is EPD)
if (x < 0) {
loadX = -x;
loadWidth += x;
x = 0;
}
if (y < 0) {
loadY = -y;
loadHeight += y;
y = 0;
}
if ((x + loadWidth) > epd->width())
loadWidth = epd->width() - x;
if ((y + loadHeight) > epd->height())
loadHeight = epd->height() - y;
}
if ((planes == 1) && (compression == 0)) { // Only uncompressed is handled
// BMP rows are padded (if needed) to 4-byte boundary
rowSize = ((depth * bmpWidth + 31) / 32) * 4;
// CURRENTLY ONLY 24-BIT BGR AND 1-BIT BMPS ARE SUPPORTED.
// 8-bit grayscale, 8- or 4-bit paletted, etc. are NOT HANDLED.
if ((depth == 24) || (depth == 1)) {
if (img) {
// Loading to RAM -- allocate GFX canvas
status = IMAGE_ERR_MALLOC; // Assume won't fit to start
// Future: handle other depths.
if (depth == 24) {
if ((img->canvas.canvas16 = new GFXcanvas16(bmpWidth, bmpHeight))) {
dest = img->canvas.canvas16->getBuffer();
}
} else {
if ((img->canvas.canvas1 = new GFXcanvas1(bmpWidth, bmpHeight))) {
dest1 = img->canvas.canvas1->getBuffer();
}
}
} // else loading to screen -- 'dest' pointer was passed in
if (dest || dest1) { // Supported format, alloc OK, etc.
status = IMAGE_SUCCESS;
if ((loadWidth > 0) && (loadHeight > 0)) { // Clip top/left
if (epd) { // If loading to display...
epd->startWrite(); // Start SPI (regardless of transact)
epd_col = x;
epd_row = y;
} else {
// Future: handle other depths.
if (depth == 1) {
img->format = IMAGE_1; // Is a GFX 1-bit canvas type
} else {
img->format = IMAGE_16; // Is a GFX 16-bit canvas type
}
}
if ((depth >= 16) ||
(quantized = (uint16_t *)malloc(colors * sizeof(uint16_t)))) {
if (depth < 16) {
// Load color table, quantied to RGB565. This is NOT
// converted to EPD color indices yet -- that's done
// during draw operation, as there may yet be
// dithering operations to perform.
for (uint16_t c = 0; c < colors; c++) {
b = file.read();
g = file.read();
r = file.read();
(void)file.read(); // Ignore 4th byte
quantized[c] =
((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
}
if (dither == DITHER_DIFFUSION) {
dither_reset((mode == THINKINK_TRICOLOR));
}
for (row = 0; row < loadHeight; row++) {
// EACH SCANLINE -------------------------------------------
yield(); // Keep ESP8266 happy
// Seek to start of scan line. It might seem labor-intensive
// to be doing this on every line, but this method covers a
// lot of gritty details like cropping, flip and scanline
// padding. Also, the seek only takes place if the file
// position actually needs to change (avoids a lot of cluster
// math in SD library).
if (flip) // Bitmap is stored bottom-to-top order (normal BMP)
bmpPos = offset + (bmpHeight - 1 - (row + loadY)) * rowSize;
else // Bitmap is stored top-to-bottom
bmpPos = offset + (row + loadY) * rowSize;
if (depth == 24) {
bmpPos += loadX * 3;
} else {
bmpPos += loadX / 8;
bitIn = 7 - (loadX & 7);
bitOut = 0x80;
if (img) { // If loading 1-bit image to RAM
destidx = ((bmpWidth + 7) / 8) * row;
}
}
if (file.position() != bmpPos) { // Need seek?
if (transact) {
epd->endWrite(); // End EPD SPI transaction
}
file.seek(bmpPos); // Seek = SD transaction
srcidx = sizeof sdbuf; // Force buffer reload
}
int span_x = epd_col;
for (col = 0; col < loadWidth; col++) {
// EACH PIXEL ON SCANLINE --------------------------------
if (srcidx >= sizeof sdbuf) { // Time to load more data?
if (epd && transact) {
epd->endWrite(); // End display SPI transaction
}
#if defined(ARDUINO_NRF52_ADAFRUIT)
// NRF52840 seems to have trouble reading more than 512
// bytes across certain boundaries. Workaround for now
// is to break the read into smaller chunks...
int32_t bytesToGo = sizeof sdbuf, bytesRead = 0,
bytesThisPass;
while (bytesToGo > 0) {
bytesThisPass = min(bytesToGo, 512);
file.read(&sdbuf[bytesRead], bytesThisPass);
bytesRead += bytesThisPass;
bytesToGo -= bytesThisPass;
}
#else
file.read(sdbuf, sizeof sdbuf); // Load from SD
#endif
if (epd && transact) {
epd->startWrite(); // Start next display SPI transact
}
srcidx = 0; // Reset bmp buf index
}
if (depth == 24) {
// Convert RGB pixel to 565 format, save in dest.
// Makes no difference if going to screen or canvas.
b = sdbuf[srcidx++];
g = sdbuf[srcidx++];
r = sdbuf[srcidx++];
dest[destidx++] =
((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
} else { // 1-bit
// Extract bit (color index) from BMP...
uint8_t n = (sdbuf[srcidx] >> bitIn) & 1;
if (!bitIn) {
srcidx++;
bitIn = 7;
} else {
bitIn--;
}
if (epd) { // Loading 1-bit image to display...
// RGB565 color from palette goes in EPD dest buffer...
dest[destidx++] = quantized[n];
// Even though source image is 1-bit, and display might
// be 1-bit, it's not always the case that the source
// image is black & white (could be any two RGB colors).
// Hence the expansion to RGB565. The span-rendering
// function then quantizes and/or dithers this to what
// the display can best handle. In some cases that's
// fantastically bloaty (converting 1-bit to 16-bit RGB
// and then back to 1-bit later in the span function),
// but the alternative is a TON of special case code.
// Since the EPD is slow to update anyway, we'll just
// accept it, the code isn't really the bottleneck.
} else { // Loading 1-bit image to RAM...
// Store bit in canvas1 buffer
if (n)
dest1[destidx] |= bitOut;
else
dest1[destidx] &= ~bitOut;
bitOut >>= 1;
if (!bitOut) {
bitOut = 0x80;
destidx++;
}
}
}
// If loading to display, and either we're on the last pixel
// of the current row, OR if the dest buffer is full...
if (epd &&
((col == (loadWidth - 1)) || (destidx >= BUFPIXELS))) {
// Issue a span of pixels to the display...
span(dest, epd, span_x, epd_row + row, destidx, mode,
dither);
span_x += destidx; // Next span will start here
destidx = 0; // Reset dest buffer counter
}
} // end pixel (column) loop -------------------------------
} // end scanline (row) loop -------------------------------
if (quantized) { // Was an RGB565 palette allocated?
if (epd) // If image was loaded to display,
free(quantized); // palette is no longer needed
else
img->palette = quantized; // Keep palette with img
}
} // end depth>24 or quantized malloc OK
} // end top/left clip
} // end malloc check
} // end depth check
} // end planes/compression check
} // end signature
file.close();
return status;
}

View file

@ -0,0 +1,67 @@
/*!
* @file Adafruit_ImageReader_ThinkInk.h
*
* This is part of Adafruit's ImageReader library for Arduino, designed to
* work with Adafruit_GFX plus a display device-specific library.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Written by Melissa LeBlanc-Williams for Adafruit Industries.
*
* BSD license, all text here must be included in any redistribution.
*/
#ifndef __ADAFRUIT_IMAGE_READER_THINKINK_H__
#define __ADAFRUIT_IMAGE_READER_THINKINK_H__
#include "Adafruit_ImageReader.h"
#include "Adafruit_ThinkInk.h"
typedef enum {
DITHER_NONE,
DITHER_PATTERN,
DITHER_DIFFUSION,
} dither_t;
/*!
@brief Data bundle returned with an image loaded to RAM. Used by
ImageReader.loadBMP() and Image.draw(), not ImageReader.drawBMP().
*/
class Adafruit_Image_ThinkInk : public Adafruit_Image {
public:
void draw(Adafruit_EPD &epd, int16_t x, int16_t y, thinkinkmode_t mode,
dither_t dither = DITHER_NONE);
protected:
friend class Adafruit_ImageReader_ThinkInk; ///< Loading occurs here
};
/*!
@brief An optional adjunct to Adafruit_EPD that reads bitmap or RGB
BMP images (maybe others in the future) from a flash filesystem
(SD card or SPI/QSPI flash). It's purposefully been made an
entirely separate class (rather than part of SPITFT or GFX
classes) so that Arduino code that uses GFX or SPITFT *without*
image loading does not need to incur the RAM overhead and
additional dependencies of the Adafruit_SPIFlash library by
its mere inclusion. The syntaxes can therefore be a bit
bizarre (passing display object as an argument), see examples
for use.
*/
class Adafruit_ImageReader_ThinkInk : public Adafruit_ImageReader {
public:
Adafruit_ImageReader_ThinkInk(FatFileSystem &fs);
ImageReturnCode drawBMP(char *filename, Adafruit_EPD &epd, int16_t x,
int16_t y, thinkinkmode_t mode,
dither_t dither = DITHER_NONE,
boolean transact = true);
private:
ImageReturnCode coreBMP(char *filename, Adafruit_EPD *epd, uint16_t *dest,
int16_t x, int16_t y, Adafruit_Image_ThinkInk *img,
thinkinkmode_t mode, dither_t dither,
boolean transact);
};
#endif // __ADAFRUIT_IMAGE_READER_THINKINK_H__

View file

@ -1,4 +1,4 @@
# Adafruit ImageReader Arduino Library [![Build Status](https://github.com/adafruit/Adafruit_ImageReader/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_ImageReader/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_ImageReader/html/index.html)
# Adafruit_ImageReader ![Build Status](https://github.com/adafruit/Adafruit_ImageReader/workflows/Arduino%20Library%20CI/badge.svg)
Companion library for Adafruit_GFX to load images from SD card or SPI Flash

View file

@ -9,7 +9,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_SSD1331.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -50,7 +50,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -72,7 +72,7 @@ void setup(void) {
tft.begin(); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -9,7 +9,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_SSD1351.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -54,7 +54,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -76,7 +76,7 @@ void setup(void) {
tft.begin(); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -9,7 +9,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -40,7 +40,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -61,7 +61,7 @@ void setup(void) {
tft.initR(INITR_144GREENTAB); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -9,7 +9,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -40,7 +40,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -61,7 +61,7 @@ void setup(void) {
tft.initR(INITR_BLACKTAB); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -10,7 +10,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -41,7 +41,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -63,7 +63,7 @@ void setup(void) {
Serial.println(F("TFT initialized."));
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -1,149 +0,0 @@
// Adafruit_ImageReader test for Adafruit ST7789 320x240 TFT Breakout for Arduino.
// Demonstrates loading images to the screen, to RAM, and how to query
// image file dimensions.
// Requires three BMP files in root directory of SD card:
// parrot.bmp, miniwoof.bmp and wales.bmp.
// As written, this uses the microcontroller's SPI interface for the screen
// (not 'bitbang') and must be wired to specific pins (e.g. for Arduino Uno,
// MOSI = pin 11, MISO = 12, SCK = 13). Other pins are configurable below.
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
// Comment out the next line to load from SPI/QSPI flash instead of SD card:
#define USE_SD_CARD
// TFT display and SD card share the hardware SPI interface, using
// 'select' pins for each to identify the active device on the bus.
#define SD_CS 4 // SD card select pin
#define TFT_CS 10 // TFT select pin
#define TFT_DC 8 // TFT display/command pin
#define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin
#if defined(USE_SD_CARD)
SdFat SD; // SD card filesystem
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
#else
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
#else
#if (SPI_INTERFACES_COUNT == 1)
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
#else
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Image img; // An image loaded into RAM
int32_t width = 0, // BMP image dimensions
height = 0;
void setup(void) {
ImageReturnCode stat; // Status from image-reading functions
Serial.begin(9600);
while(!Serial); // Wait for Serial Monitor before continuing
tft.init(170, 320); // Init ST7789 170x320
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
if(!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}
#else
// SPI or QSPI flash requires two steps, one to access the bare flash
// memory itself, then the second to access the filesystem within...
if(!flash.begin()) {
Serial.println(F("flash begin() failed"));
for(;;);
}
if(!filesys.begin(&flash)) {
Serial.println(F("filesys begin() failed"));
for(;;);
}
#endif
Serial.println(F("OK!"));
// Fill screen blue. Not a required step, this just shows that we're
// successfully communicating with the screen.
tft.fillScreen(ST77XX_BLUE);
tft.setRotation(3);
// Load full-screen BMP file 'adabot.bmp' at position (0,0) (top left).
// Notice the 'reader' object performs this, with 'tft' as an argument.
Serial.print(F("Loading adabot.bmp to screen..."));
stat = reader.drawBMP("/adabot.bmp", tft, 0, 0);
reader.printStatus(stat); // How'd we do?
// Query the dimensions of image 'miniwoof.bmp' WITHOUT loading to screen:
Serial.print(F("Querying miniwoof.bmp image size..."));
stat = reader.bmpDimensions("/miniwoof.bmp", &width, &height);
reader.printStatus(stat); // How'd we do?
if(stat == IMAGE_SUCCESS) { // If it worked, print image size...
Serial.print(F("Image dimensions: "));
Serial.print(width);
Serial.write('x');
Serial.println(height);
}
// Load small BMP 'wales.bmp' into a GFX canvas in RAM. This should fail
// gracefully on Arduino Uno and other small devices, meaning the image
// will not load, but this won't make the program stop or crash, it just
// continues on without it. Should work on Arduino Mega, Zero, etc.
Serial.print(F("Loading wales.bmp to canvas..."));
stat = reader.loadBMP("/wales.bmp", img);
reader.printStatus(stat); // How'd we do?
delay(2000); // Pause 2 seconds before moving on to loop()
}
void loop() {
for(int r=0; r<4; r++) { // For each of 4 rotations...
tft.setRotation(r); // Set rotation
tft.fillScreen(0); // and clear screen
// Load 4 copies of the 'miniwoof.bmp' image to the screen, some
// partially off screen edges to demonstrate clipping. Globals
// 'width' and 'height' were set by bmpDimensions() call in setup().
for(int i=0; i<4; i++) {
reader.drawBMP("/miniwoof.bmp", tft,
(tft.width() * i / 3) - (width / 2),
(tft.height() * i / 3) - (height / 2));
}
delay(1000); // Pause 1 sec.
// Draw 50 Welsh dragon flags in random positions. This has no effect
// on memory-constrained boards like the Arduino Uno, where the image
// failed to load due to insufficient RAM, but it's NOT fatal.
for(int i=0; i<50; i++) {
// Rather than reader.drawBMP() (which works from SD card),
// a different function is used for RAM-resident images:
img.draw(tft, // Pass in tft object
(int16_t)random(-img.width() , tft.width()) , // Horiz pos.
(int16_t)random(-img.height(), tft.height())); // Vert pos
// Reiterating a prior point: img.draw() does nothing and returns
// if the image failed to load. It's unfortunate but not disastrous.
}
delay(2000); // Pause 2 sec.
}
}

View file

@ -1,149 +0,0 @@
// Adafruit_ImageReader test for Adafruit ST7789 320x240 TFT Breakout for Arduino.
// Demonstrates loading images to the screen, to RAM, and how to query
// image file dimensions.
// Requires three BMP files in root directory of SD card:
// parrot.bmp, miniwoof.bmp and wales.bmp.
// As written, this uses the microcontroller's SPI interface for the screen
// (not 'bitbang') and must be wired to specific pins (e.g. for Arduino Uno,
// MOSI = pin 11, MISO = 12, SCK = 13). Other pins are configurable below.
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
// Comment out the next line to load from SPI/QSPI flash instead of SD card:
#define USE_SD_CARD
// TFT display and SD card share the hardware SPI interface, using
// 'select' pins for each to identify the active device on the bus.
#define SD_CS 4 // SD card select pin
#define TFT_CS 10 // TFT select pin
#define TFT_DC 8 // TFT display/command pin
#define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin
#if defined(USE_SD_CARD)
SdFat SD; // SD card filesystem
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
#else
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
#else
#if (SPI_INTERFACES_COUNT == 1)
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
#else
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Image img; // An image loaded into RAM
int32_t width = 0, // BMP image dimensions
height = 0;
void setup(void) {
ImageReturnCode stat; // Status from image-reading functions
Serial.begin(9600);
while(!Serial); // Wait for Serial Monitor before continuing
tft.init(172, 320); // Init ST7789 172x320
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
if(!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}
#else
// SPI or QSPI flash requires two steps, one to access the bare flash
// memory itself, then the second to access the filesystem within...
if(!flash.begin()) {
Serial.println(F("flash begin() failed"));
for(;;);
}
if(!filesys.begin(&flash)) {
Serial.println(F("filesys begin() failed"));
for(;;);
}
#endif
Serial.println(F("OK!"));
// Fill screen blue. Not a required step, this just shows that we're
// successfully communicating with the screen.
tft.fillScreen(ST77XX_BLUE);
tft.setRotation(3);
// Load full-screen BMP file 'adabot.bmp' at position (0,0) (top left).
// Notice the 'reader' object performs this, with 'tft' as an argument.
Serial.print(F("Loading adabot.bmp to screen..."));
stat = reader.drawBMP("/adabot.bmp", tft, 0, 0);
reader.printStatus(stat); // How'd we do?
// Query the dimensions of image 'miniwoof.bmp' WITHOUT loading to screen:
Serial.print(F("Querying miniwoof.bmp image size..."));
stat = reader.bmpDimensions("/miniwoof.bmp", &width, &height);
reader.printStatus(stat); // How'd we do?
if(stat == IMAGE_SUCCESS) { // If it worked, print image size...
Serial.print(F("Image dimensions: "));
Serial.print(width);
Serial.write('x');
Serial.println(height);
}
// Load small BMP 'wales.bmp' into a GFX canvas in RAM. This should fail
// gracefully on Arduino Uno and other small devices, meaning the image
// will not load, but this won't make the program stop or crash, it just
// continues on without it. Should work on Arduino Mega, Zero, etc.
Serial.print(F("Loading wales.bmp to canvas..."));
stat = reader.loadBMP("/wales.bmp", img);
reader.printStatus(stat); // How'd we do?
delay(2000); // Pause 2 seconds before moving on to loop()
}
void loop() {
for(int r=0; r<4; r++) { // For each of 4 rotations...
tft.setRotation(r); // Set rotation
tft.fillScreen(0); // and clear screen
// Load 4 copies of the 'miniwoof.bmp' image to the screen, some
// partially off screen edges to demonstrate clipping. Globals
// 'width' and 'height' were set by bmpDimensions() call in setup().
for(int i=0; i<4; i++) {
reader.drawBMP("/miniwoof.bmp", tft,
(tft.width() * i / 3) - (width / 2),
(tft.height() * i / 3) - (height / 2));
}
delay(1000); // Pause 1 sec.
// Draw 50 Welsh dragon flags in random positions. This has no effect
// on memory-constrained boards like the Arduino Uno, where the image
// failed to load due to insufficient RAM, but it's NOT fatal.
for(int i=0; i<50; i++) {
// Rather than reader.drawBMP() (which works from SD card),
// a different function is used for RAM-resident images:
img.draw(tft, // Pass in tft object
(int16_t)random(-img.width() , tft.width()) , // Horiz pos.
(int16_t)random(-img.height(), tft.height())); // Vert pos
// Reiterating a prior point: img.draw() does nothing and returns
// if the image failed to load. It's unfortunate but not disastrous.
}
delay(2000); // Pause 2 sec.
}
}

View file

@ -1,149 +0,0 @@
// Adafruit_ImageReader test for Adafruit ST7789 320x240 TFT Breakout for Arduino.
// Demonstrates loading images to the screen, to RAM, and how to query
// image file dimensions.
// Requires three BMP files in root directory of SD card:
// parrot.bmp, miniwoof.bmp and wales.bmp.
// As written, this uses the microcontroller's SPI interface for the screen
// (not 'bitbang') and must be wired to specific pins (e.g. for Arduino Uno,
// MOSI = pin 11, MISO = 12, SCK = 13). Other pins are configurable below.
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
// Comment out the next line to load from SPI/QSPI flash instead of SD card:
#define USE_SD_CARD
// TFT display and SD card share the hardware SPI interface, using
// 'select' pins for each to identify the active device on the bus.
#define SD_CS 4 // SD card select pin
#define TFT_CS 10 // TFT select pin
#define TFT_DC 8 // TFT display/command pin
#define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin
#if defined(USE_SD_CARD)
SdFat SD; // SD card filesystem
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
#else
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
#else
#if (SPI_INTERFACES_COUNT == 1)
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
#else
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Image img; // An image loaded into RAM
int32_t width = 0, // BMP image dimensions
height = 0;
void setup(void) {
ImageReturnCode stat; // Status from image-reading functions
Serial.begin(9600);
while(!Serial); // Wait for Serial Monitor before continuing
tft.init(135, 240); // Init ST7789 172x320
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
if(!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}
#else
// SPI or QSPI flash requires two steps, one to access the bare flash
// memory itself, then the second to access the filesystem within...
if(!flash.begin()) {
Serial.println(F("flash begin() failed"));
for(;;);
}
if(!filesys.begin(&flash)) {
Serial.println(F("filesys begin() failed"));
for(;;);
}
#endif
Serial.println(F("OK!"));
// Fill screen blue. Not a required step, this just shows that we're
// successfully communicating with the screen.
tft.fillScreen(ST77XX_BLUE);
tft.setRotation(3);
// Load full-screen BMP file 'adabot.bmp' at position (0,0) (top left).
// Notice the 'reader' object performs this, with 'tft' as an argument.
Serial.print(F("Loading adabot.bmp to screen..."));
stat = reader.drawBMP("/adabot.bmp", tft, 0, 0);
reader.printStatus(stat); // How'd we do?
// Query the dimensions of image 'miniwoof.bmp' WITHOUT loading to screen:
Serial.print(F("Querying miniwoof.bmp image size..."));
stat = reader.bmpDimensions("/miniwoof.bmp", &width, &height);
reader.printStatus(stat); // How'd we do?
if(stat == IMAGE_SUCCESS) { // If it worked, print image size...
Serial.print(F("Image dimensions: "));
Serial.print(width);
Serial.write('x');
Serial.println(height);
}
// Load small BMP 'wales.bmp' into a GFX canvas in RAM. This should fail
// gracefully on Arduino Uno and other small devices, meaning the image
// will not load, but this won't make the program stop or crash, it just
// continues on without it. Should work on Arduino Mega, Zero, etc.
Serial.print(F("Loading wales.bmp to canvas..."));
stat = reader.loadBMP("/wales.bmp", img);
reader.printStatus(stat); // How'd we do?
delay(2000); // Pause 2 seconds before moving on to loop()
}
void loop() {
for(int r=0; r<4; r++) { // For each of 4 rotations...
tft.setRotation(r); // Set rotation
tft.fillScreen(0); // and clear screen
// Load 4 copies of the 'miniwoof.bmp' image to the screen, some
// partially off screen edges to demonstrate clipping. Globals
// 'width' and 'height' were set by bmpDimensions() call in setup().
for(int i=0; i<4; i++) {
reader.drawBMP("/miniwoof.bmp", tft,
(tft.width() * i / 3) - (width / 2),
(tft.height() * i / 3) - (height / 2));
}
delay(1000); // Pause 1 sec.
// Draw 50 Welsh dragon flags in random positions. This has no effect
// on memory-constrained boards like the Arduino Uno, where the image
// failed to load due to insufficient RAM, but it's NOT fatal.
for(int i=0; i<50; i++) {
// Rather than reader.drawBMP() (which works from SD card),
// a different function is used for RAM-resident images:
img.draw(tft, // Pass in tft object
(int16_t)random(-img.width() , tft.width()) , // Horiz pos.
(int16_t)random(-img.height(), tft.height())); // Vert pos
// Reiterating a prior point: img.draw() does nothing and returns
// if the image failed to load. It's unfortunate but not disastrous.
}
delay(2000); // Pause 2 sec.
}
}

View file

@ -1,148 +0,0 @@
// Adafruit_ImageReader test for Adafruit ST7789 320x240 TFT Breakout for Arduino.
// Demonstrates loading images to the screen, to RAM, and how to query
// image file dimensions.
// Requires three BMP files in root directory of SD card:
// adabot.bmp, miniwoof.bmp and wales.bmp.
// As written, this uses the microcontroller's SPI interface for the screen
// (not 'bitbang') and must be wired to specific pins (e.g. for Arduino Uno,
// MOSI = pin 11, MISO = 12, SCK = 13). Other pins are configurable below.
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
// Comment out the next line to load from SPI/QSPI flash instead of SD card:
#define USE_SD_CARD
// TFT display and SD card share the hardware SPI interface, using
// 'select' pins for each to identify the active device on the bus.
#define SD_CS 4 // SD card select pin
#define TFT_CS 10 // TFT select pin
#define TFT_DC 8 // TFT display/command pin
#define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin
#if defined(USE_SD_CARD)
SdFat SD; // SD card filesystem
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
#else
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
#else
#if (SPI_INTERFACES_COUNT == 1)
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
#else
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Image img; // An image loaded into RAM
int32_t width = 0, // BMP image dimensions
height = 0;
void setup(void) {
ImageReturnCode stat; // Status from image-reading functions
Serial.begin(9600);
while(!Serial); // Wait for Serial Monitor before continuing
tft.init(240, 240); // Init ST7789 172x320
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
if(!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}
#else
// SPI or QSPI flash requires two steps, one to access the bare flash
// memory itself, then the second to access the filesystem within...
if(!flash.begin()) {
Serial.println(F("flash begin() failed"));
for(;;);
}
if(!filesys.begin(&flash)) {
Serial.println(F("filesys begin() failed"));
for(;;);
}
#endif
Serial.println(F("OK!"));
// Fill screen blue. Not a required step, this just shows that we're
// successfully communicating with the screen.
tft.fillScreen(ST77XX_BLUE);
// Load full-screen BMP file 'adabot.bmp' at position (0,0) (top left).
// Notice the 'reader' object performs this, with 'tft' as an argument.
Serial.print(F("Loading adabot.bmp to screen..."));
stat = reader.drawBMP("/adabot.bmp", tft, 0, 0);
reader.printStatus(stat); // How'd we do?
// Query the dimensions of image 'miniwoof.bmp' WITHOUT loading to screen:
Serial.print(F("Querying miniwoof.bmp image size..."));
stat = reader.bmpDimensions("/miniwoof.bmp", &width, &height);
reader.printStatus(stat); // How'd we do?
if(stat == IMAGE_SUCCESS) { // If it worked, print image size...
Serial.print(F("Image dimensions: "));
Serial.print(width);
Serial.write('x');
Serial.println(height);
}
// Load small BMP 'wales.bmp' into a GFX canvas in RAM. This should fail
// gracefully on Arduino Uno and other small devices, meaning the image
// will not load, but this won't make the program stop or crash, it just
// continues on without it. Should work on Arduino Mega, Zero, etc.
Serial.print(F("Loading wales.bmp to canvas..."));
stat = reader.loadBMP("/wales.bmp", img);
reader.printStatus(stat); // How'd we do?
delay(2000); // Pause 2 seconds before moving on to loop()
}
void loop() {
for(int r=0; r<4; r++) { // For each of 4 rotations...
tft.setRotation(r); // Set rotation
tft.fillScreen(0); // and clear screen
// Load 4 copies of the 'miniwoof.bmp' image to the screen, some
// partially off screen edges to demonstrate clipping. Globals
// 'width' and 'height' were set by bmpDimensions() call in setup().
for(int i=0; i<4; i++) {
reader.drawBMP("/miniwoof.bmp", tft,
(tft.width() * i / 3) - (width / 2),
(tft.height() * i / 3) - (height / 2));
}
delay(1000); // Pause 1 sec.
// Draw 50 Welsh dragon flags in random positions. This has no effect
// on memory-constrained boards like the Arduino Uno, where the image
// failed to load due to insufficient RAM, but it's NOT fatal.
for(int i=0; i<50; i++) {
// Rather than reader.drawBMP() (which works from SD card),
// a different function is used for RAM-resident images:
img.draw(tft, // Pass in tft object
(int16_t)random(-img.width() , tft.width()) , // Horiz pos.
(int16_t)random(-img.height(), tft.height())); // Vert pos
// Reiterating a prior point: img.draw() does nothing and returns
// if the image failed to load. It's unfortunate but not disastrous.
}
delay(2000); // Pause 2 sec.
}
}

View file

@ -1,148 +0,0 @@
// Adafruit_ImageReader test for Adafruit ST7789 320x240 TFT Breakout for Arduino.
// Demonstrates loading images to the screen, to RAM, and how to query
// image file dimensions.
// Requires three BMP files in root directory of SD card:
// parrot.bmp, miniwoof.bmp and wales.bmp.
// As written, this uses the microcontroller's SPI interface for the screen
// (not 'bitbang') and must be wired to specific pins (e.g. for Arduino Uno,
// MOSI = pin 11, MISO = 12, SCK = 13). Other pins are configurable below.
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
// Comment out the next line to load from SPI/QSPI flash instead of SD card:
#define USE_SD_CARD
// TFT display and SD card share the hardware SPI interface, using
// 'select' pins for each to identify the active device on the bus.
#define SD_CS 4 // SD card select pin
#define TFT_CS 10 // TFT select pin
#define TFT_DC 8 // TFT display/command pin
#define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin
#if defined(USE_SD_CARD)
SdFat SD; // SD card filesystem
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
#else
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS,
PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3);
#else
#if (SPI_INTERFACES_COUNT == 1)
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
#else
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Image img; // An image loaded into RAM
int32_t width = 0, // BMP image dimensions
height = 0;
void setup(void) {
ImageReturnCode stat; // Status from image-reading functions
Serial.begin(9600);
while(!Serial); // Wait for Serial Monitor before continuing
tft.init(240, 280); // Init ST7789 172x320
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
if(!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}
#else
// SPI or QSPI flash requires two steps, one to access the bare flash
// memory itself, then the second to access the filesystem within...
if(!flash.begin()) {
Serial.println(F("flash begin() failed"));
for(;;);
}
if(!filesys.begin(&flash)) {
Serial.println(F("filesys begin() failed"));
for(;;);
}
#endif
Serial.println(F("OK!"));
// Fill screen blue. Not a required step, this just shows that we're
// successfully communicating with the screen.
tft.fillScreen(ST77XX_BLUE);
// Load full-screen BMP file 'adabot.bmp' at position (0,0) (top left).
// Notice the 'reader' object performs this, with 'tft' as an argument.
Serial.print(F("Loading adabot.bmp to screen..."));
stat = reader.drawBMP("/adabot.bmp", tft, 0, 0);
reader.printStatus(stat); // How'd we do?
// Query the dimensions of image 'miniwoof.bmp' WITHOUT loading to screen:
Serial.print(F("Querying miniwoof.bmp image size..."));
stat = reader.bmpDimensions("/miniwoof.bmp", &width, &height);
reader.printStatus(stat); // How'd we do?
if(stat == IMAGE_SUCCESS) { // If it worked, print image size...
Serial.print(F("Image dimensions: "));
Serial.print(width);
Serial.write('x');
Serial.println(height);
}
// Load small BMP 'wales.bmp' into a GFX canvas in RAM. This should fail
// gracefully on Arduino Uno and other small devices, meaning the image
// will not load, but this won't make the program stop or crash, it just
// continues on without it. Should work on Arduino Mega, Zero, etc.
Serial.print(F("Loading wales.bmp to canvas..."));
stat = reader.loadBMP("/wales.bmp", img);
reader.printStatus(stat); // How'd we do?
delay(2000); // Pause 2 seconds before moving on to loop()
}
void loop() {
for(int r=0; r<4; r++) { // For each of 4 rotations...
tft.setRotation(r); // Set rotation
tft.fillScreen(0); // and clear screen
// Load 4 copies of the 'miniwoof.bmp' image to the screen, some
// partially off screen edges to demonstrate clipping. Globals
// 'width' and 'height' were set by bmpDimensions() call in setup().
for(int i=0; i<4; i++) {
reader.drawBMP("/miniwoof.bmp", tft,
(tft.width() * i / 3) - (width / 2),
(tft.height() * i / 3) - (height / 2));
}
delay(1000); // Pause 1 sec.
// Draw 50 Welsh dragon flags in random positions. This has no effect
// on memory-constrained boards like the Arduino Uno, where the image
// failed to load due to insufficient RAM, but it's NOT fatal.
for(int i=0; i<50; i++) {
// Rather than reader.drawBMP() (which works from SD card),
// a different function is used for RAM-resident images:
img.draw(tft, // Pass in tft object
(int16_t)random(-img.width() , tft.width()) , // Horiz pos.
(int16_t)random(-img.height(), tft.height())); // Vert pos
// Reiterating a prior point: img.draw() does nothing and returns
// if the image failed to load. It's unfortunate but not disastrous.
}
delay(2000); // Pause 2 sec.
}
}

View file

@ -9,7 +9,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -40,7 +40,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -61,7 +61,7 @@ void setup(void) {
tft.init(240, 320); // Init ST7789 320x240
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -6,7 +6,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include "Adafruit_EPD.h" // Hardware-specific library for EPD
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
@ -60,7 +60,7 @@ Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -84,7 +84,7 @@ void setup(void) {
#endif
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
// SPI or QSPI flash requires two steps, one to access the bare flash

View file

@ -6,7 +6,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include "Adafruit_EPD.h" // Hardware-specific library for EPD
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
@ -76,7 +76,7 @@ Adafruit_IL0373 display(212, 104, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -100,7 +100,7 @@ void setup(void) {
#endif
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
// SPI or QSPI flash requires two steps, one to access the bare flash

View file

@ -4,7 +4,8 @@
// Requires BMP file in root directory of QSPI Flash:
// blinka.bmp.
#include "Adafruit_ThinkInk.h" // Hardware-specific library for EPD
#include <Adafruit_GFX.h> // Core graphics library
#include "Adafruit_EPD.h" // Hardware-specific library for EPD
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
@ -14,10 +15,7 @@
#define EPD_RESET PIN_A3
#define EPD_BUSY -1
// 1.54" 152x152 Tricolor EPD with ILI0373 chipset
//ThinkInk_154_Tricolor_Z17 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// 1.54" 200x200 Tricolor EPD with SSD1681 chipset
ThinkInk_154_Tricolor_Z90 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
@ -32,7 +30,7 @@ ThinkInk_154_Tricolor_Z90 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
Adafruit_Image_EPD img; // An image loaded into RAM
@ -42,23 +40,25 @@ int32_t width = 0, // BMP image dimensions
void setup(void) {
ImageReturnCode stat; // Status from image-reading functions
Serial.begin(115200);
//while(!Serial) delay(10); // Wait for Serial Monitor before continuing
Serial.begin(9600);
//while(!Serial); // Wait for Serial Monitor before continuing
display.begin(THINKINK_TRICOLOR);
display.begin();
display.setRotation(3);
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
// SPI or QSPI flash requires two steps, one to access the bare flash
// memory itself, then the second to access the filesystem within...
if(!flash.begin()) {
errorEPD("Flash begin() failed");
Serial.println(F("flash begin() failed"));
for(;;);
}
if(!filesys.begin(&flash)) {
errorEPD("filesys begin() failed");
Serial.println(F("filesys begin() failed"));
for(;;);
}
Serial.println(F("OK!"));
@ -68,9 +68,6 @@ void setup(void) {
Serial.print(F("Loading blinka.bmp to canvas..."));
stat = reader.drawBMP((char *)"/blinka.bmp", display, 0, 0);
reader.printStatus(stat); // How'd we do?
if (stat != IMAGE_SUCCESS) {
errorEPD("Unable to draw image");
}
display.display();
// Query the dimensions of image 'blinka.bmp' WITHOUT loading to screen:
@ -107,17 +104,3 @@ void loop() {
delay(30 * 1000); // Pause 30 sec.
}
}
void errorEPD(const char *errormsg) {
display.fillScreen(0); // clear screen
display.clearBuffer();
display.setTextSize(2);
display.setCursor(10, 10);
display.setTextColor(EPD_BLACK);
display.print(errormsg);
display.display();
while (1) {
delay(10);
}
}

View file

@ -1,6 +1,6 @@
#include <Adafruit_GFX.h> // Core graphics library
#include "Adafruit_ThinkInk.h"
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions

View file

@ -6,7 +6,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_HX8357.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -19,7 +19,7 @@
#define TFT_CS 0
#define TFT_DC 15
#define SD_CS 2
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
#elif defined(ESP32)
#define TFT_CS 15
#define TFT_DC 33
#define SD_CS 14
@ -40,10 +40,6 @@
#define TFT_CS P5_3
#define STMPE_CS P3_3
#define SD_CS P3_2
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
#define TFT_CS 9
#define TFT_DC 10
#define SD_CS 7 // "pin 5" on original rp2040 feather ONLY
#else // Anything else!
#define TFT_CS 9
#define TFT_DC 10
@ -66,7 +62,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -87,14 +83,12 @@ void setup(void) {
tft.begin(); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
// M0 max SPI is 12 MHz
// ESP32 can handl 25 MHz
if(!SD.begin(SD_CS, SD_SCK_MHZ(12))) {
if(!SD.begin(SD_CS, SD_SCK_MHZ(25))) { // ESP32 requires 25 MHz limit
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}

View file

@ -6,7 +6,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ILI9341.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -19,7 +19,7 @@
#define TFT_CS 0
#define TFT_DC 15
#define SD_CS 2
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
#elif defined(ESP32)
#define TFT_CS 15
#define TFT_DC 33
#define SD_CS 14
@ -40,10 +40,6 @@
#define TFT_CS P5_3
#define STMPE_CS P3_3
#define SD_CS P3_2
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
#define TFT_CS 9
#define TFT_DC 10
#define SD_CS 7 // "pin 5" on original rp2040 feather ONLY
#else // Anything else!
#define TFT_CS 9
#define TFT_DC 10
@ -66,7 +62,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -80,19 +76,19 @@ void setup(void) {
ImageReturnCode stat; // Status from image-reading functions
Serial.begin(9600);
while(!Serial) delay(100); // Wait for Serial Monitor before continuing
#if !defined(ESP32)
while(!Serial); // Wait for Serial Monitor before continuing
#endif
tft.begin(); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
// M0 max SPI is 12 MHz
// ESP32 can handl 25 MHz
if(!SD.begin(SD_CS, SD_SCK_MHZ(12))) {
if(!SD.begin(SD_CS, SD_SCK_MHZ(25))) { // ESP32 requires 25 MHz limit
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}

View file

@ -10,7 +10,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
#include <Adafruit_miniTFTWing.h> // Part of Seesaw library
@ -41,7 +41,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -71,14 +71,12 @@ void setup(void) {
Serial.println(F("TFT initialized."));
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)
// SD card is pretty straightforward, a single call...
// M0 max SPI is 12 MHz
// ESP32 can handl 25 MHz
if(!SD.begin(SD_CS, SD_SCK_MHZ(12))) {
if(!SD.begin(SD_CS, SD_SCK_MHZ(25))) { // ESP32 requires 25 MHz limit
Serial.println(F("SD begin() failed"));
for(;;); // Fatal error, do not continue
}

View file

@ -38,7 +38,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
Adafruit_ILI9341 tft(tft8bitbus, TFT_D0, TFT_WR, TFT_DC, TFT_CS, TFT_RST, TFT_RD);
@ -60,7 +60,7 @@ void setup(void) {
tft.begin(); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -9,7 +9,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ILI9341.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
@ -39,7 +39,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -60,7 +60,7 @@ void setup(void) {
tft.begin(); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -10,7 +10,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
#include <Adafruit_seesaw.h> // IF EARLY TFT SHIELD (no Seesaw),
@ -43,7 +43,7 @@
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -73,7 +73,7 @@ void setup(void) {
tft.initR(INITR_BLACKTAB); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
#if defined(USE_SD_CARD)

View file

@ -37,7 +37,7 @@
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
Adafruit_ST7789 tft = Adafruit_ST7789(spi, TFT_CS, TFT_DC, TFT_RST);
@ -58,7 +58,7 @@ void setup(void) {
digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
// SPI or QSPI flash requires two steps, one to access the bare flash

View file

@ -6,7 +6,7 @@
#include <Adafruit_GFX.h> // Core graphics library
#include "Adafruit_ThinkInk.h"
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
#include <SdFat.h> // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
@ -26,7 +26,6 @@
//ThinkInk_213_Mono_B72 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_B73 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_213_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_290_Mono_M06 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_420_Mono_BN display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// Tri-Color Displays
@ -37,8 +36,6 @@
//ThinkInk_270_Tricolor_C44 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
ThinkInk_290_Tricolor_Z10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_420_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_290_Tricolor_Z13 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
//ThinkInk_290_Tricolor_Z94 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
// Grayscale Displays
//ThinkInk_154_Grayscale4_T8 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
@ -63,7 +60,7 @@ ThinkInk_290_Tricolor_Z10 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
FatVolume filesys;
FatFileSystem filesys;
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
#endif
@ -87,7 +84,7 @@ void setup(void) {
#endif
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or FatVolume object. This MUST
// accepts an uninitialized SdFat or FatFileSystem object. This MUST
// BE INITIALIZED before using any of the image reader functions!
Serial.print(F("Initializing filesystem..."));
// SPI or QSPI flash requires two steps, one to access the bare flash

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

View file

@ -1,5 +1,5 @@
name=Adafruit ImageReader Library
version=2.10.0
version=2.5.2
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=Companion library for Adafruit_GFX and Adafruit_EPD to load images from SD card.