Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: 3.5 inch RPi LCD with Teensy 4.0 problem

  1. #1

    3.5 inch RPi LCD with Teensy 4.0 problem

    Hello.
    I want to use a 3.5 inch RPi LCD + Touchscreen with the Teensy 4.0. The display can be seen here. I know the page is not in English, but I could not find something else. At least, you can see how it looks like.

    I made a small hardware modification to the display in order to make it work with 3.3V instead of the 5V supplied by the Raspberry Pi.
    You can see the modification in the image bellow (I have to clean the flux from the black PCB in which the display is soldered). I just removed the LDO and bridged the IN and OUT traces. Now the display turns on.
    Click image for larger version. 

Name:	WhatsApp Image 2020-10-08 at 20.35.32.jpg 
Views:	16 
Size:	110.9 KB 
ID:	22026

    I have connected it to the Teensy 4.0 like this:
    Click image for larger version. 

Name:	Teensy conections.jpg 
Views:	10 
Size:	165.1 KB 
ID:	22029
    And the 3.3V and GND of course.

    I used this image for determining the pins:
    Click image for larger version. 

Name:	RPi 3.5inch Pins.jpg 
Views:	21 
Size:	136.1 KB 
ID:	22028

    I used the graphics test sketch from the Examples in the Arduino IDE (Examples > ILI9341_t3 > graphicstest)
    Here is the code:
    Code:
    /***************************************************
      This is our GFX example for the Adafruit ILI9341 Breakout and Shield
      ----> http://www.adafruit.com/products/1651
    
      Check out the links above for our tutorials and wiring diagrams
      These displays use SPI to communicate, 4 or 5 pins are required to
      interface (RST is optional)
      Adafruit invests time and resources providing this open source code,
      please support Adafruit and open-source hardware by purchasing
      products from Adafruit!
    
      Written by Limor Fried/Ladyada for Adafruit Industries.
      MIT license, all text above must be included in any redistribution
     ****************************************************/
    
    
    #include "SPI.h"
    #include "ILI9341_t3.h"
    #include "font_Arial.h"
    
    // For the Adafruit shield, these are the default.
    #define TFT_DC  27
    #define TFT_CS 26
    
    // Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
    ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
    
    void setup() {
      tft.begin();
    // Note: you can now set the SPI speed to any value
    // the default value is 30Mhz, but most ILI9341 displays
    // can handle at least 60Mhz and as much as 100Mhz
    //  tft.setClock(60000000);
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_YELLOW);
      tft.setTextSize(2);
      tft.println("Waiting for Arduino Serial Monitor...");
    
      Serial.begin(9600);
      while (!Serial) ; // wait for Arduino Serial Monitor
      Serial.println("ILI9341 Test!"); 
    
      // read diagnostics (optional but can help debug problems)
      uint8_t x = tft.readcommand8(ILI9341_RDMODE);
      Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(ILI9341_RDMADCTL);
      Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(ILI9341_RDPIXFMT);
      Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(ILI9341_RDIMGFMT);
      Serial.print("Image Format: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(ILI9341_RDSELFDIAG);
      Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); 
      
      Serial.println(F("Benchmark                Time (microseconds)"));
    
      Serial.print(F("Screen fill              "));
      Serial.println(testFillScreen());
      delay(200);
    
      Serial.print(F("Text                     "));
      Serial.println(testText());
      delay(600);
    
      Serial.print(F("Proportional Text        "));
      Serial.println(testProportionalText());
      delay(600);
    
      Serial.print(F("Lines                    "));
      Serial.println(testLines(ILI9341_CYAN));
      delay(200);
    
      Serial.print(F("Horiz/Vert Lines         "));
      Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
      delay(200);
    
      Serial.print(F("Rectangles (outline)     "));
      Serial.println(testRects(ILI9341_GREEN));
      delay(200);
    
      Serial.print(F("Rectangles (filled)      "));
      Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
      delay(200);
    
      Serial.print(F("Circles (filled)         "));
      Serial.println(testFilledCircles(10, ILI9341_MAGENTA));
    
      Serial.print(F("Circles (outline)        "));
      Serial.println(testCircles(10, ILI9341_WHITE));
      delay(200);
    
      Serial.print(F("Triangles (outline)      "));
      Serial.println(testTriangles());
      delay(200);
    
      Serial.print(F("Triangles (filled)       "));
      Serial.println(testFilledTriangles());
      delay(200);
    
      Serial.print(F("Rounded rects (outline)  "));
      Serial.println(testRoundRects());
      delay(200);
    
      Serial.print(F("Rounded rects (filled)   "));
      Serial.println(testFilledRoundRects());
      delay(200);
    
      Serial.println(F("Done!"));
    
    }
    
    
    void loop(void) {
      for(uint8_t rotation=0; rotation<4; rotation++) {
        tft.setRotation(rotation);
        testText();
        delay(1000);
      }
    }
    
    unsigned long testFillScreen() {
      unsigned long start = micros();
      tft.fillScreen(ILI9341_BLACK);
      tft.fillScreen(ILI9341_RED);
      tft.fillScreen(ILI9341_GREEN);
      tft.fillScreen(ILI9341_BLUE);
      tft.fillScreen(ILI9341_BLACK);
      return micros() - start;
    }
    
    unsigned long testText() {
      tft.fillScreen(ILI9341_BLACK);
      unsigned long start = micros();
      tft.setCursor(0, 0);
      tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
      tft.println("Hello World!");
      tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
      tft.println(1234.56);
      tft.setTextColor(ILI9341_RED);    tft.setTextSize(3);
      tft.println(0xDEADBEEF, HEX);
      tft.println();
      tft.setTextColor(ILI9341_GREEN);
      tft.setTextSize(5);
      tft.println("Groop");
      tft.setTextSize(2);
      tft.println("I implore thee,");
      tft.setTextSize(1);
      tft.println("my foonting turlingdromes.");
      tft.println("And hooptiously drangle me");
      tft.println("with crinkly bindlewurdles,");
      tft.println("Or I will rend thee");
      tft.println("in the gobberwarts");
      tft.println("with my blurglecruncheon,");
      tft.println("see if I don't!");
      return micros() - start;
    }
    
    unsigned long testProportionalText() {
      tft.fillScreen(ILI9341_BLACK);
      unsigned long start = micros();
      tft.setCursor(0, 0);
      tft.setTextColor(ILI9341_WHITE);  tft.setFont(Arial_10);
      tft.println("Hello World!");
      tft.setTextColor(ILI9341_YELLOW); tft.setFont(Arial_16);
      tft.println(1234.56);
      tft.setTextColor(ILI9341_RED);    tft.setFont(Arial_24);
      tft.println(0xDEADBEEF, HEX);
      tft.println();
      tft.setTextColor(ILI9341_GREEN);
      tft.setFont(Arial_40);
      tft.println("Groop");
      tft.setFont(Arial_16);
      tft.println("I implore thee,");
      tft.setFont(Arial_10);
      tft.println("my foonting turlingdromes.");
      tft.println("And hooptiously drangle me");
      tft.println("with crinkly bindlewurdles,");
      tft.println("Or I will rend thee");
      tft.println("in the gobberwarts");
      tft.println("with my blurglecruncheon,");
      tft.println("see if I don't!");
      tft.setFontAdafruit();
      return micros() - start;
    }
    
    unsigned long testLines(uint16_t color) {
      unsigned long start, t;
      int           x1, y1, x2, y2,
                    w = tft.width(),
                    h = tft.height();
    
      tft.fillScreen(ILI9341_BLACK);
    
      x1 = y1 = 0;
      y2    = h - 1;
      start = micros();
      for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
      x2    = w - 1;
      for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
      t     = micros() - start; // fillScreen doesn't count against timing
    
      tft.fillScreen(ILI9341_BLACK);
    
      x1    = w - 1;
      y1    = 0;
      y2    = h - 1;
      start = micros();
      for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
      x2    = 0;
      for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
      t    += micros() - start;
    
      tft.fillScreen(ILI9341_BLACK);
    
      x1    = 0;
      y1    = h - 1;
      y2    = 0;
      start = micros();
      for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
      x2    = w - 1;
      for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
      t    += micros() - start;
    
      tft.fillScreen(ILI9341_BLACK);
    
      x1    = w - 1;
      y1    = h - 1;
      y2    = 0;
      start = micros();
      for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
      x2    = 0;
      for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
    
      return micros() - start;
    }
    
    unsigned long testFastLines(uint16_t color1, uint16_t color2) {
      unsigned long start;
      int           x, y, w = tft.width(), h = tft.height();
    
      tft.fillScreen(ILI9341_BLACK);
      start = micros();
      for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
      for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
    
      return micros() - start;
    }
    
    unsigned long testRects(uint16_t color) {
      unsigned long start;
      int           n, i, i2,
                    cx = tft.width()  / 2,
                    cy = tft.height() / 2;
    
      tft.fillScreen(ILI9341_BLACK);
      n     = min(tft.width(), tft.height());
      start = micros();
      for(i=2; i<n; i+=6) {
        i2 = i / 2;
        tft.drawRect(cx-i2, cy-i2, i, i, color);
      }
    
      return micros() - start;
    }
    
    unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
      unsigned long start, t = 0;
      int           n, i, i2,
                    cx = tft.width()  / 2 - 1,
                    cy = tft.height() / 2 - 1;
    
      tft.fillScreen(ILI9341_BLACK);
      n = min(tft.width(), tft.height()) - 1;
      for(i=n; i>0; i-=6) {
        i2    = i / 2;
        start = micros();
        tft.fillRect(cx-i2, cy-i2, i, i, color1);
        t    += micros() - start;
        // Outlines are not included in timing results
        tft.drawRect(cx-i2, cy-i2, i, i, color2);
      }
    
      return t;
    }
    
    unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
      unsigned long start;
      int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
    
      tft.fillScreen(ILI9341_BLACK);
      start = micros();
      for(x=radius; x<w; x+=r2) {
        for(y=radius; y<h; y+=r2) {
          tft.fillCircle(x, y, radius, color);
        }
      }
    
      return micros() - start;
    }
    
    unsigned long testCircles(uint8_t radius, uint16_t color) {
      unsigned long start;
      int           x, y, r2 = radius * 2,
                    w = tft.width()  + radius,
                    h = tft.height() + radius;
    
      // Screen is not cleared for this one -- this is
      // intentional and does not affect the reported time.
      start = micros();
      for(x=0; x<w; x+=r2) {
        for(y=0; y<h; y+=r2) {
          tft.drawCircle(x, y, radius, color);
        }
      }
    
      return micros() - start;
    }
    
    unsigned long testTriangles() {
      unsigned long start;
      int           n, i, cx = tft.width()  / 2 - 1,
                          cy = tft.height() / 2 - 1;
    
      tft.fillScreen(ILI9341_BLACK);
      n     = min(cx, cy);
      start = micros();
      for(i=0; i<n; i+=5) {
        tft.drawTriangle(
          cx    , cy - i, // peak
          cx - i, cy + i, // bottom left
          cx + i, cy + i, // bottom right
          tft.color565(0, 0, i));
      }
    
      return micros() - start;
    }
    
    unsigned long testFilledTriangles() {
      unsigned long start, t = 0;
      int           i, cx = tft.width()  / 2 - 1,
                       cy = tft.height() / 2 - 1;
    
      tft.fillScreen(ILI9341_BLACK);
      start = micros();
      for(i=min(cx,cy); i>10; i-=5) {
        start = micros();
        tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
          tft.color565(0, i, i));
        t += micros() - start;
        tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
          tft.color565(i, i, 0));
      }
    
      return t;
    }
    
    unsigned long testRoundRects() {
      unsigned long start;
      int           w, i, i2,
                    cx = tft.width()  / 2 - 1,
                    cy = tft.height() / 2 - 1;
    
      tft.fillScreen(ILI9341_BLACK);
      w     = min(tft.width(), tft.height()) - 1;
      start = micros();
      for(i=0; i<w; i+=6) {
        i2 = i / 2;
        tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
      }
    
      return micros() - start;
    }
    
    unsigned long testFilledRoundRects() {
      unsigned long start;
      int           i, i2,
                    cx = tft.width()  / 2 - 1,
                    cy = tft.height() / 2 - 1;
    
      tft.fillScreen(ILI9341_BLACK);
      start = micros();
      for(i=min(tft.width(), tft.height()) - 1; i>20; i-=6) {
        i2 = i / 2;
        tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
      }
    
      return micros() - start;
    }
    I also used this code with a
    Code:
    # define TFT_RST 30
    ...
    ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, TFT_RST);
    The problem is that the display is not working. It is just a white screen. I tried other examples too but nothing made the screen display something.
    When I run the above code the Serial monitor shows this:
    Click image for larger version. 

