ST7735 TFT goes blank when initializing SdFat on same SPI

Hi,

I have a ST7735 TFT with an SD card reader connected to an Arduino Nano on the same SPI bus.
But even thought I use two Chip Select pins to avoid conflicts, I cannot get both devices to function at the same time and don’t understand, why.

When I initialize the display first and then call sd.begin(…), the display goes blank (white backlight). Before that, the display works fine, and after having the SD initialized, this one works too, but not the display anymore.

Libraries used (both up to date):

Minimal code example that reproduces the bug:

#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SdFat.h>
#include <sdios.h>
#include <SPI.h>

// Pins
#define DISPLAY_CS 10
#define DISPLAY_DC 8
#define SD_CS 4

Adafruit_ST7735 _tft{DISPLAY_CS, DISPLAY_DC, -1};
SdFat32 _sd;

void setup()
{
    // Deselect all SPI devices before initialization
    pinMode(DISPLAY_CS, OUTPUT);
    pinMode(SD_CS, OUTPUT);
    digitalWrite(DISPLAY_CS, HIGH);
    digitalWrite(SD_CS, HIGH);

    Serial.begin(115200);


    // Init display
    _tft.initR(INITR_BLACKTAB);
    _tft.setSPISpeed(1000000UL * 50); // Make sure the SPI speed is always the same

    // Print something
    _tft.fillScreen(ST77XX_BLACK);
    _tft.setTextColor(ST77XX_WHITE);
    _tft.setTextSize(3);
    _tft.print(F("FOO")); // <--- Is displayed.

    // Just a test, doesnt make a difference.
    digitalWrite(DISPLAY_CS, HIGH);
    digitalWrite(SD_CS, HIGH);


    delay(2000);


    // Init SD
    if (!_sd.begin(SD_CS, 1000000UL * 50)) // <--- TFT goes blank (white backlight)
        _sd.initErrorHalt(&Serial);

    // This hack works, but that's ugly and the TFT still flickers.
    //_tft.initR(INITR_BLACKTAB);

    // Print again
    _tft.fillScreen(ST77XX_BLACK);
    _tft.print(F("BAR")); // <--- Still blank, not displayed.


    Serial.println("I'm alive!"); // Code didn't crash.
}

void loop() {}

I think that the sd.begin() causes the display to receive some wrong data that causes it to go blank. But I don’t undestand, why this can happen, because it’s unselected, when sd.begin is called.

When I remove the sd from the slot, this issue doesn’t occur and the display stays on.

Do you have an idea, what could be causing this behaviour?

Thanks in advance!

Some SD card modules will not play well with other devices on the SPI bus. The problem is with the way the level shifter on the SD module is wired. The ones that do not work well have the MISO signal running through the level shifter. That causes the MISO signal to not be released so that the other devices can control it. The modules made by Adafruit (and some others) have the MISO signal going from the SD card straight to the MISO, bypassing the level shifter. Look at the schematic for the Adafruit module to see what to look for. DO (data out) is the MISO signal.

I think that the sd.begin() causes the display to receive some wrong data that causes it to go blank

i havnt SPI lcd so i cant test it...
but maybe LCD make SPI Bus busy continuously and dont let the sd card for transfering

maybe software SPI is better way (i.e: using another pin for SPI with software SPI library)

@groundFungus: Thank you for your answer. I just checked, and there is no level shifter for the MISO pin on my module. Also the sd card reader is the only device connected to the MISO pin of the arduino, because the display only has MOSI (only receives commands/data).

@marteen1337: What do you mean with making the bus busy continuously? The display does not make the sd reader malfunction in any way. It just goes blank as soon as i use the sd reader.
Yes, software SPI might be a solution to this, but I would prefer to understand the problem instead of working around it. Also the Arduino Nano is a bit short on digital ports and I still need them for some buttons and one more SPI device, later. :wink:

Please post a link to the actual screen that you have bought.

Then you will get an accurate answer.

David.

@david_prentice: Of course, here it is:

(It's a german page, but you can find a download of the datasheet/schematics there.)

It is a regular Red SPI display. You can connect SD and TFT to the same 3.3V SPI bus. Everything will work fine.

Your Nano has 5V logic. So you need to use level shifters of some kind e.g.

  1. purpose made chips e.g. TSX0108
  2. general purpose voltage tolerant buffers e.g. CD4050
  3. series resistors e.g. 10k
  4. voltage dividers e.g. 4k7 + 10k

You need to use the correct 3.3V level on TFT_CS, SD_CS, RST, DC, MOSI, SCK signals e.g. 6 sets (4).
You can put a 10k series resistor in the MISO line but don't use a divider.

Life is much simpler when you use a proper 3.3V MCU like ARM or ESP
But Arduinos with horrible 5V logic work fine (when you add the extra electronics)

David.

@david_prentice:
On the linked product page, the display is advertised to work with 5V TTL levels and it contains all the necessary resistors for the sd card reader. And in fact, both components do work very well with the Arduino, just not both at the same time.

So why should I need additional level shifters? Could you please clarify, how that could solve the issue of the display turning blank/white as soon as the SD communication starts?

As long as I use only one of them, the display or the card reader, they are very reliable.

In the world of Trump shops just lie through their teeth.

The ST7735 datasheet clearly specifies the DC Characteristics logic limits.
The SD card specs specify the limits.

Yes, I am aware that the ST7735 is actually fairly tolerant even though the datasheet states otherwise.
Likewise, many SD cards will work too.

You will not be so fortunate with the ILI9341.

Seriously, it is not difficult to wire up (4) and even easier for (3). Cheaper too.
A TSX0108 is inexpensive. So is CD4050.

Did you ever wonder why Adafruit, SparkFun, Seeed, ... put level shifters on their Arduino Shields ?

David.

@david_prentice: You’re right. I added 5 1K resistors in series to CS, RST, DC, SDA and SCK now and IT WORKS! :slight_smile:
Can you please explain, why this made a difference? I really wonder, how this made the display crashing only when talking with the SD.

And I should probably shoot a mail to that shop… :wink:

Anyway, thank you very much!

It is fairly straightforward. Integrated circuits are made with different layers on a Silicon substrate.

From an electrical connection point of view, no logic signals should be below GND and no logic signals should be above VCC.
Chips have diodes integrated into the Silicon that start conducting if you have voltages < 0V or > VCC.

Your ST7735 has its VCC pin supplied with 3.3V by the AMS1117-3.3V regulator (printed i1 on your pcb)

Whenever the Uno, Nano sends a logic-high signal you have 5V being fed directly to the respective pin on the ST7735. Not only will the substrate diode conduct but it will greatly exceed the safe current. An AVR output pin can source 40mA or more. After all, you have 5V feeding directly to 3.3V (VCC) via the substrate diode.

The substrate diodes are only allowed 10mA or so.

It is pretty obvious that you will harm ANY integrated circuit when you exceed the datasheet limits.
And it is not surprising that the i.c. will lock up or misbehave in some way.

All the same, I can point you to several Arduino Shields that “work” but are technically wrong.
And many “Ebay shop adverts” that are wrong.

I was brought up in a world where you believed parents, teachers, vicars, policemen, … would tell the truth.
Politicians would phrase their words carefully. They did not outright lie but gave you “their opinion”.
The Earth was round. Ohms Law was correct…

I am worried about a child growing up today. Adults make no attempt to be truthful. Should a child believe in a Flat Earth, no Global Warming, … ?

David.

Ah, thank you for the explanation and the lesson, not to believe in what the shopping page says. :slight_smile: Will take a look at the datasheet instead, next time.

But it's interesting, how many webpages and blog posts there are on the internet that explain, how to wire this display wrongly.

I think this is solved then, thank you again! Took me nearly a day of debugging before I gave up and decided to ask here. :slight_smile:

Surely there are many correct examples of how to wire the Red SPI ST7735 display.
Several examples of all 4 methods that I suggested.

I am fascinated by the 5V 8051 examples with direct logic connections. They still use a 3.3V regulator for ST7735 VCC.

8051 has something called a QASI output stage. Whereas chips like AVR, ARM, PIC, ... have a push-pull output stage for their PORTs.

A QASI output can sink current but it can not source current. You attach weak pullups. However it briefly sends a pulse of current when the output goes from low to high. This ensures a square rising edge on the signal that would otherwise look like an I2C SharkFin.
The net effect would be for a 0V low logic and a 3.3V high logic (determined by the substrate diodes)

I am not an electronics engineer. I would appreciate comments from knowledgeable readers.

David.