I'm running into an error where a derivative of the Adafruit_ImageReader library's ILI9341shield example refuses to draw bitmaps from the inserted SD card. Wiring is as follows:
SD card CS: 4
SD card MOSI/TFT MOSI: 11
SD card MISO/TFT MISO: 12
SD card CLK/TFT CLK: 13
TFT CS: 10
TFT RST: 9
TFT DC: 8
All pins are connected through voltage dividers to lower voltages to ~3.3V.
The code I am using is attached below. The SD card is a SanDisk Ultra Plus 64GB microSD card that has been manually reformatted to FAT32 using an external program, which is connected to the TFT (a red ILI9341 off EBay) through a SanDisk microSD adapter. The relevant .bmp file is the only file on the chip.
When turned on and with the sketch uploaded, the screen will turn blue (indicating successful communication between the TFT and Arduino) but will not load the subsequent image. The Serial Monitor reads the following:
Initializing filesystem...OK!
Loading pokedexscreen.bmp to screen...File not found.
// Adafruit_ImageReader test for Adafruit ILI9341 TFT Shield for Arduino.
// Demonstrates loading images from SD card or flash memory to the screen,
// to RAM, and how to query image file dimensions.
// Requires three BMP files in root directory of SD card:
// purple.bmp, parrot.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_ILI9341.h> // Hardware-specific library
#include <SdFat.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 // TFT 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_ILI9341 tft = Adafruit_ILI9341(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);
#if !defined(ESP32)
while(!Serial); // Wait for Serial Monitor before continuing
#endif
tft.begin(); // Initialize screen
// The Adafruit_ImageReader constructor call (above, before setup())
// accepts an uninitialized SdFat or 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(25))) { // ESP32 requires 25 MHz limit
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(ILI9341_BLUE);
tft.setRotation(3);
// Load full-screen BMP file 'pokedexscreen.bmp' at position (0,0) (top left).
// Notice the 'reader' object performs this, with 'tft' as an argument.
Serial.print(F("Loading pokedexscreen.bmp to screen..."));
stat = reader.drawBMP("/pokedexscreen.bmp", tft, 0, 0);
reader.printStatus(stat); // How'd we do?
}
void loop() {
}
I am certain that the TFT works, as I was using it previously to manually draw graphics approximating this image to the screen. I am also certain that the SD card is not corrupted in any meaningful way, as inserting it into a USB adapter allows me to open, add or delete files without issue. However, something appears to be lost in transmission between the SD card and the Arduino - is there some simple error here I'm not seeing?