Compare commits
8 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f19f9afb6e | ||
|
|
adefa6684f | ||
|
|
fa0777372d | ||
|
|
730e7c3122 | ||
|
|
07ced7149f | ||
|
|
26054f14bc | ||
|
|
a8f54fe5f7 | ||
|
|
f957559192 |
|
|
@ -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
|
|
||||||
21
.github/workflows/githubci.yml
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
name: Arduino Library CI
|
name: Arduino Library CI
|
||||||
|
|
||||||
on: [pull_request, push, repository_dispatch]
|
on: [pull_request, push]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
@ -8,18 +8,17 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
arduino-platform: ["uno", "leonardo", "mega2560", "esp8266", "esp32",
|
arduino-platform: ["uno", "leonardo", "mega2560", "esp8266", "esp32",
|
||||||
"zero", "metro_m4", "nrf52840", "pybadge",
|
"zero", "m4", "nrf52840", "pybadge", "hallowing_m4",
|
||||||
"hallowing_m4", "cpb", "cpx_ada", "pyportal",
|
"cpb", "cpx_ada", "pyportal"]
|
||||||
"feather_rp2040"]
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: '3.8'
|
python-version: '3.x'
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
repository: adafruit/ci-arduino
|
repository: adafruit/ci-arduino
|
||||||
path: ci
|
path: ci
|
||||||
|
|
@ -34,12 +33,12 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
repository: adafruit/ci-arduino
|
repository: adafruit/ci-arduino
|
||||||
path: ci
|
path: ci
|
||||||
|
|
|
||||||
|
|
@ -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
|
often be in pre-setup() declaration, but DOES need initializing
|
||||||
before any of the image loading or size functions are called!
|
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.
|
@brief Destructor.
|
||||||
|
|
@ -246,7 +246,7 @@ Adafruit_ImageReader::~Adafruit_ImageReader(void) {
|
||||||
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
|
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
|
||||||
completion, other values on failure).
|
completion, other values on failure).
|
||||||
*/
|
*/
|
||||||
ImageReturnCode Adafruit_ImageReader::drawBMP(const char *filename,
|
ImageReturnCode Adafruit_ImageReader::drawBMP(char *filename,
|
||||||
Adafruit_SPITFT &tft, int16_t x,
|
Adafruit_SPITFT &tft, int16_t x,
|
||||||
int16_t y, boolean transact) {
|
int16_t y, boolean transact) {
|
||||||
uint16_t tftbuf[BUFPIXELS]; // Temp space for buffering TFT data
|
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
|
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
|
||||||
completion, other values on failure).
|
completion, other values on failure).
|
||||||
*/
|
*/
|
||||||
ImageReturnCode Adafruit_ImageReader::loadBMP(const char *filename,
|
ImageReturnCode Adafruit_ImageReader::loadBMP(char *filename,
|
||||||
Adafruit_Image &img) {
|
Adafruit_Image &img) {
|
||||||
// Call core BMP-reading function. TFT and working buffer are NULL
|
// Call core BMP-reading function. TFT and working buffer are NULL
|
||||||
// (unused and allocated in function, respectively), X & Y position are
|
// (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).
|
completion, other values on failure).
|
||||||
*/
|
*/
|
||||||
ImageReturnCode Adafruit_ImageReader::coreBMP(
|
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
|
Adafruit_SPITFT *tft, // Pointer to TFT object, or NULL if to image
|
||||||
uint16_t *dest, // TFT working buffer, or NULL if to canvas
|
uint16_t *dest, // TFT working buffer, or NULL if to canvas
|
||||||
int16_t x, // Position if loading to TFT (else ignored)
|
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...
|
for (row = 0; row < loadHeight; row++) { // For each scanline...
|
||||||
#ifdef ESP8266
|
|
||||||
delay(1); // Keep ESP8266 happy
|
yield(); // Keep ESP8266 happy
|
||||||
#endif
|
|
||||||
// Seek to start of scan line. It might seem labor-intensive
|
// Seek to start of scan line. It might seem labor-intensive
|
||||||
// to be doing this on every line, but this method covers a
|
// to be doing this on every line, but this method covers a
|
||||||
// lot of gritty details like cropping, flip and scanline
|
// lot of gritty details like cropping, flip and scanline
|
||||||
|
|
@ -529,8 +529,8 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
||||||
}
|
}
|
||||||
} else { // Canvas is simpler,
|
} else { // Canvas is simpler,
|
||||||
file.read(sdbuf, sizeof sdbuf); // just load sdbuf
|
file.read(sdbuf, sizeof sdbuf); // just load sdbuf
|
||||||
} // (destidx never resets)
|
} // (destidx never resets)
|
||||||
srcidx = 0; // Reset bmp buf index
|
srcidx = 0; // Reset bmp buf index
|
||||||
}
|
}
|
||||||
if (depth == 24) {
|
if (depth == 24) {
|
||||||
// Convert each pixel from BMP to 565 format, save in dest
|
// 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 (tft) { // Drawing to TFT?
|
||||||
if (destidx) { // Any remainders?
|
if (destidx) { // Any remainders?
|
||||||
// See notes above re: DMA
|
// See notes above re: DMA
|
||||||
|
|
@ -584,11 +584,11 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
||||||
img->palette = quantized; // Keep palette with img
|
img->palette = quantized; // Keep palette with img
|
||||||
}
|
}
|
||||||
} // end depth>24 or quantized malloc OK
|
} // end depth>24 or quantized malloc OK
|
||||||
} // end top/left clip
|
} // end top/left clip
|
||||||
} // end malloc check
|
} // end malloc check
|
||||||
} // end depth check
|
} // end depth check
|
||||||
} // end planes/compression check
|
} // end planes/compression check
|
||||||
} // end signature
|
} // end signature
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -605,7 +605,7 @@ ImageReturnCode Adafruit_ImageReader::coreBMP(
|
||||||
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
|
@return One of the ImageReturnCode values (IMAGE_SUCCESS on successful
|
||||||
completion, other values on failure).
|
completion, other values on failure).
|
||||||
*/
|
*/
|
||||||
ImageReturnCode Adafruit_ImageReader::bmpDimensions(const char *filename,
|
ImageReturnCode Adafruit_ImageReader::bmpDimensions(char *filename,
|
||||||
int32_t *width,
|
int32_t *width,
|
||||||
int32_t *height) {
|
int32_t *height) {
|
||||||
|
|
||||||
|
|
@ -628,9 +628,9 @@ ImageReturnCode Adafruit_ImageReader::bmpDimensions(const char *filename,
|
||||||
}
|
}
|
||||||
status = IMAGE_SUCCESS; // YAY.
|
status = IMAGE_SUCCESS; // YAY.
|
||||||
}
|
}
|
||||||
file.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -643,7 +643,7 @@ ImageReturnCode Adafruit_ImageReader::bmpDimensions(const char *filename,
|
||||||
@return Unsigned 16-bit value, native endianism.
|
@return Unsigned 16-bit value, native endianism.
|
||||||
*/
|
*/
|
||||||
uint16_t Adafruit_ImageReader::readLE16(void) {
|
uint16_t Adafruit_ImageReader::readLE16(void) {
|
||||||
#if !defined(ESP32) && !defined(ESP8266) && \
|
#if !defined(ESP32) && !defined(ESP8266) && \
|
||||||
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||||
// Read directly into result -- BMP data and variable both little-endian.
|
// Read directly into result -- BMP data and variable both little-endian.
|
||||||
uint16_t result;
|
uint16_t result;
|
||||||
|
|
@ -662,7 +662,7 @@ uint16_t Adafruit_ImageReader::readLE16(void) {
|
||||||
@return Unsigned 32-bit value, native endianism.
|
@return Unsigned 32-bit value, native endianism.
|
||||||
*/
|
*/
|
||||||
uint32_t Adafruit_ImageReader::readLE32(void) {
|
uint32_t Adafruit_ImageReader::readLE32(void) {
|
||||||
#if !defined(ESP32) && !defined(ESP8266) && \
|
#if !defined(ESP32) && !defined(ESP8266) && \
|
||||||
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||||
// Read directly into result -- BMP data and variable both little-endian.
|
// Read directly into result -- BMP data and variable both little-endian.
|
||||||
uint32_t result;
|
uint32_t result;
|
||||||
|
|
|
||||||
|
|
@ -94,20 +94,20 @@ protected:
|
||||||
*/
|
*/
|
||||||
class Adafruit_ImageReader {
|
class Adafruit_ImageReader {
|
||||||
public:
|
public:
|
||||||
Adafruit_ImageReader(FatVolume &fs);
|
Adafruit_ImageReader(FatFileSystem &fs);
|
||||||
~Adafruit_ImageReader(void);
|
~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);
|
int16_t y, boolean transact = true);
|
||||||
ImageReturnCode loadBMP(const char *filename, Adafruit_Image &img);
|
ImageReturnCode loadBMP(char *filename, Adafruit_Image &img);
|
||||||
ImageReturnCode bmpDimensions(const char *filename, int32_t *w, int32_t *h);
|
ImageReturnCode bmpDimensions(char *filename, int32_t *w, int32_t *h);
|
||||||
void printStatus(ImageReturnCode stat, Stream &stream = Serial);
|
void printStatus(ImageReturnCode stat, Stream &stream = Serial);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
FatVolume *filesys; ///< FAT FileSystem Object
|
FatFileSystem *filesys;
|
||||||
File32 file; ///< Current Open file
|
File file;
|
||||||
ImageReturnCode coreBMP(const char *filename, Adafruit_SPITFT *tft,
|
ImageReturnCode coreBMP(char *filename, Adafruit_SPITFT *tft, uint16_t *dest,
|
||||||
uint16_t *dest, int16_t x, int16_t y,
|
int16_t x, int16_t y, Adafruit_Image *img,
|
||||||
Adafruit_Image *img, boolean transact);
|
boolean transact);
|
||||||
uint16_t readLE16(void);
|
uint16_t readLE16(void);
|
||||||
uint32_t readLE32(void);
|
uint32_t readLE32(void);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,91 +1,5 @@
|
||||||
#include "Adafruit_ImageReader_EPD.h"
|
#include "Adafruit_ImageReader_EPD.h"
|
||||||
|
|
||||||
#ifdef __AVR__
|
|
||||||
#define BUFPIXELS 24 ///< 24 * 5 = 120 bytes
|
|
||||||
#else
|
|
||||||
#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.
|
@brief Draw image to an Adafruit ePaper-type display.
|
||||||
@param epd
|
@param epd
|
||||||
|
|
@ -113,26 +27,30 @@ void Adafruit_Image_EPD::draw(Adafruit_EPD &epd, int16_t x, int16_t y) {
|
||||||
epd.writePixel(col, row, c);
|
epd.writePixel(col, row, c);
|
||||||
|
|
||||||
col++;
|
col++;
|
||||||
}
|
if (col == x + canvas.canvas1->width()) {
|
||||||
if (col >= x + canvas.canvas1->width()) {
|
col = x;
|
||||||
col = x;
|
row++;
|
||||||
row++;
|
}
|
||||||
}
|
}
|
||||||
buffer++;
|
buffer++;
|
||||||
};
|
};
|
||||||
} else if (format == IMAGE_8) {
|
} else if (format == IMAGE_8) {
|
||||||
} else if (format == IMAGE_16) {
|
} else if (format == IMAGE_16) {
|
||||||
uint16_t *buffer = canvas.canvas16->getBuffer();
|
uint16_t *buffer = canvas.canvas16->getBuffer();
|
||||||
thinkinkmode_t displayMode = epd.getMode();
|
|
||||||
|
|
||||||
while (row < y + canvas.canvas16->height()) {
|
while (row < y + canvas.canvas16->height()) {
|
||||||
// RGB in 565 format
|
// RGB in 565 format
|
||||||
uint8_t r = (*buffer & 0xf800) >> 8;
|
uint8_t r = (*buffer & 0xf800) >> 8;
|
||||||
uint8_t g = (*buffer & 0x07e0) >> 3;
|
uint8_t g = (*buffer & 0x07e0) >> 3;
|
||||||
uint8_t b = (*buffer & 0x001f) << 3;
|
uint8_t b = (*buffer & 0x001f) << 3;
|
||||||
|
|
||||||
uint8_t c =
|
uint8_t c = 0;
|
||||||
Adafruit_ImageReader_EPD::mapColorForDisplay(r, g, b, displayMode);
|
if ((r < 0x80) && (g < 0x80) && (b < 0x80)) {
|
||||||
|
c = EPD_BLACK; // try to infer black
|
||||||
|
} 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);
|
epd.writePixel(col, row, c);
|
||||||
col++;
|
col++;
|
||||||
|
|
@ -144,384 +62,3 @@ void Adafruit_Image_EPD::draw(Adafruit_EPD &epd, int16_t x, int16_t y) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ADAFRUIT_IMAGEREADER_EPD 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_EPD::Adafruit_ImageReader_EPD(FatVolume &fs)
|
|
||||||
: Adafruit_ImageReader(fs) {}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief Loads BMP image file from SD card directly to Adafruit_EPD screen.
|
|
||||||
@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 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_EPD::drawBMP(char *filename,
|
|
||||||
Adafruit_EPD &epd, int16_t x,
|
|
||||||
int16_t y, 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, 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, else NULL.
|
|
||||||
@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_EPD object, if loading to RAM (or NULL
|
|
||||||
if loading to screen).
|
|
||||||
@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_EPD::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_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
|
|
||||||
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 = 0, epd_row = 0;
|
|
||||||
#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;
|
|
||||||
|
|
||||||
if ((depth == 24) || (depth == 1)) { // BGR or 1-bit bitmap format
|
|
||||||
|
|
||||||
if (img) {
|
|
||||||
// Loading to RAM -- allocate GFX 16-bit canvas type
|
|
||||||
status = IMAGE_ERR_MALLOC; // Assume won't fit to start
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Future: handle other depths.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest || dest1) { // Supported format, alloc OK, etc.
|
|
||||||
status = IMAGE_SUCCESS;
|
|
||||||
|
|
||||||
if ((loadWidth > 0) && (loadHeight > 0)) { // Clip top/left
|
|
||||||
if (epd) {
|
|
||||||
epd->startWrite(); // Start SPI (regardless of transact)
|
|
||||||
epd_col = x;
|
|
||||||
epd_row = y;
|
|
||||||
} else {
|
|
||||||
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 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);
|
|
||||||
quantized[c] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (row = 0; row < loadHeight; row++) { // For 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) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
for (col = 0; col < loadWidth; col++) { // For each pixel...
|
|
||||||
if (srcidx >= sizeof sdbuf) { // Time to load more?
|
|
||||||
if (epd) { // Drawing to TFT?
|
|
||||||
if (transact) {
|
|
||||||
epd->endWrite(); // End EPD SPI transact
|
|
||||||
}
|
|
||||||
#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 (transact)
|
|
||||||
epd->startWrite(); // Start EPD SPI transact
|
|
||||||
if (destidx) { // If buffered EPD data
|
|
||||||
// Non-blocking writes (DMA) have been temporarily
|
|
||||||
// disabled until this can be rewritten with two
|
|
||||||
// alternating 'dest' buffers (else the nonblocking
|
|
||||||
// data out is overwritten in the dest[] write below).
|
|
||||||
uint16_t index = 0;
|
|
||||||
while (index < destidx && epd_row < y + loadHeight) {
|
|
||||||
epd->writePixel(epd_col, epd_row, dest[index]);
|
|
||||||
epd_col++;
|
|
||||||
if (epd_col == x + loadWidth) {
|
|
||||||
epd_col = x;
|
|
||||||
epd_row++;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
};
|
|
||||||
destidx = 0; // and reset dest index
|
|
||||||
}
|
|
||||||
} else { // Canvas is simpler,
|
|
||||||
file.read(sdbuf, sizeof sdbuf); // just load sdbuf
|
|
||||||
} // (destidx never resets)
|
|
||||||
srcidx = 0; // Reset bmp buf index
|
|
||||||
}
|
|
||||||
if (depth == 24) {
|
|
||||||
// Convert each pixel from BMP to 565 format, save in dest
|
|
||||||
b = sdbuf[srcidx++];
|
|
||||||
g = sdbuf[srcidx++];
|
|
||||||
r = sdbuf[srcidx++];
|
|
||||||
|
|
||||||
color = mapColorForDisplay(r, g, b, displayMode);
|
|
||||||
dest[destidx++] = color;
|
|
||||||
} else {
|
|
||||||
// Extract 1-bit color index
|
|
||||||
uint8_t n = (sdbuf[srcidx] >> bitIn) & 1;
|
|
||||||
if (!bitIn) {
|
|
||||||
srcidx++;
|
|
||||||
bitIn = 7;
|
|
||||||
} else {
|
|
||||||
bitIn--;
|
|
||||||
}
|
|
||||||
if (epd) {
|
|
||||||
// Look up in palette, store in epd dest buf
|
|
||||||
dest[destidx++] = quantized[n];
|
|
||||||
} else {
|
|
||||||
// Store bit in canvas1 buffer (ignore palette)
|
|
||||||
if (n)
|
|
||||||
dest1[destidx] |= bitOut;
|
|
||||||
else
|
|
||||||
dest1[destidx] &= ~bitOut;
|
|
||||||
bitOut >>= 1;
|
|
||||||
if (!bitOut) {
|
|
||||||
bitOut = 0x80;
|
|
||||||
destidx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // end pixel loop
|
|
||||||
if (epd) { // Drawing to TFT?
|
|
||||||
if (destidx) { // Any remainders?
|
|
||||||
uint16_t index = 0;
|
|
||||||
while (index < destidx && epd_row < y + loadHeight) {
|
|
||||||
epd->writePixel(epd_col, epd_row, dest[index]);
|
|
||||||
epd_col++;
|
|
||||||
if (epd_col == x + loadWidth) {
|
|
||||||
epd_col = x;
|
|
||||||
epd_row++;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
};
|
|
||||||
destidx = 0; // and reset dest index
|
|
||||||
}
|
|
||||||
epd->endWrite(); // End TFT (regardless of transact)
|
|
||||||
}
|
|
||||||
} // end scanline loop
|
|
||||||
|
|
||||||
if (quantized) {
|
|
||||||
if (epd)
|
|
||||||
free(quantized); // Palette 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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -27,34 +27,7 @@ public:
|
||||||
void draw(Adafruit_EPD &epd, int16_t x, int16_t y);
|
void draw(Adafruit_EPD &epd, int16_t x, int16_t y);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Adafruit_ImageReader_EPD; ///< Loading occurs here
|
friend class Adafruit_ImageReader; ///< Loading occurs here
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief An optional adjunct to Adafruit_EPD that reads 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_EPD : public Adafruit_ImageReader {
|
|
||||||
public:
|
|
||||||
Adafruit_ImageReader_EPD(FatVolume &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,
|
|
||||||
boolean transact);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ADAFRUIT_IMAGE_READER_EPD_H__
|
#endif // __ADAFRUIT_IMAGE_READER_EPD_H__
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Adafruit ImageReader Arduino Library [](https://github.com/adafruit/Adafruit_ImageReader/actions)[](http://adafruit.github.io/Adafruit_ImageReader/html/index.html)
|
# Adafruit_ImageReader 
|
||||||
|
|
||||||
Companion library for Adafruit_GFX to load images from SD card or SPI Flash
|
Companion library for Adafruit_GFX to load images from SD card or SPI Flash
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_SSD1331.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ void setup(void) {
|
||||||
tft.begin(); // Initialize screen
|
tft.begin(); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_SSD1351.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ void setup(void) {
|
||||||
tft.begin(); // Initialize screen
|
tft.begin(); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_ST7735.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ void setup(void) {
|
||||||
tft.initR(INITR_144GREENTAB); // Initialize screen
|
tft.initR(INITR_144GREENTAB); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_ST7735.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ void setup(void) {
|
||||||
tft.initR(INITR_BLACKTAB); // Initialize screen
|
tft.initR(INITR_BLACKTAB); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_ST7735.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ void setup(void) {
|
||||||
Serial.println(F("TFT initialized."));
|
Serial.println(F("TFT initialized."));
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
|
#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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ void setup(void) {
|
||||||
tft.init(240, 320); // Init ST7789 320x240
|
tft.init(240, 320); // Init ST7789 320x240
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include "Adafruit_EPD.h" // Hardware-specific library for EPD
|
#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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
|
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -44,8 +44,8 @@ Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
||||||
//Adafruit_IL0398 display(300, 400, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
//Adafruit_IL0398 display(300, 400, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
||||||
|
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
SdFat SD; // SD card filesystem
|
SdFat SD; // SD card filesystem
|
||||||
Adafruit_ImageReader_EPD reader(SD); // Image-reader object, pass in SD filesys
|
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
|
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
|
||||||
|
|
@ -59,9 +59,9 @@ Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
||||||
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
|
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Adafruit_Image_EPD img; // An image loaded into RAM
|
Adafruit_Image_EPD img; // An image loaded into RAM
|
||||||
|
|
@ -84,7 +84,7 @@ void setup(void) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
// SPI or QSPI flash requires two steps, one to access the bare flash
|
// SPI or QSPI flash requires two steps, one to access the bare flash
|
||||||
|
|
@ -109,44 +109,27 @@ void setup(void) {
|
||||||
#endif
|
#endif
|
||||||
Serial.println(F("OK!"));
|
Serial.println(F("OK!"));
|
||||||
|
|
||||||
// Load full-screen BMP file 'blinka.bmp' at position (0,0) (top left).
|
// Load full-screen BMP file 'tricolor-blinka.bmp' at position (0,0) (top left).
|
||||||
// Notice the 'reader' object performs this, with 'epd' as an argument.
|
// Notice the 'reader' object performs this, with 'epd' as an argument.
|
||||||
Serial.print(F("Loading blinka.bmp to canvas..."));
|
Serial.print(F("Loading tricolor-blinka.bmp to canvas..."));
|
||||||
stat = reader.drawBMP((char *)"/blinka.bmp", display, 0, 0);
|
stat = reader.loadBMP((char *)"/tricolor-blinka.bmp", img);
|
||||||
reader.printStatus(stat); // How'd we do?
|
reader.printStatus(stat); // How'd we do?
|
||||||
display.display();
|
|
||||||
|
|
||||||
// Query the dimensions of image 'blinka.bmp' WITHOUT loading to screen:
|
|
||||||
Serial.print(F("Querying blinka.bmp image size..."));
|
|
||||||
stat = reader.bmpDimensions("blinka.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(30 * 1000); // Pause 30 seconds before continuing because it's eInk
|
|
||||||
|
|
||||||
Serial.print(F("Drawing canvas to EPD..."));
|
Serial.print(F("Drawing canvas to EPD..."));
|
||||||
display.clearBuffer();
|
display.clearBuffer();
|
||||||
|
img.draw(display, 0, 0);
|
||||||
|
display.display();
|
||||||
|
|
||||||
// Load small BMP 'blinka.bmp' into a GFX canvas in RAM. This should fail
|
delay(15 * 1000); // Pause 15 seconds before moving on to loop()
|
||||||
// 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 larger ram boards like M4, etc.
|
|
||||||
stat = reader.loadBMP("/blinka.bmp", img);
|
|
||||||
reader.printStatus(stat); // How'd we do?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
for(int r=0; r<4; r++) { // For each of 4 rotations...
|
for(int r=0; r<4; r++) { // For each of 4 rotations...
|
||||||
display.setRotation(r); // Set rotation
|
display.setRotation(r); // Set rotation
|
||||||
display.fillScreen(0); // and clear screen
|
display.fillScreen(0); // and clear screen
|
||||||
display.clearBuffer();
|
display.clearBuffer();
|
||||||
img.draw(display, 0, 0);
|
img.draw(display, 0, 0);
|
||||||
display.display();
|
display.display();
|
||||||
delay(30 * 1000); // Pause 30 sec.
|
delay(15 * 1000); // Pause 15 sec.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include "Adafruit_EPD.h" // Hardware-specific library for EPD
|
#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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
|
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -60,8 +60,8 @@ Adafruit_IL0373 display(212, 104, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
||||||
//#define FLEXIBLE_290
|
//#define FLEXIBLE_290
|
||||||
|
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
SdFat SD; // SD card filesystem
|
SdFat SD; // SD card filesystem
|
||||||
Adafruit_ImageReader_EPD reader(SD); // Image-reader object, pass in SD filesys
|
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
|
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
|
||||||
|
|
@ -75,9 +75,9 @@ Adafruit_IL0373 display(212, 104, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
||||||
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
|
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Adafruit_Image_EPD img; // An image loaded into RAM
|
Adafruit_Image_EPD img; // An image loaded into RAM
|
||||||
|
|
@ -100,7 +100,7 @@ void setup(void) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
// SPI or QSPI flash requires two steps, one to access the bare flash
|
// SPI or QSPI flash requires two steps, one to access the bare flash
|
||||||
|
|
@ -125,35 +125,18 @@ void setup(void) {
|
||||||
#endif
|
#endif
|
||||||
Serial.println(F("OK!"));
|
Serial.println(F("OK!"));
|
||||||
|
|
||||||
// Load full-screen BMP file 'blinka.bmp' at position (0,0) (top left).
|
// Load full-screen BMP file 'tricolor-blinka.bmp' at position (0,0) (top left).
|
||||||
// Notice the 'reader' object performs this, with 'epd' as an argument.
|
// Notice the 'reader' object performs this, with 'epd' as an argument.
|
||||||
Serial.print(F("Loading blinka.bmp to canvas..."));
|
Serial.print(F("Loading tricolor-blinka.bmp to canvas..."));
|
||||||
stat = reader.drawBMP((char *)"/blinka.bmp", display, 0, 0);
|
stat = reader.loadBMP((char *)"/tricolor-blinka.bmp", img);
|
||||||
reader.printStatus(stat); // How'd we do?
|
reader.printStatus(stat); // How'd we do?
|
||||||
display.display();
|
|
||||||
|
|
||||||
// Query the dimensions of image 'blinka.bmp' WITHOUT loading to screen:
|
|
||||||
Serial.print(F("Querying blinka.bmp image size..."));
|
|
||||||
stat = reader.bmpDimensions("blinka.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(30 * 1000); // Pause 30 seconds before continuing because it's eInk
|
|
||||||
|
|
||||||
Serial.print(F("Drawing canvas to EPD..."));
|
Serial.print(F("Drawing canvas to EPD..."));
|
||||||
display.clearBuffer();
|
display.clearBuffer();
|
||||||
|
img.draw(display, 0, 0);
|
||||||
|
display.display();
|
||||||
|
|
||||||
// Load small BMP 'blinka.bmp' into a GFX canvas in RAM. This should fail
|
delay(15 * 1000); // Pause 15 seconds before moving on to loop()
|
||||||
// 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 larger ram boards like M4, etc.
|
|
||||||
stat = reader.loadBMP("/blinka.bmp", img);
|
|
||||||
reader.printStatus(stat); // How'd we do?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
@ -163,6 +146,6 @@ void loop() {
|
||||||
display.clearBuffer();
|
display.clearBuffer();
|
||||||
img.draw(display, 0, 0);
|
img.draw(display, 0, 0);
|
||||||
display.display();
|
display.display();
|
||||||
delay(30 * 1000); // Pause 30 sec.
|
delay(15 * 1000); // Pause 15 sec.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
// Requires BMP file in root directory of QSPI Flash:
|
// Requires BMP file in root directory of QSPI Flash:
|
||||||
// blinka.bmp.
|
// 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
|
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -14,10 +15,7 @@
|
||||||
#define EPD_RESET PIN_A3
|
#define EPD_RESET PIN_A3
|
||||||
#define EPD_BUSY -1
|
#define EPD_BUSY -1
|
||||||
|
|
||||||
// 1.54" 152x152 Tricolor EPD with ILI0373 chipset
|
Adafruit_IL0373 display(152, 152, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
||||||
//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);
|
|
||||||
|
|
||||||
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
|
// SPI or QSPI flash filesystem (i.e. CIRCUITPY drive)
|
||||||
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
|
#if defined(__SAMD51__) || defined(NRF52840_XXAA)
|
||||||
|
|
@ -31,70 +29,53 @@ ThinkInk_154_Tricolor_Z90 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
|
|
||||||
Adafruit_Image_EPD img; // An image loaded into RAM
|
Adafruit_Image_EPD img; // An image loaded into RAM
|
||||||
int32_t width = 0, // BMP image dimensions
|
int32_t width = 0, // BMP image dimensions
|
||||||
height = 0;
|
height = 0;
|
||||||
|
|
||||||
void setup(void) {
|
void setup(void) {
|
||||||
|
|
||||||
ImageReturnCode stat; // Status from image-reading functions
|
ImageReturnCode stat; // Status from image-reading functions
|
||||||
|
|
||||||
Serial.begin(115200);
|
Serial.begin(9600);
|
||||||
//while(!Serial) delay(10); // Wait for Serial Monitor before continuing
|
//while(!Serial); // Wait for Serial Monitor before continuing
|
||||||
|
|
||||||
display.begin(THINKINK_TRICOLOR);
|
display.begin();
|
||||||
display.setRotation(3);
|
display.setRotation(3);
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
// SPI or QSPI flash requires two steps, one to access the bare flash
|
// SPI or QSPI flash requires two steps, one to access the bare flash
|
||||||
// memory itself, then the second to access the filesystem within...
|
// memory itself, then the second to access the filesystem within...
|
||||||
if(!flash.begin()) {
|
if(!flash.begin()) {
|
||||||
errorEPD("Flash begin() failed");
|
Serial.println(F("flash begin() failed"));
|
||||||
|
for(;;);
|
||||||
}
|
}
|
||||||
if(!filesys.begin(&flash)) {
|
if(!filesys.begin(&flash)) {
|
||||||
errorEPD("filesys begin() failed");
|
Serial.println(F("filesys begin() failed"));
|
||||||
|
for(;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.println(F("OK!"));
|
Serial.println(F("OK!"));
|
||||||
|
|
||||||
// Load full-screen BMP file 'blinka.bmp' at position (0,0) (top left).
|
// Load full-screen BMP file 'tricolor-blinka.bmp' at position (0,0) (top left).
|
||||||
// Notice the 'reader' object performs this, with 'epd' as an argument.
|
// Notice the 'reader' object performs this, with 'epd' as an argument.
|
||||||
Serial.print(F("Loading blinka.bmp to canvas..."));
|
Serial.print(F("Loading tricolor-blinka.bmp to canvas..."));
|
||||||
stat = reader.drawBMP((char *)"/blinka.bmp", display, 0, 0);
|
stat = reader.loadBMP((char *)"/tricolor-blinka.bmp", img);
|
||||||
reader.printStatus(stat); // How'd we do?
|
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:
|
|
||||||
Serial.print(F("Querying blinka.bmp image size..."));
|
|
||||||
stat = reader.bmpDimensions("blinka.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(30 * 1000); // Pause 30 seconds before continuing because it's eInk
|
|
||||||
|
|
||||||
Serial.print(F("Drawing canvas to EPD..."));
|
Serial.print(F("Drawing canvas to EPD..."));
|
||||||
display.clearBuffer();
|
display.clearBuffer();
|
||||||
|
img.draw(display, 0, 0);
|
||||||
|
display.display();
|
||||||
|
|
||||||
// Load small BMP 'blinka.bmp' into a GFX canvas in RAM. This should fail
|
delay(15 * 1000); // Pause 15 seconds before moving on to loop()
|
||||||
// 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 larger ram boards like M4, etc.
|
|
||||||
stat = reader.loadBMP("/blinka.bmp", img);
|
|
||||||
reader.printStatus(stat); // How'd we do?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
@ -104,20 +85,6 @@ void loop() {
|
||||||
display.clearBuffer();
|
display.clearBuffer();
|
||||||
img.draw(display, 0, 0);
|
img.draw(display, 0, 0);
|
||||||
display.display();
|
display.display();
|
||||||
delay(30 * 1000); // Pause 30 sec.
|
delay(15 * 1000); // Pause 15 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
|
||||||
#include "Adafruit_ThinkInk.h"
|
|
||||||
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
|
|
||||||
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
|
|
||||||
|
|
||||||
|
|
||||||
#define SD_CS 5
|
|
||||||
#define SRAM_CS -1
|
|
||||||
#define EPD_CS 9
|
|
||||||
#define EPD_DC 10
|
|
||||||
#define EPD_RESET -1 // can set to -1 and share with microcontroller Reset!
|
|
||||||
#define EPD_BUSY -1 // can set to -1 to not use a pin (will wait a fixed delay)
|
|
||||||
|
|
||||||
ThinkInk_290_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
|
|
||||||
SdFat SD; // SD card filesystem
|
|
||||||
Adafruit_ImageReader_EPD reader(SD); // Image-reader object, pass in SD filesys
|
|
||||||
|
|
||||||
|
|
||||||
#define FILENAME1 "/adabot_head.bmp"
|
|
||||||
#define FILENAME2 "/panda_head.bmp"
|
|
||||||
#define FILENAME3 "/29gray4.bmp"
|
|
||||||
|
|
||||||
#define BUTTON1 11
|
|
||||||
#define BUTTON2 12
|
|
||||||
#define BUTTON3 13
|
|
||||||
|
|
||||||
|
|
||||||
void setup(void) {
|
|
||||||
Serial.begin(9600);
|
|
||||||
//while(!Serial); // Wait for Serial Monitor before continuing
|
|
||||||
|
|
||||||
display.begin();
|
|
||||||
display.clearBuffer();
|
|
||||||
/*
|
|
||||||
Serial.print("Initializing filesystem...");
|
|
||||||
display.setTextSize(3);
|
|
||||||
display.setCursor(10,10);
|
|
||||||
display.setTextColor(EPD_BLACK);
|
|
||||||
display.print("SD Card...");
|
|
||||||
*/
|
|
||||||
display.display();
|
|
||||||
|
|
||||||
// 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"));
|
|
||||||
display.println("failed!");
|
|
||||||
display.display();
|
|
||||||
for(;;); // Fatal error, do not continue
|
|
||||||
}
|
|
||||||
Serial.println("OK!");
|
|
||||||
/*
|
|
||||||
display.println("OK!");
|
|
||||||
display.display();
|
|
||||||
|
|
||||||
display.setCursor(10,100);
|
|
||||||
display.setTextSize(1);
|
|
||||||
display.println("Press buttons to display images!");
|
|
||||||
display.display();
|
|
||||||
*/
|
|
||||||
pinMode(BUTTON1, INPUT_PULLUP);
|
|
||||||
pinMode(BUTTON2, INPUT_PULLUP);
|
|
||||||
pinMode(BUTTON3, INPUT_PULLUP);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
char selected_file[80] = {0};
|
|
||||||
ImageReturnCode stat; // Status from image-reading functions
|
|
||||||
|
|
||||||
|
|
||||||
if (!digitalRead(BUTTON1)) {
|
|
||||||
strcpy(selected_file, FILENAME1);
|
|
||||||
Serial.println("Button 1 pressed");
|
|
||||||
}
|
|
||||||
if (!digitalRead(BUTTON2)) {
|
|
||||||
strcpy(selected_file, FILENAME2);
|
|
||||||
Serial.println("Button 2 pressed");
|
|
||||||
}
|
|
||||||
if (!digitalRead(BUTTON3)) {
|
|
||||||
strcpy(selected_file, FILENAME3);
|
|
||||||
Serial.println("Button 3 pressed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (selected_file[0] != 0) {
|
|
||||||
display.clearBuffer();
|
|
||||||
display.display();
|
|
||||||
delay(500);
|
|
||||||
Serial.print("Loading ");
|
|
||||||
Serial.print(selected_file);
|
|
||||||
Serial.println(" to canvas...");
|
|
||||||
display.clearBuffer();
|
|
||||||
stat = reader.drawBMP(selected_file, display, 0, 0);
|
|
||||||
reader.printStatus(stat); // How'd we do?
|
|
||||||
display.display();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_HX8357.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#define TFT_CS 0
|
#define TFT_CS 0
|
||||||
#define TFT_DC 15
|
#define TFT_DC 15
|
||||||
#define SD_CS 2
|
#define SD_CS 2
|
||||||
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
|
#elif defined(ESP32)
|
||||||
#define TFT_CS 15
|
#define TFT_CS 15
|
||||||
#define TFT_DC 33
|
#define TFT_DC 33
|
||||||
#define SD_CS 14
|
#define SD_CS 14
|
||||||
|
|
@ -40,10 +40,6 @@
|
||||||
#define TFT_CS P5_3
|
#define TFT_CS P5_3
|
||||||
#define STMPE_CS P3_3
|
#define STMPE_CS P3_3
|
||||||
#define SD_CS P3_2
|
#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!
|
#else // Anything else!
|
||||||
#define TFT_CS 9
|
#define TFT_CS 9
|
||||||
#define TFT_DC 10
|
#define TFT_DC 10
|
||||||
|
|
@ -66,7 +62,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -87,14 +83,12 @@ void setup(void) {
|
||||||
tft.begin(); // Initialize screen
|
tft.begin(); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
// SD card is pretty straightforward, a single call...
|
// SD card is pretty straightforward, a single call...
|
||||||
// M0 max SPI is 12 MHz
|
if(!SD.begin(SD_CS, SD_SCK_MHZ(25))) { // ESP32 requires 25 MHz limit
|
||||||
// ESP32 can handl 25 MHz
|
|
||||||
if(!SD.begin(SD_CS, SD_SCK_MHZ(12))) {
|
|
||||||
Serial.println(F("SD begin() failed"));
|
Serial.println(F("SD begin() failed"));
|
||||||
for(;;); // Fatal error, do not continue
|
for(;;); // Fatal error, do not continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_ILI9341.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#define TFT_CS 0
|
#define TFT_CS 0
|
||||||
#define TFT_DC 15
|
#define TFT_DC 15
|
||||||
#define SD_CS 2
|
#define SD_CS 2
|
||||||
#elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
|
#elif defined(ESP32)
|
||||||
#define TFT_CS 15
|
#define TFT_CS 15
|
||||||
#define TFT_DC 33
|
#define TFT_DC 33
|
||||||
#define SD_CS 14
|
#define SD_CS 14
|
||||||
|
|
@ -40,10 +40,6 @@
|
||||||
#define TFT_CS P5_3
|
#define TFT_CS P5_3
|
||||||
#define STMPE_CS P3_3
|
#define STMPE_CS P3_3
|
||||||
#define SD_CS P3_2
|
#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!
|
#else // Anything else!
|
||||||
#define TFT_CS 9
|
#define TFT_CS 9
|
||||||
#define TFT_DC 10
|
#define TFT_DC 10
|
||||||
|
|
@ -66,7 +62,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -80,19 +76,19 @@ void setup(void) {
|
||||||
ImageReturnCode stat; // Status from image-reading functions
|
ImageReturnCode stat; // Status from image-reading functions
|
||||||
|
|
||||||
Serial.begin(9600);
|
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
|
tft.begin(); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
// SD card is pretty straightforward, a single call...
|
// SD card is pretty straightforward, a single call...
|
||||||
// M0 max SPI is 12 MHz
|
if(!SD.begin(SD_CS, SD_SCK_MHZ(25))) { // ESP32 requires 25 MHz limit
|
||||||
// ESP32 can handl 25 MHz
|
|
||||||
if(!SD.begin(SD_CS, SD_SCK_MHZ(12))) {
|
|
||||||
Serial.println(F("SD begin() failed"));
|
Serial.println(F("SD begin() failed"));
|
||||||
for(;;); // Fatal error, do not continue
|
for(;;); // Fatal error, do not continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_ST7735.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
#include <Adafruit_miniTFTWing.h> // Part of Seesaw library
|
#include <Adafruit_miniTFTWing.h> // Part of Seesaw library
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -71,14 +71,12 @@ void setup(void) {
|
||||||
Serial.println(F("TFT initialized."));
|
Serial.println(F("TFT initialized."));
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
// SD card is pretty straightforward, a single call...
|
// SD card is pretty straightforward, a single call...
|
||||||
// M0 max SPI is 12 MHz
|
if(!SD.begin(SD_CS, SD_SCK_MHZ(25))) { // ESP32 requires 25 MHz limit
|
||||||
// ESP32 can handl 25 MHz
|
|
||||||
if(!SD.begin(SD_CS, SD_SCK_MHZ(12))) {
|
|
||||||
Serial.println(F("SD begin() failed"));
|
Serial.println(F("SD begin() failed"));
|
||||||
for(;;); // Fatal error, do not continue
|
for(;;); // Fatal error, do not continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
Adafruit_ILI9341 tft(tft8bitbus, TFT_D0, TFT_WR, TFT_DC, TFT_CS, TFT_RST, TFT_RD);
|
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
|
tft.begin(); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_ILI9341.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ void setup(void) {
|
||||||
tft.begin(); // Initialize screen
|
tft.begin(); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
#include <Adafruit_GFX.h> // Core graphics library
|
||||||
#include <Adafruit_ST7735.h> // Hardware-specific 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_SPIFlash.h> // SPI / QSPI flash library
|
||||||
#include <Adafruit_ImageReader.h> // Image-reading functions
|
#include <Adafruit_ImageReader.h> // Image-reading functions
|
||||||
#include <Adafruit_seesaw.h> // IF EARLY TFT SHIELD (no Seesaw),
|
#include <Adafruit_seesaw.h> // IF EARLY TFT SHIELD (no Seesaw),
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ void setup(void) {
|
||||||
tft.initR(INITR_BLACKTAB); // Initialize screen
|
tft.initR(INITR_BLACKTAB); // Initialize screen
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
#if defined(USE_SD_CARD)
|
#if defined(USE_SD_CARD)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
FatVolume filesys;
|
FatFileSystem filesys;
|
||||||
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
|
||||||
|
|
||||||
Adafruit_ST7789 tft = Adafruit_ST7789(spi, TFT_CS, TFT_DC, TFT_RST);
|
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
|
digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
// 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!
|
// BE INITIALIZED before using any of the image reader functions!
|
||||||
Serial.print(F("Initializing filesystem..."));
|
Serial.print(F("Initializing filesystem..."));
|
||||||
// SPI or QSPI flash requires two steps, one to access the bare flash
|
// SPI or QSPI flash requires two steps, one to access the bare flash
|
||||||
|
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
// Adafruit_ImageReader test for Adafruit E-Ink Breakouts.
|
|
||||||
// Demonstrates loading images from SD card or flash memory to the screen,
|
|
||||||
// to RAM, and how to query image file dimensions.
|
|
||||||
// Requires BMP file in root directory of QSPI Flash:
|
|
||||||
// blinka.bmp.
|
|
||||||
|
|
||||||
#include <Adafruit_GFX.h> // Core graphics library
|
|
||||||
#include "Adafruit_ThinkInk.h"
|
|
||||||
#include <SdFat_Adafruit_Fork.h> // SD card & FAT filesystem library
|
|
||||||
#include <Adafruit_SPIFlash.h> // SPI / QSPI flash library
|
|
||||||
#include <Adafruit_ImageReader_EPD.h> // Image-reading functions
|
|
||||||
|
|
||||||
// Comment out the next line to load from SPI/QSPI flash instead of SD card:
|
|
||||||
#define USE_SD_CARD
|
|
||||||
|
|
||||||
#define EPD_DC 10 // can be any pin, but required!
|
|
||||||
#define EPD_CS 9 // can be any pin, but required!
|
|
||||||
#define SRAM_CS 6 // can set to -1 to not use a pin (uses a lot of RAM!)
|
|
||||||
#define EPD_BUSY 7 // can set to -1 to not use a pin (will wait a fixed delay)
|
|
||||||
#define EPD_RESET 8 // can set to -1 and share with chip Reset (can't deep sleep)
|
|
||||||
#define SD_CS 5 // SD card chip select
|
|
||||||
|
|
||||||
// Mono Displays
|
|
||||||
//ThinkInk_154_Mono_D67 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
//ThinkInk_154_Mono_D27 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
//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
|
|
||||||
//ThinkInk_154_Tricolor_Z17 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
//ThinkInk_154_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
//ThinkInk_213_Tricolor_RW display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
//ThinkInk_213_Tricolor_Z16 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
//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);
|
|
||||||
//ThinkInk_213_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
//ThinkInk_290_Grayscale4_T5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(USE_SD_CARD)
|
|
||||||
SdFat SD; // SD card filesystem
|
|
||||||
Adafruit_ImageReader_EPD 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 || defined(ADAFRUIT_CIRCUITPLAYGROUND_M0))
|
|
||||||
Adafruit_FlashTransport_SPI flashTransport(SS, &SPI);
|
|
||||||
#else
|
|
||||||
Adafruit_FlashTransport_SPI flashTransport(SS1, &SPI1);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
|
||||||
FatVolume filesys;
|
|
||||||
Adafruit_ImageReader_EPD reader(filesys); // Image-reader, pass in flash filesys
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Adafruit_Image_EPD 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
|
|
||||||
|
|
||||||
display.begin();
|
|
||||||
|
|
||||||
#if defined(FLEXIBLE_213) || defined(FLEXIBLE_290)
|
|
||||||
// The flexible displays have different buffers and invert settings!
|
|
||||||
display.setBlackBuffer(1, false);
|
|
||||||
display.setColorBuffer(1, false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The Adafruit_ImageReader constructor call (above, before setup())
|
|
||||||
// accepts an uninitialized SdFat or FatVolume 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 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!"));
|
|
||||||
|
|
||||||
// Load full-screen BMP file 'blinka.bmp' at position (0,0) (top left).
|
|
||||||
// Notice the 'reader' object performs this, with 'epd' as an argument.
|
|
||||||
Serial.print(F("Loading blinka.bmp to canvas..."));
|
|
||||||
stat = reader.drawBMP((char *)"/blinka.bmp", display, 0, 0);
|
|
||||||
reader.printStatus(stat); // How'd we do?
|
|
||||||
display.display();
|
|
||||||
|
|
||||||
// Query the dimensions of image 'blinka.bmp' WITHOUT loading to screen:
|
|
||||||
Serial.print(F("Querying blinka.bmp image size..."));
|
|
||||||
stat = reader.bmpDimensions("blinka.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(30 * 1000); // Pause 30 seconds before continuing because it's eInk
|
|
||||||
|
|
||||||
Serial.print(F("Drawing canvas to EPD..."));
|
|
||||||
display.clearBuffer();
|
|
||||||
|
|
||||||
// Load small BMP 'blinka.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 larger ram boards like M4, etc.
|
|
||||||
stat = reader.loadBMP("/blinka.bmp", img);
|
|
||||||
reader.printStatus(stat); // How'd we do?
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
for(int r=0; r<4; r++) { // For each of 4 rotations...
|
|
||||||
display.setRotation(r); // Set rotation
|
|
||||||
display.fillScreen(0); // and clear screen
|
|
||||||
display.clearBuffer();
|
|
||||||
img.draw(display, 0, 0);
|
|
||||||
display.display();
|
|
||||||
delay(30 * 1000); // Pause 30 sec.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3 KiB |
0
images/purple.bmp
Normal file → Executable file
|
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
|
@ -1,5 +1,5 @@
|
||||||
name=Adafruit ImageReader Library
|
name=Adafruit ImageReader Library
|
||||||
version=2.10.0
|
version=2.3.4
|
||||||
author=Adafruit
|
author=Adafruit
|
||||||
maintainer=Adafruit <info@adafruit.com>
|
maintainer=Adafruit <info@adafruit.com>
|
||||||
sentence=Companion library for Adafruit_GFX and Adafruit_EPD to load images from SD card.
|
sentence=Companion library for Adafruit_GFX and Adafruit_EPD to load images from SD card.
|
||||||
|
|
@ -7,4 +7,4 @@ paragraph=Install this library in addition to Adafruit_GFX and the display libra
|
||||||
category=Display
|
category=Display
|
||||||
url=https://github.com/adafruit/Adafruit_ImageReader
|
url=https://github.com/adafruit/Adafruit_ImageReader
|
||||||
architectures=*
|
architectures=*
|
||||||
depends=Adafruit GFX Library, Adafruit ST7735 and ST7789 Library, Adafruit HX8357 Library, Adafruit ILI9341, Adafruit SSD1351 library, Adafruit SSD1331 OLED Driver Library for Arduino, Adafruit SPIFlash, SdFat - Adafruit Fork, Adafruit EPD
|
depends=Adafruit GFX Library, Adafruit ST7735 and ST7789 Library, Adafruit HX8357 Library, Adafruit ILI9341, Adafruit SSD1351 library, Adafruit SSD1331 OLED Driver Library for Arduino, Adafruit SPIFlash, SdFat - Adafruit Fork, Adafruit EPD
|
||||||