Imagereader and Teensy 4.0

Howdy everyone. Apologies if this post is not in the correct place.

I have always used the Mega 2560 and I am now trying to use a Teensy 4.0 due to the higher memory.

I am compiling the example sketch from Adafruit_Imagereader "BreakoutST7735-128x128" which I have included below:

// Adafruit_ImageReader test for Adafruit ST7735 TFT Breakout 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:
// rgbwheel.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_ST7735.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 // 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);
  FatVolume        filesys;
  Adafruit_ImageReader reader(filesys); // Image-reader, pass in flash filesys
#endif

Adafruit_ST7735      tft    = Adafruit_ST7735(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.initR(INITR_144GREENTAB); // Initialize screen

  // 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..."));
#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(ST7735_BLUE);

  // Load full-screen BMP file 'rgbwheel.bmp' at position (0,0) (top left).
  // Notice the 'reader' object performs this, with 'tft' as an argument.
  Serial.print(F("Loading rgbwheel.bmp to screen..."));
  stat = reader.drawBMP("/rgbwheel.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.
  }
}

When I compile the code with Mega2560 set as the board, it compiles fine. When I compile the same code and only change the board to Teensy 4.0, I receive the following error:

error: no matching function for call to 'Adafruit_ImageReader::Adafruit_ImageReader(SdFat&)'
note: candidate: 'Adafruit_ImageReader::Adafruit_ImageReader(FatVolume&)'

So when I compile for the teensy, the imagereader function now expects FatVolume instead of SdFat? Why does this code compile for Mega2560 but not for Teensy 4.0? Shouldn't it be using the same Adafruit Imagereader library with the same functions?

Clearly I am missing something. If anyone could point me in the right direction it would be much appreciated.

Thanks everyone :slight_smile:

The Mega2560 and the Teensy 4.0 are completely different processors, and use different libraries.

You need to check whether the Adafruit library supports the Teensy processor, and if it does not, make any necessary changes.

The PJRC Teensy and Adafruit forums would be better places to post.

The library for teensy 4.x is ST7735_t3

Thank you for your reply. I have the display itself working fine with the Adafruit library. I'm able to connect to the screen and draw text/images. I am also able to access the SD card attached to the screen with the SdFat library in my main code.

My only problem is the Adafruit Imagereader library no longer allows me to pass the SdFat object and now expects a FatVolume. I don't understand why, when using the same Adafruit library, the function parameters change.

I will post my question on the forums you mentioned and I'll post any updates here. Thanks.

Thanks, I downloaded the library you recommended. I haven't had any issue connecting the Teensy to the TFT using the Adafruit library and displaying text or graphics primitives, it's just passing the SdFat object to the imagereader lib. Looks like there is an example sketch in the ST7735_t3 library that prints bitmaps, but is not part of the library. I'll see if it works and if so, I guess I'll write my own version and add it to my library.

Presumably the Teensy library for the SD device uses a differently named class to access the physical storage. You didn't post enough of the error messages to deduce the exact issue, but the compiler/linker is suggesting a fix that might work.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.