Name:	Oled_CS.jpg 
Views:	12 
Size:	87.1 KB 
ID:	22030

    The touchscreen is working. I tested it with the XPT2046_Touchscreen example code in the Arduino IDE examples folder (the one that comes with Teensyduino) and it shows the X and Y coordinates of the touch and the pressure.
    If instead of the #define TFT_CS 26 i use #define TFT_CS 2 (the CS pin for the touchscreen) the Serial Monitor shows this:
    Click image for larger version. 

Name:	Touch_CS.jpg 
Views:	11 
Size:	88.6 KB 
ID:	22031

    Am I doing something wrong? What could be the problem?

    Thank you very much in advance for your time.

  2. #2
    Member
    Join Date
    Feb 2017
    Location
    Chicago, IL
    Posts
    26
    I haven't tried this particular model screen, but I did have success with a different RPi SPI screen, the 125Mhz SPI model C. For that model, it basically has a SPI interface to the MCU but uses the 16 bit parallel interface to communicate with the screen, so it is probably just using a shift register to directly convert the SPI data to parallel data. It's been a few weeks and I cleaned away my code sadly, but I recall basically just tweaking the ILI9341_t3 libraries. In the case of my screen, it blindly shifts the SPI data to the 16 bit parallel interface to the screen, so it requires 16 bit SPI data too. In ILI9341_t3.h, I changed LPSPI_TCR_FRAMESZ(7) to LPSPI_TCR_FRAMESZ(15) in writecommand_cont, writecommand_last, writedata8_cont and writedata8_last, effectively sending the 8 bit data as 16 bit data, and I think that worked, or at least took me from white screen to flickering updates. I probably modified the init commands too, from the ILI9341 to the ILI9486 commands in the "stock" examples you can find out there. Hope this pointer helps a little.

  3. #3
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    41
    I want to use a 3.5 inch RPi LCD + Touchscreen with the Teensy 4.0. The display can be seen here. I know the page is not in English, but I could not find something else...

    I do not know if it will help but it is a Waveshare LCD Type (A):

    https://www.waveshare.com/3.5inch-rpi-lcd-a.htm
    https://www.waveshare.com/wiki/3.5inch_RPi_LCD_(A)

  4. #4
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,902
    A while ago @KurtE and I and others worked on getting a RPI Kedei display working with the T3x-T4. You might want to give the library we developed for that a try:
    https://github.com/KurtE/KeDeiRPI35_t3. Its based on the ILI9341 library.

  5. #5
    Member
    Join Date
    Feb 2017
    Location
    Chicago, IL
    Posts
    26
    The latest "high speed SPI" RPi screens are intriguing. The WaveShare Model C uses an ILI9486 controller, I believe. I bought one thinking it would be a ton of work to get running via the Teensy, but it turned out to be a cinch with the tweaks above to the wonderful ILI9341_t3 library, the gift that keeps on giving They clearly refined the chipset and processing from the model A as the circuitry on the back is quite different and very little effort was needed to modify "regular" Teensy SPI driver code to work with it. Anyway, the upshot was, on T4.1 @ 600Mhz, I went from a respectable 51ms for a fullscreen 480x320x16bpp refresh on a BuyDisplay SPI ILI9488 @ 80Mhz, to 26ms on the WaveShare Model C, pushing the SPI bus to 119Mhz. The extra bus speed in conjunction with a 2 byte data transfer for 16bpp (vs 3 byte on the ILI9488) effectively doubled the transfer speed.

    I have, though, now moved on to using a parallel interface, as the same BuyDisplay ILI9488 TFT configured for 8 bit parallel takes a hair over 6.5ms for the same 480x320x16bpp refresh, and I had exactly 9 edge pins to spare on my project so with some juggling (thanks Paul for the wonderful flexibility of alternate pins), I was able to use pins that map to 8 consecutive bits on GPIO6, for blazing fast update speed. Additionally, I have managed to achieve 24fps video streamed from the T4.1 SD card @ a whopping 800x480x16bpp on a 4" BuyDisplay TFT with the NT35510 controller in 8 bit parallel mode, and just failed to stream 24fps 800x480x24bpp, although the gating factor was the SD card read of that much data at ~37ms per frame. I think I will live in this parallel world now, for a bit

  6. #6
    Member
    Join Date
    Feb 2020
    Location
    South Africa
    Posts
    41
    Quote Originally Posted by beermat View Post
    The latest "high speed SPI" RPi screens are intriguing. The WaveShare Model C uses an ILI9486 controller, I believe. I bought one thinking it would be a ton of work to get running via the Teensy, but it turned out to be a cinch with the tweaks above to the wonderful ILI9341_t3 library, the gift that keeps on giving They clearly refined the chipset and processing from the model A as the circuitry on the back is quite different and very little effort was needed to modify "regular" Teensy SPI driver code to work with it. Anyway, the upshot was, on T4.1 @ 600Mhz, I went from a respectable 51ms for a fullscreen 480x320x16bpp refresh on a BuyDisplay SPI ILI9488 @ 80Mhz, to 26ms on the WaveShare Model C, pushing the SPI bus to 119Mhz. The extra bus speed in conjunction with a 2 byte data transfer for 16bpp (vs 3 byte on the ILI9488) effectively doubled the transfer speed.
    Never mind I only now saw the code cleaning away part....

    Hi beermat if possible share your Teensy library for the Waveshare 125 MHz SPI type C - I have a few of these...

  7. #7
    Quote Originally Posted by mjs513 View Post
    A while ago @KurtE and I and others worked on getting a RPI Kedei display working with the T3x-T4. You might want to give the library we developed for that a try:
    https://github.com/KurtE/KeDeiRPI35_t3. Its based on the ILI9341 library.
    Thank you @mjs513
    I have downloaded your library and used the graphicstestKeDei sketch. However the display is still white.
    Here is the code I used:
    Code:
    /***************************************************
      This is our GFX example for the Adafruit ILI9488 Breakout and Shield
      ----> http://www.adafruit.com/products/1651
    
      Check out the links above for our tutorials and wiring diagrams
      These displays use SPI to communicate, 4 or 5 pins are required to
      interface (RST is optional)
      Adafruit invests time and resources providing this open source code,
      please support Adafruit and open-source hardware by purchasing
      products from Adafruit!
    
      Written by Limor Fried/Ladyada for Adafruit Industries.
      MIT license, all text above must be included in any redistribution
     ****************************************************/
    
    
    #include "SPI.h"
    #include "KeDeiRPI35_t3.h"
    //#define TEENSY64
    
    // For the Adafruit shield, these are the default.
    #if defined(__MK66FX1M0__) && !defined(TEENSY64)
    #define TOUCH_CS 2
    #define TFT_CS 26
    KEDEIRPI35_t3 tft = KEDEIRPI35_t3(&SPI, TFT_CS, TOUCH_CS);
    #elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
    // On Teensy 4 beta with Paul's breakout out:
    // Using pins (MOSI, MISO, SCK which are labeled on Audio board breakout location
    // which are not in the Normal processor positions
    // Also DC=10(CS), CS=9(BCLK) and RST 23(MCLK)
    #define TOUCH_CS 2
    #define TFT_CS 26
    KEDEIRPI35_t3 tft = KEDEIRPI35_t3(&SPI, TFT_CS, TOUCH_CS);
    #elif defined(TEENSY64)
    #define TFT_DC 27
    #define TFT_CS 26
    #define TFT_SCK 13
    #define TFT_MISO 12
    #define TFT_MOSI 11
    KEDEIRPI35_t3 tft = KEDEIRPI35_t3(&SPI, TFT_CS, TOUCH_CS, TFT_MOSI, TFT_SCK, TFT_MISO);
    #else
    #error "This example App will only work with Teensy 3.6 or Teensy 4."
    #endif
    void setup() {
      tft.begin();
      tft.fillScreen(KEDEIRPI35_BLACK);
      tft.setTextColor(KEDEIRPI35_YELLOW);
      tft.setTextSize(2);
      tft.println("Waiting for Arduino Serial Monitor...");
      tft.setOrigin(0,0);
      Serial.begin(9600);
      while (!Serial) ; // wait for Arduino Serial Monitor
      Serial.println("ILI9488 Test!"); 
    
      // read diagnostics (optional but can help debug problems)
      uint8_t x = tft.readcommand8(KEDEIRPI35_RDMODE);
      Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(KEDEIRPI35_RDMADCTL);
      Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(KEDEIRPI35_RDPIXFMT);
      Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(KEDEIRPI35_RDIMGFMT);
      Serial.print("Image Format: 0x"); Serial.println(x, HEX);
      x = tft.readcommand8(KEDEIRPI35_RDSELFDIAG);
      Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); 
      
      Serial.println(F("Benchmark                Time (microseconds)"));
    
      Serial.print(F("Screen fill              "));
      Serial.println(testFillScreen());
      delay(200);
    
      Serial.print(F("Text                     "));
      Serial.println(testText());
      delay(600);
    
      Serial.print(F("Lines                    "));
      Serial.println(testLines(KEDEIRPI35_CYAN));
      delay(500);
    
      Serial.print(F("Horiz/Vert Lines         "));
      Serial.println(testFastLines(KEDEIRPI35_RED, KEDEIRPI35_BLUE));
      delay(500);
    
      Serial.print(F("Rectangles (outline)     "));
      Serial.println(testRects(KEDEIRPI35_GREEN));
      delay(500);
    
      Serial.print(F("Rectangles (filled)      "));
      Serial.println(testFilledRects(KEDEIRPI35_YELLOW, KEDEIRPI35_MAGENTA));
      delay(500);
    
      Serial.print(F("Circles (filled)         "));
      Serial.println(testFilledCircles(10, KEDEIRPI35_MAGENTA));
    
      Serial.print(F("Circles (outline)        "));
      Serial.println(testCircles(10, KEDEIRPI35_WHITE));
      delay(200);
    
      Serial.print(F("Triangles (outline)      "));
      Serial.println(testTriangles());
      delay(200);
    
      Serial.print(F("Triangles (filled)       "));
      Serial.println(testFilledTriangles());
      delay(200);
    
      Serial.print(F("Rounded rects (outline)  "));
      Serial.println(testRoundRects());
      delay(200);
    
      Serial.print(F("Rounded rects (filled)   "));
      Serial.println(testFilledRoundRects());
      delay(200);
    
      Serial.println(F("Done!"));
    
    }
    
    
    void loop(void) {
      for(uint8_t rotation=0; rotation<4; rotation++) {
        tft.setRotation(rotation);
        testText();
        delay(1000);
      }
    }
    
    unsigned long testFillScreen() {
      unsigned long start = micros();
      tft.fillScreen(KEDEIRPI35_BLACK);
      tft.fillScreen(KEDEIRPI35_RED);
      tft.fillScreen(KEDEIRPI35_GREEN);
      tft.fillScreen(KEDEIRPI35_BLUE);
      tft.fillScreen(KEDEIRPI35_BLACK);
      return micros() - start;
    }
    
    unsigned long testText() {
      tft.fillScreen(KEDEIRPI35_BLACK);
      unsigned long start = micros();
      tft.setCursor(0, 0);
      tft.setTextColor(KEDEIRPI35_WHITE);  tft.setTextSize(1);
      tft.println("Hello World!");
      tft.setTextColor(KEDEIRPI35_YELLOW); tft.setTextSize(2);
      tft.println(1234.56);
      tft.setTextColor(KEDEIRPI35_RED);    tft.setTextSize(3);
      tft.println(0xDEADBEEF, HEX);
      tft.println();
      tft.setTextColor(KEDEIRPI35_GREEN);
      tft.setTextSize(5);
      tft.println("Groop");
      tft.setTextSize(2);
      tft.println("I implore thee,");
      tft.setTextSize(1);
      tft.println("my foonting turlingdromes.");
      tft.println("And hooptiously drangle me");
      tft.println("with crinkly bindlewurdles,");
      tft.println("Or I will rend thee");
      tft.println("in the gobberwarts");
      tft.println("with my blurglecruncheon,");
      tft.println("see if I don't!");
      return micros() - start;
    }
    
    unsigned long testLines(uint16_t color) {
      unsigned long start, t;
      int           x1, y1, x2, y2,
                    w = tft.width(),
                    h = tft.height();
    
      tft.fillScreen(KEDEIRPI35_BLACK);
    
      x1 = y1 = 0;
      y2    = h - 1;
      start = micros();
      for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
      x2    = w - 1;
      for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
      t     = micros() - start; // fillScreen doesn't count against timing
    
      tft.fillScreen(KEDEIRPI35_BLACK);
    
      x1    = w - 1;
      y1    = 0;
      y2    = h - 1;
      start = micros();
      for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
      x2    = 0;
      for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
      t    += micros() - start;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
    
      x1    = 0;
      y1    = h - 1;
      y2    = 0;
      start = micros();
      for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
      x2    = w - 1;
      for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
      t    += micros() - start;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
    
      x1    = w - 1;
      y1    = h - 1;
      y2    = 0;
      start = micros();
      for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
      x2    = 0;
      for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
    
      return micros() - start;
    }
    
    unsigned long testFastLines(uint16_t color1, uint16_t color2) {
      unsigned long start;
      int           x, y, w = tft.width(), h = tft.height();
    
      tft.fillScreen(KEDEIRPI35_BLACK);
      start = micros();
      for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
      for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);
    
      return micros() - start;
    }
    
    unsigned long testRects(uint16_t color) {
      unsigned long start;
      int           n, i, i2,
                    cx = tft.width()  / 2,
                    cy = tft.height() / 2;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
      n     = min(tft.width(), tft.height());
      start = micros();
      for(i=2; i<n; i+=6) {
        i2 = i / 2;
        tft.drawRect(cx-i2, cy-i2, i, i, color);
      }
    
      return micros() - start;
    }
    
    unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
      unsigned long start, t = 0;
      int           n, i, i2,
                    cx = tft.width()  / 2 - 1,
                    cy = tft.height() / 2 - 1;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
      n = min(tft.width(), tft.height()) - 1;
      for(i=n; i>0; i-=6) {
        i2    = i / 2;
        start = micros();
        tft.fillRect(cx-i2, cy-i2, i, i, color1);
        t    += micros() - start;
        // Outlines are not included in timing results
        tft.drawRect(cx-i2, cy-i2, i, i, color2);
      }
    
      return t;
    }
    
    unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
      unsigned long start;
      int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
      start = micros();
      for(x=radius; x<w; x+=r2) {
        for(y=radius; y<h; y+=r2) {
          tft.fillCircle(x, y, radius, color);
        }
      }
    
      return micros() - start;
    }
    
    unsigned long testCircles(uint8_t radius, uint16_t color) {
      unsigned long start;
      int           x, y, r2 = radius * 2,
                    w = tft.width()  + radius,
                    h = tft.height() + radius;
    
      // Screen is not cleared for this one -- this is
      // intentional and does not affect the reported time.
      start = micros();
      for(x=0; x<w; x+=r2) {
        for(y=0; y<h; y+=r2) {
          tft.drawCircle(x, y, radius, color);
        }
      }
    
      return micros() - start;
    }
    
    unsigned long testTriangles() {
      unsigned long start;
      int           n, i, cx = tft.width()  / 2 - 1,
                          cy = tft.height() / 2 - 1;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
      n     = min(cx, cy);
      start = micros();
      for(i=0; i<n; i+=5) {
        tft.drawTriangle(
          cx    , cy - i, // peak
          cx - i, cy + i, // bottom left
          cx + i, cy + i, // bottom right
          tft.color565(0, 0, i));
      }
    
      return micros() - start;
    }
    
    unsigned long testFilledTriangles() {
      unsigned long start, t = 0;
      int           i, cx = tft.width()  / 2 - 1,
                       cy = tft.height() / 2 - 1;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
      start = micros();
      for(i=min(cx,cy); i>10; i-=5) {
        start = micros();
        tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
          tft.color565(0, i, i));
        t += micros() - start;
        tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
          tft.color565(i, i, 0));
      }
    
      return t;
    }
    
    unsigned long testRoundRects() {
      unsigned long start;
      int           w, i, i2,
                    cx = tft.width()  / 2 - 1,
                    cy = tft.height() / 2 - 1;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
      w     = min(tft.width(), tft.height()) - 1;
      start = micros();
      for(i=0; i<w; i+=6) {
        i2 = i / 2;
        tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
      }
    
      return micros() - start;
    }
    
    unsigned long testFilledRoundRects() {
      unsigned long start;
      int           i, i2,
                    cx = tft.width()  / 2 - 1,
                    cy = tft.height() / 2 - 1;
    
      tft.fillScreen(KEDEIRPI35_BLACK);
      start = micros();
      for(i=min(tft.width(), tft.height()) - 1; i>20; i-=6) {
        i2 = i / 2;
        tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
      }
    
      return micros() - start;
    }
    And here is the serial monitor printout:
    Code:
    ILI9488 Test!
    
    Display Power Mode: 0xFF
    
    MADCTL Mode: 0xFF
    
    Pixel Format: 0xFF
    
    Image Format: 0xFF
    
    Self Diagnostic: 0xFF
    
    Benchmark                Time (microseconds)
    
    Screen fill              1003641
    
    Text                     31099
    
    Lines                    456853
    
    Horiz/Vert Lines         82701
    
    Rectangles (outline)     46945
    
    Rectangles (filled)      2424419
    
    Circles (filled)         374118
    
    Circles (outline)        377290
    
    Triangles (outline)      94516
    
    Triangles (filled)       774477
    
    Rounded rects (outline)  136058
    
    Rounded rects (filled)   2651014
    
    Done!
    Shouldn't there be some #defines for the DC and RST pins of the display?

  8. #8
    Quote Originally Posted by beermat View Post
    I haven't tried this particular model screen, but I did have success with a different RPi SPI screen, the 125Mhz SPI model C. For that model, it basically has a SPI interface to the MCU but uses the 16 bit parallel interface to communicate with the screen, so it is probably just using a shift register to directly convert the SPI data to parallel data. It's been a few weeks and I cleaned away my code sadly, but I recall basically just tweaking the ILI9341_t3 libraries. In the case of my screen, it blindly shifts the SPI data to the 16 bit parallel interface to the screen, so it requires 16 bit SPI data too. In ILI9341_t3.h, I changed LPSPI_TCR_FRAMESZ(7) to LPSPI_TCR_FRAMESZ(15) in writecommand_cont, writecommand_last, writedata8_cont and writedata8_last, effectively sending the 8 bit data as 16 bit data, and I think that worked, or at least took me from white screen to flickering updates. I probably modified the init commands too, from the ILI9341 to the ILI9486 commands in the "stock" examples you can find out there. Hope this pointer helps a little.
    Thank you for this information.
    I have done this but the display is still white.
    Quote Originally Posted by beermat View Post
    In ILI9341_t3.h, I changed LPSPI_TCR_FRAMESZ(7) to LPSPI_TCR_FRAMESZ(15) in writecommand_cont, writecommand_last, writedata8_cont and writedata8_last

    I don't know what you meant by
    Quote Originally Posted by beermat View Post
    modified the init commands too, from the ILI9341 to the ILI9486 commands in the "stock" examples
    Where in the files could I find these commands?

    Thank you.

  9. #9
    After much searching, I think I have found the actual LCD used in my display. It is this one (the 42 pin version).
    It says there that it uses the R61581 driver.

    Is this a discrete driver? Or the ili9341 should work with this?

  10. #10
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,931
    The ILI9341 is setup for ILI9341 and not for this device. This device is more likely usable with the ILI9488 driver (as at least it has the same resolution). The KeDei was another screwy RPI display.
    Also there is another driver we have for that resolution.

    I think there may be some support, but not sure...

    Edit: You might look through the thread: https://forum.pjrc.com/threads/55735...3-x-and-beyond

    Also I think they have had a few different RPI versions out, so may need to see which one it is.
    Do you have a link to the one you have?
    Last edited by KurtE; 10-09-2020 at 02:34 PM.

  11. #11
    Quote Originally Posted by KurtE View Post
    Do you have a link to the one you have?
    This is the one I bought. The silkscreen on the back is a little different, but the placement of the parts is exactly the same.

    Quote Originally Posted by KurtE View Post
    The ILI9341 is setup for ILI9341 and not for this device. This device is more likely usable with the ILI9488 driver (as at least it has the same resolution). The KeDei was another screwy RPI display.
    Also there is another driver we have for that resolution.

    I think there may be some support, but not sure...

    Edit: You might look through the thread: https://forum.pjrc.com/threads/55735...3-x-and-beyond

    Also I think they have had a few different RPI versions out, so may need to see which one it is.
    Do you have a link to the one you have?
    Thank you KurtE. I made some progress with the library in the post.
    Now the display turns on and something appears.
    Se here:
    Click image for larger version. 

Name:	WhatsApp Image 2020-10-09 at 21.33.08.jpg 
Views:	6 
Size:	178.2 KB 
ID:	22039

    And the image "moves" as the test unfolds. (The lines move as a pattern in sync with the data on the serial monitor.)

    Is there anything else I could do to make it better?

    Thanks.

  12. #12
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,931
    You might out of curiosity try out the https://github.com/mjs513/HX8357_t3n
    one... And see if it looks any better.

    What I don't remember is things like with the ILI9486 if it is like the 9488 in that you can not do 16 bit color per pixel over SPI, so instead we are outputting 24 bits. The HX... does allow 16 bit per pixel... But again different manufacturer...

    But if it does need the 24 bits (actually 18 bits) per pixel than my guess is that most things could probably be fixed by changing one or two places.

    In particular the init commands...
    Code:
    static const uint8_t init_commands[] = {
    	16, 0xE0, 0x00,0x03, 0x09, 0x08, 0x16, 0x0A, 0x3F, 0x78, 0x4C, 0x09, 0x0A, 0x08, 0x16, 0x1A, 0x0F,
    	16, 0XE1, 0x00, 0x16, 0x19, 0x03, 0x0F, 0x05, 0x32, 0x45, 0x46, 0x04, 0x0E, 0x0D, 0x35, 0x37, 0x0F,
    	3, 0XC0, 0x17, 0x15,
    	2, 0xC1, 0x41,       //Power Control 2
    	4, 0xC5, 0x00, 0x12, 0x80,        //Power Control 3
    	2, 0x36, 0x48,      //Memory Access
    	2, 0x3A, 0x66,      // Interface Pixel Format, 18bit
    	2, 0xB0, 0x80,      // Interface Mode Control
    	2, 0xB1, 0xA0,      //Frame rate, 60hz
    	2, 0xB4, 0x02,      //Display Inversion Control
    	1, 0XB6, 			//Display Function Control  RGB/MCU Interface Control
    	2, 0x02, 0x02,		//MCU
    	2, 0xE9, 0x00,      // Set Image Functio,Disable 24 bit data
    	5, 0xF7, 0xA9, 0x51, 0x2C, 0x82,          // Adjust Control
    
    	//4, 0xE8, 0x85, 0x00, 0x78,
    	//6, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02,
    	//2, 0xF7, 0x20,
    	//3, 0xEA, 0x00, 0x00,   //Power Control 1
    	
    	0
    };
    And the other possible change needed is in the rotation settings:
    Code:
    #define MADCTL_MY  0x80
    #define MADCTL_MX  0x40
    #define MADCTL_MV  0x20
    #define MADCTL_ML  0x10
    #define MADCTL_RGB 0x00
    #define MADCTL_BGR 0x08
    #define MADCTL_MH  0x04
    
    void ILI9488_t3::setRotation(uint8_t m)
    {
    	rotation = m % 4; // can't be higher than 3
    	beginSPITransaction();
    	writecommand_cont(ILI9488_MADCTL);
    	switch (rotation) {
    	case 0:
    		writedata8_last(MADCTL_MX | MADCTL_BGR);
    		_width  = ILI9488_TFTWIDTH;
    		_height = ILI9488_TFTHEIGHT;
    		break;
    	case 1:
    		writedata8_last(MADCTL_MV | MADCTL_BGR);
    		_width  = ILI9488_TFTHEIGHT;
    		_height = ILI9488_TFTWIDTH;
    		break;
    	case 2:
    		writedata8_last(MADCTL_MY | MADCTL_BGR);
    		_width  = ILI9488_TFTWIDTH;
    		_height = ILI9488_TFTHEIGHT;
    		break;
    	case 3:
    		writedata8_last(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
    		_width  = ILI9488_TFTHEIGHT;
    		_height = ILI9488_TFTWIDTH;
    		break;
    	}
    	endSPITransaction();
    	setClipRect();
    	setOrigin();
    	
    	cursor_x = 0;
    	cursor_y = 0;
    }
    So you might be able to search the ILI9488 thread and see if anyone maybe has a fix for this... I will try see if I has something similar sitting around here.

  13. #13
    Quote Originally Posted by KurtE View Post
    You might out of curiosity try out the https://github.com/mjs513/HX8357_t3n
    one... And see if it looks any better.
    I tried this library and the display is white. I did not change anything in the INIT lines because it is over my head

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •