Help with ST7789 240x240 display not working

boxxofrobots

Well-known member
Anyone have an idea why this doesn't work? I have checked pins 26 and 27, both are dc, no clock or data and obviously nothing appears on the display. Can someone please tell me what I am doing wrong here? I am using one of the Amazon chinese 7789 based 240x240 lcds with no cs pin. The pins are correctly connected as defined in the sketch. I have tried invoking the object using SPI_MODE2, MODE3 and leaving it out altogether, nothing works.

Thanks if you can help, I'm stumped!

Code:
#include <MIDI.h> 
#include <Audio.h>
#include <Wire.h>
#include <Bounce.h>
#include <SPI.h>
#include <SD.h>
#include <PCA9634.h>
#include <Encoder.h>

#include <Arduino.h>
#include <math.h>

#include <Adafruit_GFX.h>      // Core graphics library
#include <Adafruit_ST7789.h>  // ST7789 display library

#define TFT_CS    10  // Chip select pin
#define TFT_RST   9   // Reset pin
#define TFT_DC     8   // Data/Command pin
#define TFT_SCLK     27   // TFT Clock
#define TFT_MOSI     26   // TFT Data
#define TFT_MISO     -1   // 

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Define the SPI port
SPIClass &spiPort = SPI1;  // Use SPI1 on Teensy 4.1
// Create an instance of the ST7789 display
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK);

void setup() {
  // put your setup code here, to run once:
  delay(1000);

  //*display stuff
  spiPort.setMOSI(TFT_MOSI);  // Set the MOSI pin for SPI1 (Teensy 4.1 pin 25)
  spiPort.setMISO(-1);       // Set the MISO pin for SPI1 (Teensy 4.1 pin 26)
  spiPort.setSCK(TFT_SCLK);  // Set the SCK pin for SPI1 (Teensy 4.1 pin 32)
  spiPort.begin();

  // Initialize the display
  tft.init(240, 240, SPI_MODE3);  // Initialize the display with 240x240 resolution
  tft.setRotation(3);             // Set display rotation if needed (0 to 3)
  tft.fillScreen(ST77XX_BLACK);   // Clear the screen with black color

  // Set text color and size
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(2);

  // Print "Hello, World!" at the center of the screen
  tft.setCursor(40, 120);
  tft.println("Hello, World!");
  //
}

void loop() {
}
 
Pretty sure the adafruit library supports displays with no cs pins. If you use the ST7735_t3 library that comes bundled with Teensyduino those displays are supported by simply setting the CS pin to 0xff or -1. You did not mention what Teensy you are using.
 
I'm using the trensy 4.1 and tried the st7735_t3 library, but that resulted in a race condition that left my teensy unstable
 
I'm using the trensy 4.1 and tried the st7735_t3 library, but that resulted in a race condition that left my teensy unstable

I can't help with the adafruit library but if you can switch back to the st7735_t3 library - post the code, wiring, link to the display and any error messages maybe I can help.
 
Sorry BoxOfRobots - I have no idea what you are trying to do...
That is, what is this supposed to do?
Code:
SPIClass &spiPort = SPI1;  // Use SPI1 on Teensy 4.1
// Create an instance of the ST7789 display
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK);

