On-going problems with cheap ST7735 TFT displays

Continuing the discussion from [SOLVED] Getting the ST7735 to work with Spark:

I have to come back to this as this is frustrating the hell out of me and I think I have tried all the suggested things in the original thread.

Like @apassemard in the original thread I purchased 3 1.8inch TFT SPI displays which use the ST7735 display controller.

I had originally bought an adafruit 1.8 TFT with microSD card module and have experienced some intermittent issues (white screen). All had settled down and I was getting on with my project and now I have got to the part where I want to use the cheaper displays. Display #1 - initialised OK but nothing shown. Display #2 - a brief flicker. Display #3 - success was short-lived, text displayed for a few seconds then the white screen. I have gone back to my adafruit display and that is playing up.

I am hoping the collective community has some wisdom about what combination of things makes these displays work reliably. Here is a picture of one of the display modules.

@armor, are you using a Core or Photon? Also can you describe your wiring between the Core/Photon and the display. The IDE library is a clone of my original repo. I was planning on updating the code to drop all the Arduino stuff and take advantage of the newest firmware features.

1 Like

Does this mean, that you've also got problems with it (at least the British English interpretation of "playing up" would suggest this)?

The wiring is important here (even if it was already conveyed in the other thread) in this thread, to keep things clear.
One thing from the photo, you'll obviously have to use Vin on the Photon/Core (or any other 5V source) as Vcc on your shield.

Indeed - playing up - means was working and is now not working at least partially.

This is the wiring for adafruit ST7735 module. I am using a Core and I am powering from the 5V Vin - powered by USB connected to a iMac.

My 1.8tftwithsdtest.ino is here - I started on this journey just trying to be able to load images on the TFT.

// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_ST7735/Adafruit_ST7735.h"

// This #include statement was automatically added by the Particle IDE.
#include "sd-card-library/sd-card-library.h"

/**
 * 1.8 inch TFT SPI Screen ST7735 adafruit
 * Board    Core
 * LITE     A0
 * TFTCS    D5 TFT Chip/Slave Select
 * SDCS     D4 SD Chip/Slave Select
 * Vcc      5V
 * GND      GND
 * SCK      A3 Clock
 * D/C      A2 command
 * MOSI     A5 Data MOSI
 * MISO     A4 Data MISO
 * RESET    not connected
 **/
#include "Adafruit_ST7735/Adafruit_mfGFX.h"
#include "Adafruit_ST7735/fonts.h"
#include "application.h"

#define BUFFPIXEL 20

const uint8_t chipSelect = D4;
const uint8_t mosiPin = A5;
const uint8_t misoPin = A4;
const uint8_t clockPin = A3;

unsigned long startMilli = 0UL;

SdFile root;
Sd2Card card;
SdVolume volume;


Adafruit_ST7735 tft = Adafruit_ST7735(D5, A2, 0); // hardware spi

void setup()
{
    Serial.begin(9600);
    Serial.println("Wait for 5 seconds");
    startMilli = millis();
    while ((millis()-startMilli) < 5000);       //wait for 5 seconds
    Serial.println("Done Waiting");
//
    pinMode(A0, OUTPUT);    //PWM on A0 for backlight
    analogWrite(A0, 0);    //backlight off
//
     Serial.print("Initializing SD card...");
      // Initialize SOFTWARE SPI - note Hardware does not work
      if (!card.init(mosiPin, misoPin, clockPin, chipSelect))
      {
        Serial.println("initialization failed! 1");
        return;
      }
      if (!SD.begin(mosiPin, misoPin, clockPin, chipSelect))
      {
        Serial.println("initialization failed! 2");
        return;
      }
      Serial.println("initialization done.");
      if (!volume.init(card))
      {
        Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
        return;
    }
//
    tft.initR(INITR_BLACKTAB);  //for the ST7735R
    Serial.println("Wait for 5 seconds");
    startMilli = millis();
    while ((millis()-startMilli) < 2000);       //wait for 2 seconds
    Serial.println("Done Waiting");
    tft.fillScreen(ST7735_WHITE);
    tft.setRotation(0); //portrait
    analogWrite(A0,127);   // backlight on
    tft.setFont(2); //arial
    tft.setTextSize(1);
    tft.setTextColor(ST7735_BLACK);
    tft.setCursor(0,0);
    tft.println("TFT init done");
    Serial.println("TFT initialisation done");
    bmpDraw("parrot.bmp", 0, 0);
}

void loop(void)
{
}

// This function opens a Windows Bitmap (BMP) file and
// displays it at the given coordinates.  It's sped up
// by reading many pixels worth of data at a time
// (rather than pixel by pixel).  Increasing the buffer
// size takes more of the Particle's precious RAM but
// makes loading a little faster.  20 pixels seems a
// good balance.

// Pass 8-bit (each) R,G,B, get back 16-bit packed color

void bmpDraw(char *filename, uint8_t x, uint16_t y)
{
    File      bmpFile;
    int       bmpWidth, bmpHeight;   // W+H in pixels
    uint8_t   bmpDepth;              // Bit depth (currently must be 24)
    uint16_t  bmpType;
    uint32_t  bmpImageoffset;        // Start of image data in file
    uint32_t  rowSize;               // Not always = bmpWidth; may have padding
    uint8_t   sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
    uint8_t   buffidx = sizeof(sdbuffer); // Current position in sdbuffer
    boolean   goodBmp = false;       // Set to true on valid header parse
    boolean   flip    = true;        // BMP is stored bottom-to-top
    int       w, h, row, col;
    uint8_t   r, g, b;
    uint32_t  pos = 0;

    if ((x >= tft.width()) || (y >= tft.height())) return;
    //truncated
}

I can read the test parrot.BMP fine with just SD card reading using software SPI.

I am now getting the adafruit display to work (hence playing up) but I get this message:

Initializing SD card…Error: CMD0
Error: Sd2Card::init()
initialization failed! 1

from the SD card with software SPI. I am thinking that the card.init using the software SPI is troubling the tft.init if this is done before, so it seems that one can have an SD card reader or a TFT display but not both at the same time?

I have tried something else which is to do the SD reader Hardware SPI instead of the Software SPI. Good news is the screen is still working and now the card is initialising BUT when I go to read the parrot.BMP file it returns 0xFF for every byte read, thus the bmpDraw function ends with no MBP format recognised. The serial log is below:

Wait for 5 seconds
Done Waiting
Initializing SD card…initialization done.
Wait for 5 seconds
Done Waiting
TFT initialisation done
Loading image: parrot.bmp
BMP type: FFFF
BMP format not recognized.

@armor, you pin assignment shows both the SD and the display share the hardware SPI lines. So you might as well use both in hardware spi mode for both. The good news is that both libraries use SPI mode0. However, they both set different SPI setClockDivider values. The second device to be initialized will dictate the final settings which may not agree with the other device. I don’t have a board to test with unfortunately. How are you compiling your project - IDE, DEV, CLI?

1 Like

Web IDE. I am considering moving to the DEV client - would you recommend this over the IDE?

I have just added SD.begin(chipSelect); after the card.Init and set the SPI_FULL_SPEED. This seems to have done the trick (@ScruffR in British English = worked).

I am now nervous to disconnect anything to see if this software now works with the cheap displays. :grimacing:

Anyhow - feeling better than this morning. Thanks for insight on the SPI use.

Contributed to another thread on a cheap ST7735 board not working with the photon. The trick to making these work is with the RESET pin. It essentially needs to be held HIGH and stable at power on otherwise a white screen is all that results. This can be achieved by connecting it to the RST pin on the photon. Simples!

@armor, though I compile locally with a full toolchain, I find having CLI and DEV very useful. I am glad things are now working. Make sure the “cheap” displays have the same pin-out when you test them. Please share your results! :wink: