Bodmer / TFT_eSPI

Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
Other
3.78k stars 1.09k forks source link

sharing SPI with other devices #215

Closed rocketbob closed 6 years ago

rocketbob commented 6 years ago

Is there a trick I'm likely not aware of in getting a SD card to work sharing the same SPI lines as a ILI9341, using this library? SDcard and adapter test fine and I can get the SD to read and write using the ESP32 SD examples in a separate project. But by sharing the same SPI MISO, MOSI, and clock pins, and obviously using independent CS pins, I can't get the SD card to work. Meanwhile, the LCD works fine. Watching on a scope my CS pin for the SD card never goes low when calling SD.begin(my cs pin), and I'm sure that has to do with why its not working but I don't see anything obvious. Have tried 10K pullups on everything and different pins for CS to no avail.

This is the most fantastic TFT library I've ever used! Thanks for building it!

Bodmer commented 6 years ago

Hi, thanks for your positive comments, they encourage me to continue development!

I have a display and SD card setup available using an SD card and it is working OK, but saying that is not very helpful to you. Tell me which pins you are using for the TFT and SD card and I will try an identical setup. I assume you are using the Arduino IDE? I have not tried the SD(esp32) library examples, are those the ones you are trying? If you have an example basic sketch for me to try that will help.

rocketbob commented 6 years ago

Yes your library is great and its vastly simplified my code being able to refresh changing values using sprites, instead of managing changes and updating small areas of the display.

Here are my ILI9341 and SD defines:

define TFT_CS 15

define TFT_DC 5

define TFT_RST 4

define TFT_MISO 12

define TFT_MOSI 13

define TFT_SCLK 14

define TFT_LED 2

define SD_MISO 12

define SD_MOSI 13

define SD_CLK 14

define SD_CS 27

So, 12,13 & 14 are shared. Yes, I'm using the default SD library. I will put a sample sketch together this evening. I'm using Visual Micro with Visual Studio 2017.

I've tried several different pins for SD_CS to no avail. The thing I know is wrong is SD_CS not going low, which would make it impossible to read the SD card if it never goes low. Question is why.

I've tried reinitializing SPI before the following code, but it doesn't change anything. During this call I never see the SD_CS pin go low. I've enabled SUPPORT_TRANSACTIONS in User_setup.h and as expected, it made no difference.

if (!SD.begin(SD_CS)){ Serial.println(F("Card Mount Failed")); Serial.print("SD_CS "); Serial.println(SD_CS); Serial.print("SD_MOSI "); Serial.println(SD_MOSI); Serial.print("SD_MISO "); Serial.println(SD_MISO); Serial.print("SD_CLK "); Serial.println(SD_CLK); }

rocketbob commented 6 years ago

Basically to test this, connect up your LCD and SD and wire them to the shared pins, separate CS pins, and call SD.Begin(your_sd_cs_pin). It should be as simple as that.

rocketbob commented 6 years ago

One thing to watch out for. Most SD card adapters have a regulator tied to Vcc and there's usually a set of pads on the board to bypass it. If feeding the SD adapter from a 3.3V device such as an ESP32, the jumper is necessary.

Ierlandfan commented 6 years ago

I noticed the same with a ESP32. Though I use a (micro) sdcard adapter that came with the card. (Those black things where you can stick a microsd card in) Could it be that pin 5 (which I use for SD_CS) need to be defined in the user_setup? TFT works fine when using the shared setup but the card will not initialize. (To make sure, Pin 5 is also physically labeled pin 5)

Bodmer commented 6 years ago

I have run this example, I see I added a note that the SD CS must be pin 5, but that is probably because I did not specify the pin in the begin() functions call. I have run it again and it works. Can you try that pin setup and sketch? I am using IDE 1.8.5 but later ones should not cause problems.

rocketbob commented 6 years ago

I'll give this a try tonight. It will be interesting to try using the default pin arrangement, then try by changing the SPI pins.

rocketbob commented 6 years ago

Using your example.

With User_Setup.h configured as:

define TFT_MISO 12

define TFT_MOSI 13

define TFT_SCLK 14

define TFT_CS 15 // Chip select control pin

define TFT_DC 5 // Data Command control pin

define TFT_RST 4 // Reset pin (could connect to RST pin)

I was able to use the LCD but SD did not work with its CS on pin 27.

With User_Setup.h configured as:

define TFT_MISO 19

define TFT_MOSI 23

define TFT_SCLK 18

define TFT_CS 15 // Chip select control pin

define TFT_DC 2 // Data Command control pin

define TFT_RST 4 // Reset pin (could connect to RST pin)

and the SD CS pin on 5, as per your example, neither would work. I checked the wiring several times to validate that I was not losing my mind.

I also tried two different SD adapters of different manufacturers. One is known to work with the basic SD example, as I was able to write two files to SD.

Perhaps I should try a different ESP32 board. I'm using the ESP32U-01 from ezsbc.com.

Bodmer commented 6 years ago

How are you powering the SD Card and TFT?

rocketbob commented 6 years ago

Just off of the USB connection. I wondered about this also, but have yet to wire up power separately.

Bodmer commented 6 years ago

The board you have has quite a weak regulator (250mA maximum) so maybe the load of the ESP32 + display and SD card is too much? If the dis[play has a regulator onboard you can power it from 5V, viz direct from USB.

Bodmer commented 6 years ago

I has a look at my setup. The display runs from 5V and has an onboard regulator. The SDCard board also runs from 5V and has an onboard regulator.

If I run the SDCard board off the 3.3V from the ESP32 board it does not work. This indicates that the power supply is key to the success.

rocketbob commented 6 years ago

I soldered a jumper across two pins of the regulator to bypass it and it ran fine on 3.3V when I successfully ran the SD example. I was able to write two files to SD. So I know the hardware works, albeit in a different pin configuration to run the example. Last night I powered the board with 3.3V from my bench power supply and the SD still didn't work, but that was with my project.

Bodmer commented 6 years ago

I reformatted my SD Card and reloaded the jpegs and now the SDCard works reliably and images are drawn on the TFT even with 3.3V direct from the ESP32 board. The card reports as type SDHC.

I suspect I had a bad connection before as I setup the test on a breadboard with jumper wires.

If you do not use the default SPI pins (MISO=19, MOSI=23, SCK=18)on the ESP32 you must run tft.begin(); before you run SD.begin(), so the SPI ports get moved to those pins by the TFT_eSPI library. This is because the SD library always expects that you use the default SPI pins.

Ierlandfan commented 6 years ago

Does that mean when using the default pins that SD_Begin() needs to be inserted before tft_begin()?

Bodmer commented 6 years ago

The order does not matter if using the default SPI pins, but to be "safe" I would put tft.begin() first.

rocketbob commented 6 years ago

I tried SD.Begin() before tft.Begin(), and the LCD stopped working.

On Fri, Oct 12, 2018 at 7:41 AM Bodmer notifications@github.com wrote:

The order does not matter if using the default SPI pins, but to be "safe" I would put tft.begin() first.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Bodmer/TFT_eSPI/issues/215#issuecomment-429297779, or mute the thread https://github.com/notifications/unsubscribe-auth/AAWWcpeVfpUyd0OmVX00CptYQmq8xQaTks5ukIADgaJpZM4XMM0k .

Bodmer commented 6 years ago

Oh, dear. This is peculiar as it works fine for me, even with your pin setup.

Make sure you set all the CS pins high at the start of setup as in the example. e.g. // Set all chip selects high to avoid bus contention during initialisation of each peripheral digitalWrite(22, HIGH); // Touch controller chip select (if used) digitalWrite(15, HIGH); // TFT screen chip select digitalWrite( 5, HIGH); // SD card chips select

Make sure you have the latest ESP32 board support package installed (1.0.0) as the ESP32 does require the SD library in that package.

rocketbob commented 6 years ago

I believe I've made some headway in figuring this out. It appears that pushSprite doesn't do anything if it follows calls to SD when sharing SPI. I'm able to call fillScreen() and it works fine, and SD continues to work after doing doing so. If I move the lcd initialization code above the SD.Begin() call, then sprites work correctly but the SD does not. I'm thinking this has something to do with the SPI transaction flags not clearing, blocking one or the other, and pushSprite().

Bodmer commented 6 years ago

What size of Sprite and what colour depth. pushSprite uses the same function calls so I am beginning to suspect memory. What happens if you just specify a small sprite. Try the jpeg example cited earlier. I have added the images that must be put on the SD card to the example on github. Post an example sketch that fails.

Bodmer commented 6 years ago

Also disconnect the TFT MISO line from the ESP32, it is not needed unless reading from the display.

rocketbob commented 6 years ago

Getting closer. I had tried removing MISO to no effect, which I had done before.

_sprite.setColorDepth(8); _sprite.createSprite(320, 240);

Using one sprite to refresh the entire screen. Works great.

I just tried resizing to use a smaller sprite (25,25) and it worked. I will keep increasing the size. I'm not writing images but have a pretty extensive menu structure and am updating several values on the screen every 100ms.

Compiler output: Program size: 1,225,733 bytes (used 58% of a 2,097,152 byte maximum) (23.46 secs) Minimum Memory Usage: 67756 bytes (21% of a 327680 byte maximum)

Using Partition Scheme: No OTA (Large app)

On Sat, Oct 13, 2018 at 6:00 AM Bodmer notifications@github.com wrote:

Also disconnect the TFT MISO line from the ESP32, it is not needed unless reading from the display.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Bodmer/TFT_eSPI/issues/215#issuecomment-429527549, or mute the thread https://github.com/notifications/unsubscribe-auth/AAWWcmFUuCSJtynfNNRfmwpuWk6lpWYfks5ukbmkgaJpZM4XMM0k .

rocketbob commented 6 years ago

Everything works fine setting the color depth to 1. But, of course, its monochrome.

On Sat, Oct 13, 2018 at 9:31 AM Bob J. rocketbob@gmail.com wrote:

Getting closer. I had tried removing MISO to no effect, which I had done before.

_sprite.setColorDepth(8); _sprite.createSprite(320, 240);

Using one sprite to refresh the entire screen. Works great.

I just tried resizing to use a smaller sprite (25,25) and it worked. I will keep increasing the size. I'm not writing images but have a pretty extensive menu structure and am updating several values on the screen every 100ms.

Compiler output: Program size: 1,225,733 bytes (used 58% of a 2,097,152 byte maximum) (23.46 secs) Minimum Memory Usage: 67756 bytes (21% of a 327680 byte maximum)

Using Partition Scheme: No OTA (Large app)

On Sat, Oct 13, 2018 at 6:00 AM Bodmer notifications@github.com wrote:

Also disconnect the TFT MISO line from the ESP32, it is not needed unless reading from the display.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Bodmer/TFT_eSPI/issues/215#issuecomment-429527549, or mute the thread https://github.com/notifications/unsubscribe-auth/AAWWcmFUuCSJtynfNNRfmwpuWk6lpWYfks5ukbmkgaJpZM4XMM0k .

rocketbob commented 6 years ago

Wasn't aware of until now what the PSRAM option is for the ESP32 WROOM modules, and have just ordered a couple of boards that have that option.

Seems to be the logical fix to this.

I'm looking for a way to monitor ram usage.

On Sat, Oct 13, 2018 at 10:03 AM Bob J. rocketbob@gmail.com wrote:

Everything works fine setting the color depth to 1. But, of course, its monochrome.

On Sat, Oct 13, 2018 at 9:31 AM Bob J. rocketbob@gmail.com wrote:

Getting closer. I had tried removing MISO to no effect, which I had done before.

_sprite.setColorDepth(8); _sprite.createSprite(320, 240);

Using one sprite to refresh the entire screen. Works great.

I just tried resizing to use a smaller sprite (25,25) and it worked. I will keep increasing the size. I'm not writing images but have a pretty extensive menu structure and am updating several values on the screen every 100ms.

Compiler output: Program size: 1,225,733 bytes (used 58% of a 2,097,152 byte maximum) (23.46 secs) Minimum Memory Usage: 67756 bytes (21% of a 327680 byte maximum)

Using Partition Scheme: No OTA (Large app)

On Sat, Oct 13, 2018 at 6:00 AM Bodmer notifications@github.com wrote:

Also disconnect the TFT MISO line from the ESP32, it is not needed unless reading from the display.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Bodmer/TFT_eSPI/issues/215#issuecomment-429527549, or mute the thread https://github.com/notifications/unsubscribe-auth/AAWWcmFUuCSJtynfNNRfmwpuWk6lpWYfks5ukbmkgaJpZM4XMM0k .

Bodmer commented 6 years ago

OK, good to hear, I will close this.

I recently bought a cheap board with PSRAM and it works fine with large Sprites, even multiple 480 x 320 16 bit screen buffer sprites. The library will be updated soon with the changes. The board also has a microSD socket and Lipo charger so is the board of choice for me now. I will also be adding the option for smooth fonts in PSRAM as that should speed up rendering those nicely.

rocketbob commented 6 years ago

Thanks for all of your help! At a minimum it was a good learning exercise for me. The PSRAM ESP32 I ordered was very similar: https://www.ebay.com/itm/183455967257. I had no idea larger ram was an option until today, although that one appears to have a better antenna.

On Sat, Oct 13, 2018 at 11:47 AM Bodmer notifications@github.com wrote:

OK, good to hear, I will close this.

I recently bought a cheap board with PSRAM https://www.ebay.com/itm/TTGO-T8-V1-1-Wifi-Bluetooth-for-ESP32-WROVER-4MB-FLASH-PSRAM-Electronic-Modules/123392415487?hash=item1cbac2d6ff:g:sWUAAOSwespbrJbs:rk:2:pf:0 and it works fine with large Sprites, even multiple 480 x 320 16 bit screen buffer sprites. The library will be updated soon with the changes. The board also has a microSD socket and Lipo charger so is the board of choice for me now. I will also be adding the option for smooth fonts in PSRAM as that should speed up rendering those nicely.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Bodmer/TFT_eSPI/issues/215#issuecomment-429552149, or mute the thread https://github.com/notifications/unsubscribe-auth/AAWWcoiYmZ94gjal75m9RjiH7BnK0DKCks5ukgsDgaJpZM4XMM0k .

O60PMOT commented 5 years ago

hello, i found this issue. I have little differen trouble - i have T-watcher and i have correct work with SD without tft.begin:

include "SD.h"

include "SPI.h"

include "TFT_eSPI.h"

define PIN_NUM_MISO 2

define PIN_NUM_MOSI 15

define PIN_NUM_CLK 14

define PIN_NUM_CS 13

/*

define TFT_MISO 11

define TFT_MOSI 23

define TFT_SCLK 18

define TFT_CS 27 // Chip select control pin

define TFT_DC 32 // Data Command control pin

define TFT_RST 5 // Reset pin (could connect to RST pin)

define TFT_BL 4 // LED back-light (only for ST7789 with backlight control pin)

*/

TFT_eSPI tft = TFT_eSPI();

void setup() { Serial.begin(115200); SPI.begin(PIN_NUM_CLK, PIN_NUM_MISO, PIN_NUM_MOSI);

if(!SD.begin(PIN_NUM_CS)){
    Serial.println("Card Mount Failed");
    return;
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);

} void loop() {}

this sample work and in monitor:

SD Card Size: 958MB

if i insert tft.begin() - card mount failed, my sample code:

include "SD.h"

include "SPI.h"

include "TFT_eSPI.h"

define PIN_NUM_MISO 2

define PIN_NUM_MOSI 15

define PIN_NUM_CLK 14

define PIN_NUM_CS 13

/*

define TFT_MISO 11

define TFT_MOSI 23

define TFT_SCLK 18

define TFT_CS 27 // Chip select control pin

define TFT_DC 32 // Data Command control pin

define TFT_RST 5 // Reset pin (could connect to RST pin)

define TFT_BL 4 // LED back-light (only for ST7789 with backlight control pin)

*/

TFT_eSPI tft = TFT_eSPI();

void setup() { digitalWrite(TFT_CS, HIGH); // TFT screen chip select digitalWrite(PIN_NUM_CS, HIGH); // SD card chips select

tft.begin();
Serial.begin(115200);
SPI.begin(PIN_NUM_CLK, PIN_NUM_MISO, PIN_NUM_MOSI);

if(!SD.begin(PIN_NUM_CS)){
    Serial.println("Card Mount Failed");
} else {
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);

}

tft.fillScreen(TFT_BLACK);
tft.setRotation(1); 
tft.println("Setup end");

} void loop() {}

screen and sdcard have different pinout.

dbtronics commented 4 months ago

hello, i found this issue. I have little differen trouble - i have T-watcher and i have correct work with SD without tft.begin:

include "SD.h"

include "SPI.h"

include "TFT_eSPI.h"

define PIN_NUM_MISO 2

define PIN_NUM_MOSI 15

define PIN_NUM_CLK 14

define PIN_NUM_CS 13

/*

define TFT_MISO 11

define TFT_MOSI 23

define TFT_SCLK 18

define TFT_CS 27 // Chip select control pin

define TFT_DC 32 // Data Command control pin

define TFT_RST 5 // Reset pin (could connect to RST pin)

define TFT_BL 4 // LED back-light (only for ST7789 with backlight control pin)

*/

TFT_eSPI tft = TFT_eSPI();

void setup() {

Serial.begin(115200);

SPI.begin(PIN_NUM_CLK, PIN_NUM_MISO, PIN_NUM_MOSI);

if(!SD.begin(PIN_NUM_CS)){

    Serial.println("Card Mount Failed");

    return;

}

uint64_t cardSize = SD.cardSize() / (1024 * 1024);

Serial.printf("SD Card Size: %lluMB\n", cardSize);

}

void loop() {}

this sample work and in monitor:

SD Card Size: 958MB

if i insert tft.begin() - card mount failed, my sample code:

include "SD.h"

include "SPI.h"

include "TFT_eSPI.h"

define PIN_NUM_MISO 2

define PIN_NUM_MOSI 15

define PIN_NUM_CLK 14

define PIN_NUM_CS 13

/*

define TFT_MISO 11

define TFT_MOSI 23

define TFT_SCLK 18

define TFT_CS 27 // Chip select control pin

define TFT_DC 32 // Data Command control pin

define TFT_RST 5 // Reset pin (could connect to RST pin)

define TFT_BL 4 // LED back-light (only for ST7789 with backlight control pin)

*/

TFT_eSPI tft = TFT_eSPI();

void setup() {

digitalWrite(TFT_CS, HIGH); // TFT screen chip select

digitalWrite(PIN_NUM_CS, HIGH); // SD card chips select

tft.begin();

Serial.begin(115200);

SPI.begin(PIN_NUM_CLK, PIN_NUM_MISO, PIN_NUM_MOSI);

if(!SD.begin(PIN_NUM_CS)){

    Serial.println("Card Mount Failed");

} else {

uint64_t cardSize = SD.cardSize() / (1024 * 1024);

Serial.printf("SD Card Size: %lluMB\n", cardSize);

}

tft.fillScreen(TFT_BLACK);

tft.setRotation(1); 

tft.println("Setup end");

}

void loop() {}

screen and sdcard have different pinout.

Hey were you able to get a solution to this? I'm having the same issue. Card mount failed and cant open file.