void setup() {
  // put your setup code here, to run once:
  delay(1000);

  //*display stuff
  spiPort.setMOSI(TFT_MOSI);  // Set the MOSI pin for SPI1 (Teensy 4.1 pin 25)
  spiPort.setMISO(-1);       // Set the MISO pin for SPI1 (Teensy 4.1 pin 26)
  spiPort.setSCK(TFT_SCLK);  // Set the SCK pin for SPI1 (Teensy 4.1 pin 32)
  spiPort.begin();
Yes I understand that you setup the spiPort to be a reference to the SPI1 object and you setup specific pins...
But what has that to do with your ST7789 object?

Now if you are expecting that the display is on SPI1, then you need to let it know that. I believe you do that like:
Code:
Adafruit_ST7789 tft = Adafruit_ST7789(&spiPort, TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK);

But again assuming you are trying to use SPI1?

As for ST7789_t3 leaves your teensy unstable? Hard to know what that means. Or what might cause it...
 
@boxxofrobots
I found my ST7789 without a CS pin and hooked it up to a T4.1 and ran graphicstest.ino and it worked without a problem. No race conditions or hangs etc.

EDIT:
Tested on SPI and SPI1 to work.
 
Last edited:
Here's my attemtp at using st7735_t3 and it doesn't crash, but it also doesn't work display anything. Note that I am trying to use spi1 on the default pins, and I've checked my wiring but I get no display. Mjs513, if you can find the time could you try wiring up your display as indicated in my sketch and try it? Or can you just see something I'm doing wrong right off?

Thanks


Code:
/***************************************************
  This is a library for several Adafruit displays based on ST77* drivers.

  Works with the Adafruit 1.8" TFT Breakout w/SD card
    ----> http://www.adafruit.com/products/358
  The 1.8" TFT shield
    ----> https://www.adafruit.com/product/802
  The 1.44" TFT breakout
    ----> https://www.adafruit.com/product/2088
  The 1.54" TFT breakout
    ----> https://www.adafruit.com/product/3787
  The 2.0" TFT breakout
    ----> https://www.adafruit.com/product/4311
  as well as Adafruit raw 1.8" TFT display
    ----> http://www.adafruit.com/products/618

  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
 ****************************************************/

// This Teensy3 and 4 native optimized and extended version
// requires specific pins. 
// If you use the short version of the constructor and the DC
// pin is hardware CS pin, then it will be slower.

#define TFT_MISO  -1
#define TFT_MOSI  26  //a12
#define TFT_SCK   27  //a13
#define TFT_DC   8 
#define TFT_CS   -1  
#define TFT_RST  9

// Note the above pins are for the SPI object.  For those Teensy boards which have
// more than one SPI object, such as T3.5, T3.6, T4 which have at SPI1 and SPI2
// LC with SPI1, look at the cards that come with the teensy or the web page
// https://www.pjrc.com/teensy/pinout.html to select the appropriate IO pins.

//#include <Adafruit_GFX.h>    // Core graphics library
#include <ST7735_t3.h> // Hardware-specific library
#include <ST7789_t3.h> // Hardware-specific library
#include <SPI.h>

// Option 1: use any pins but a little slower
// Note: code will detect if specified pins are the hardware SPI pins
//       and will use hardware SPI if appropriate
// For 1.44" and 1.8" TFT with ST7735 use
//ST7735_t3 tft = ST7735_t3(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);

// For 1.54" or other TFT with ST7789, This has worked with some ST7789
// displays without CS pins, for those you can pass in -1 or 0xff for CS
// More notes by the tft.init call
ST7789_t3 tft = ST7789_t3(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);

// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
// For 1.44" and 1.8" TFT with ST7735 use
//ST7735_t3 tft = ST7735_t3(TFT_CS, TFT_DC, TFT_RST);

// For 1.54" TFT with ST7789
//ST7789_t3 tft = ST7789_t3(TFT_CS, TFT_DC, TFT_RST);

float p = 3.1415926;


void setup(void) {
  //pinMode(SD_CS, INPUT_PULLUP);  // don't touch the SD card
  Serial.begin(9600);
  Serial.print("hello!");

  // Use this initializer if you're using a 1.8" TFT 128x160 displays
  //tft.initR(INITR_BLACKTAB);

  // Or use this initializer (uncomment) if you're using a 1.44" TFT (128x128)
  //tft.initR(INITR_144GREENTAB);

  // Or use this initializer (uncomment) if you're using a .96" TFT(160x80)
  //tft.initR(INITR_MINI160x80);

  // Or use this initializer (uncomment) for Some 1.44" displays use different memory offsets
  // Try it if yours is not working properly
  // May need to tweek the offsets
  //tft.setRowColStart(32,0);

  // Or use this initializer (uncomment) if you're using a 1.54" 240x240 TFT
  //tft.init(240, 240);   // initialize a ST7789 chip, 240x240 pixels

  // OR use this initializer (uncomment) if using a 2.0" 320x240 TFT:
  //tft.init(240, 320);           // Init ST7789 320x240

  // OR use this initializer (uncomment) if using a 240x240 clone 
  // that does not have a CS pin2.0" 320x240 TFT:
  tft.init(240, 240, SPI_MODE2);           // Init ST7789 240x240 no CS

  Serial.println("init");

  uint16_t time = millis();
  tft.fillScreen(ST7735_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(ST7735_BLACK);
  testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST7735_WHITE);
  delay(1000);

  // tft print function!
  tftPrintTest();
  delay(4000);

  // a single pixel
  tft.drawPixel(tft.width()/2, tft.height()/2, ST7735_GREEN);
  delay(500);

  // line draw test
  testlines(ST7735_YELLOW);
  delay(1000);

  // optimized lines
  testfastlines(ST7735_RED, ST7735_BLUE);
  delay(1000);

  testdrawrects(ST7735_GREEN);
  delay(1000);

  testfillrects(ST7735_YELLOW, ST7735_MAGENTA);
  delay(1000);

  tft.fillScreen(ST7735_BLACK);
  testfillcircles(10, ST7735_BLUE);
  testdrawcircles(10, ST7735_WHITE);
  delay(500);

  testroundrects();
  delay(1000);

  testtriangles();
  delay(1000);

  mediabuttons();
  delay(500);

  Serial.println("done");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);
}

void testlines(uint16_t color) {
  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(0, 0, x, tft.height()-1, color);
    delay(200);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(0, 0, tft.width()-1, y, color);
  }

  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, 0, 0, y, color);
  }

  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(0, tft.height()-1, x, 0, color);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
  }

  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
  }
}

void testdrawtext(const char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST7735_BLACK);
  for (int16_t y=0; y < tft.height(); y+=5) {
    tft.drawFastHLine(0, y, tft.width(), color1);
  }
  for (int16_t x=0; x < tft.width(); x+=5) {
    tft.drawFastVLine(x, 0, tft.height(), color2);
  }
}

void testdrawrects(uint16_t color) {
  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
  }
}

void testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST7735_BLACK);
  for (int16_t x=tft.width()-1; x > 6; x-=6) {
    tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
    tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
  }
}

void testfillcircles(uint8_t radius, uint16_t color) {
  for (int16_t x=radius; x < tft.width(); x+=radius*2) {
    for (int16_t y=radius; y < tft.height(); y+=radius*2) {
      tft.fillCircle(x, y, radius, color);
    }
  }
}

void testdrawcircles(uint8_t radius, uint16_t color) {
  for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
    for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
      tft.drawCircle(x, y, radius, color);
    }
  }
}

void testtriangles() {
  tft.fillScreen(ST7735_BLACK);
  int color = 0xF800;
  int t;
  int w = tft.width()/2;
  int x = tft.height()-1;
  int y = 0;
  int z = tft.width();
  for(t = 0 ; t <= 15; t+=1) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x-=4;
    y+=4;
    z-=4;
    color+=100;
  }
}

void testroundrects() {
  tft.fillScreen(ST7735_BLACK);
  int color = 100;
  int i;
  int t;
  for(t = 0 ; t <= 4; t+=1) {
    int x = 0;
    int y = 0;
    int w = tft.width()-2;
    int h = tft.height()-2;
    for(i = 0 ; i <= 16; i+=1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
      x+=2;
      y+=3;
      w-=4;
      h-=6;
      color+=1100;
    }
    color+=100;
  }
}

void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST7735_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST7735_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST7735_BLACK);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST7735_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi?");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST7735_WHITE);
  tft.println("Sketch has been");
  tft.println("running for: ");
  tft.setTextColor(ST7735_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST7735_WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(ST7735_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST7735_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST7735_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_GREEN);
}
 
@boxxofrobots

Just ran the copy and pasted your posted sketch in post #7 and it worked without any issue. Displays everything correctly.

Suggest that maybe you post a link to your display and maybe a photo of the wiring. Just as a note I have VCC attached to 3.3v. BL not connected
 
I second what @mjs513 suggested. It is very difficult to help much without information.
Things like maybe a link to the display. All we know is you maybe got it at Amazon and it was made in China, which does not narrow the search down much.

For example I have purchased 2 of these: https://www.amazon.com/MakerFocus-Display-1-3inch-Interface-Routines/dp/B07P9X3L7M
I can not say for sure that I necessarily can find them. Especially when recently, I did some cleanup and organization of my office, which implies I cannot find a thing ;)
Having a link to things helps as I have seen some products who show one display controller, but the details say it may have X or it may have Y...

Also your wiring. How long are the wires, how is it powered. Again as suggestion a photo can often help.

With the Adafruit library, did you try the change I mentioned?

Good luck
Kurt
 
Interesting. That’s the same one as I am testing with do either your wiring is off or you have a bad display. As we said before maybe a photo of your wiring would help
 
Here's my prototype as it is. Next week I will order the adafruit part and hopefully it will replace both. Anyway, you can sorta track the wiring I guess. I've checked it several times but its entirely possible I overlooked something, I've been going crosseyed all week trying to get this display to work,.

20230624_214244.jpg

20230624_214253.jpg
 
Its a bit hard to tell from the angles but if I zoom in:
Capture.PNG

It looks like pin 26 is not connected and there seems to be a wire going between pins near pin 26 to 24/25. Now even if I am off it looks like you have the green and blue wires attached to the same pin or touching - dont see any solder. Suggest that you pull out a multimeter and check.
 
Here's my prototype as it is. Next week I will order the adafruit part and hopefully it will replace both. Anyway, you can sorta track the wiring I guess. I've checked it several times but its entirely possible I overlooked something, I've been going crosseyed all week trying to get this display to work,.
As @mjs513 mentioned, you probably need to ring out each of the signals.

What I would probably do is use a program that allows you to check to see what if anything is connected to each pin. For example the sketch that @defragster and I played with earlier.
HiLowTest...

It allows you to try to set all of the IO pins to either INPUT_PULLUP or INPUT_PULLDOWN and then keeps checking the state of each of the pins and prints out when a pin changes state.
So for example when all of the pins are in the PU state, you can use a jumper wire with one end connected to GND, and then touch the different terminals on the display and see if it thinks
there is a signal connected to it and if so which one...

Also if you touch one and multiple pins show a change then maybe you have a short. When you change from using PULL up to PULL down or the like, it reports all of the pins that fail to go to the new state. It also has a check to see when going to the new states if when it changes one pin if the ones next to it change as well, again to indicate maybe a short.

This will not work to check to see if your power and gnd pins are connected, but simple multimeter should tell you that.

Also I am assuming nothing else is on those IO pins? That is the displays without a CS pin can only work if they are the only device on the SPI buss.

Kurt
 

Attachments

  • HiLowTest-230417a.zip
    1.1 KB · Views: 24
Success! Thanks everyone for your help. Turns out I had (of course) a wiring error where I was off by one pin and had sclk and sdata crossed. Even after rewiring it twice, I still hadn't managed to do it right. Third time is the charm, I guess. Thanks!

20230625_115650.jpg
 
Thanks again for the help. Made great progress today getting some functionality. Can you guess what it does? I mean, it plays sounds, so maybe how it does what it does?

20230625_182308.jpg
 
Back
Top