ILI9341 not working on Teensy 4.1

Sorry, sounds like something might be wrong with your display and/or wiring.

Is this a new display? Did you buy it from PJRC or for example from somewhere else like EBAY? Could you show a picture of the bottom of the display?


Also maybe verify that your display is aligned correctly with the pins you plugged into the breadboard. I have accidentally before replugged in a display and figured out later I was off by one row on the breadboard.

My display has no trouble running with 115 MHz at all, and I have tried adding the reset pin to the constructor, with the same error. I am also previously aware of the speed increase by using DC on the hardware CS pin from a different library.
???
It is not working at 30hhz, so not sure why you would think it works at 115mhz? Did you try running at 20mhz?

Well, I’ve tried different breadboards, different MCU boards, different wires and even new headers for the LCD and nothing worked. ESP32, STM32F401 and the Teensy all can’t get it to work, only the stripes.
I am guessing you don't have a second display to try?

Here is a simple sketch that simply sets the display to 3 colors... Setup to run at 20mhz. Note I tested it on my own MMOD board, which is why the #define
Code:
//#define USE_KURTE_MMOD2
#include "SPI.h"
#include "ILI9341_t3n.h"
// *************** Change to your Pin numbers ***************
#define TFT_DC  9
#define TFT_CS 10
#define TFT_RST 8
#define TFT_SCK 13
#define TFT_MISO 12
#define TFT_MOSI 11
#define TOUCH_CS  6

#ifdef USE_KURTE_MMOD2
#undef TFT_DC
#undef TFT_CS
#undef TFT_RST
#define TFT_DC 9
#define TFT_CS 32
#define TFT_RST 31
#endif

#ifndef BLUE
#define BLUE 0x001F
#define BLACK 0x0000
#define WHITE 0xFFFF
#define GREEN 0x07E0
#define RED 0xf800
#endif


ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);

void setup() {
  while (!Serial && millis() < 5000) ; // wait for Arduino Serial Monitor
  Serial.begin(9600);
  delay(500);
  Serial.println("ILI9341 Test!");
  Serial.printf("CS:%u DC:%u RST:%u MOSI:%u SCK:%u MISO:%u\n", TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);
  tft.begin(20000000);

  Serial.println("After TFT Begin");

  tft.fillScreen(RED);
  delay(500);
  tft.fillScreen(GREEN);
  delay(500);
  tft.fillScreen(BLUE);
}
void loop() {
  
}


I checked all pins of all the boards I used. Every single one worked fine.
Here is a pin test program that @defragster and I hacking on to make easier to test the pins:
Code:
#ifdef ESP_PLATFORM
#define digitalWriteFast digitalWrite
#define digitalReadFast digitalRead
#endif

void setup()
{
  Serial.begin(115200);
  while (!Serial && millis() < 4000 );
  Serial.println("Compile Time:: " __FILE__ " " __DATE__ " " __TIME__);
  Serial.printf("Num Digital Pins: %d\n", NUM_DIGITAL_PINS);

  testForShorts();
  
}

uint32_t cnt = 0;
void loop() {
  cnt++;
    allPinTest( cnt );
}

uint32_t pinLast[NUM_DIGITAL_PINS];
void allPinTest( uint32_t cnt ) {
  uint32_t ii, SET;
  Serial.print("PULLDOWN Start Vals:\n  ");
  SET = 0;
  Serial.print("PULLDOWN :: TEST to 3.3V\n  ");
  for ( ii = 0; ii < NUM_DIGITAL_PINS; ii++) {
    pinMode( ii, INPUT_PULLDOWN );
    delayMicroseconds( 5 );
    pinLast[ii] = digitalReadFast( ii );
    if (pinLast[ii]) {
      Serial.print("\nd#=");
      Serial.print( ii );
      Serial.print( " val=" );
    }
    Serial.print( pinLast[ii] );
    Serial.print(',');
  }
  Serial.println();
  Serial.println();
  while ( 1 ) {
    uint32_t jj, dd = 0, cc = 0, ee=4;
    cc = 0;
    for ( ii = 0; ii < NUM_DIGITAL_PINS; ii++) {
      jj = digitalReadFast( ii );
      if ( jj != pinLast[ii] ) {
        dd = 1;
        cc++;
        pinLast[ii] = jj;
        Serial.print("d#=");
        Serial.print( ii );
        if ( pinLast[ii] ) Serial.print( "\t" );
        Serial.print( " val=" );
        Serial.print( pinLast[ii] );
        Serial.print(',');
      }
      if ( cc > 1 && ee ) {
        Serial.println(">>> MULTI CHANGE !!");
        ee--;
      }
      if ( Serial.available() ) {
        while ( Serial.available() ) Serial.read();
        if ( 0 == SET ) {
          SET = 1;
          Serial.print("PULLUP :: TEST TO GND\n  ");
        }
        else {
          SET = 0;
          Serial.print("PULLDOWN :: TEST to 3.3V\n  ");
        }
        for ( ii = 0; ii < NUM_DIGITAL_PINS; ii++) {
          if ( 0 == SET )
            pinMode( ii, INPUT_PULLDOWN );
          else
            pinMode( ii, INPUT_PULLUP );
          delayMicroseconds( 20 );
          pinLast[ii] = digitalReadFast( ii );
          if (SET != pinLast[ii]) {
            Serial.print("d#=");
            Serial.print( ii );
            Serial.print( " val=" );
            Serial.println( pinLast[ii] );
          }
        }
      }
    }
    if ( dd ) {
      dd = 0;
      Serial.println();
      delay( 50 );
    }
  }
}

void testForShorts() {
  uint32_t ii;
  Serial.print("Quick Test for Shorts to adjacent pin");
  Serial.println("First pull pins down and see if the next one follows");
  for ( ii = 0; ii < NUM_DIGITAL_PINS-1; ii++) {
    pinMode( ii+1, INPUT_PULLDOWN );
    pinMode( ii, OUTPUT);
    digitalWrite(ii, HIGH);
    delayMicroseconds( 5 );
    if (digitalRead(ii+1)) {
      Serial.printf("%d:%d ", ii, ii+1);
    }
  }
  Serial.println("\n Now try Pull up and see if setting low follow");
  for ( ii = 0; ii < NUM_DIGITAL_PINS-1; ii++) {
    pinMode( ii+1, INPUT_PULLUP );
    pinMode( ii, OUTPUT);
    digitalWrite(ii, LOW);
    delayMicroseconds( 5 );
    if (!digitalRead(ii+1)) {
      Serial.printf("%d:%d ", ii, ii+1);
    }
  }
  Serial.println();  
}
It sets all of the pins either HIGH or LOW and then loops doing digitalReads of all of the pins and if a pin is not at the expected low or high it reports it to you. You can hit enter in the Serial Terminal to switch from LOW to HIGH on the pin setting. It also tries to guess if there are shorts as if it finds multiple pins changed...

So to use, I typically get it into all pins set HIGH, and then take a jumper wire that one end hooked up to GND and then you can touch other pins and see what pin it is, by what is printed out in the serial monitor window.
Then I would go and touch each signal pin on the display and see if it is connected to what you think it is. And if there might be a short, or open (touch and nothing shows up).
 
Hello, I got my display from here

It is a new display, everything is exactly the same as it appears in the hyperlink above as to in real life.

I have made a mistake with pin alignment at least 4 times and I'm worried that that could have cause the issue, as I'm supplying the display with 5v and the display logic level is 3.3v, so something could have gotten fried.

It used to work perfectly well on 115 MHz, like in this video here (This is a video recorded by me)

I do have a second display to try, but it is a different type. ST7789V (240 x 320). Speaking of it (ST7789), do you know any Teensy 4.1-optimised library for it that uses DMA, and can be used with LVGL library?

I tried your colour code, it does not work for me. Yielding stripes on the display like usual.

The pin test seems to work fine, too. Not only that, but multimeter confirms continuity between the pins, I can read buttons with all the pins and I have confirmed it is connected right.
 
Those displays are cheaply made. The ones PJRC sells get 100% tested and we often find a couple bad units in each batch which we just throw away. I'm pretty sure whoever in China manufacturers them does only random sample testing. But even if you got it from PJRC, if it worked initially, we would have seen it work and concluded it to be a good unit. The test we do takes only a couple sends and involve the operator touching 2 corners of the screen to confirm the touch interface works.

Especially if it's been handled quite a lot, the display part might separate from the red PCB. The display itself as a couple parts which might come separated. Pressing gently might make it work, but the pressure would need to be applied during the moment your program starts up and initializes the display. If that doesn't work, at the display is effectively dead, you might try physically detaching the display part of the red PCB. Normally it's held by glue in a couple spots. Then it will dangle from the flex PCB of the display part which is soldered to a strip of thin pads on the PCB. Maybe gently squeezing the display in places (again, during the moment your program initializes the hardware), or pressing those connections between the display and PCB might help.
 
Hello, thank you for the idea of removing the display! I have just desoldered, thoroughly cleaned with isopropanol and then resoldered the flex cable in place and now it works like a charm. I have dropped it a few times, so that’s maybe why it’s like this.
 
Back
Top