Many ST7735 displays on long SPI bus - solution found

Hi, not a problem but an interesting finding that might help others.

In short: Adafruit ST7735 library always initialises the SPI bus with 32MHz, even if you use [object].setSPISpeed(frequency) for turning the SPI clk frequency down. The setting is in the ST77xx library which is used by the ST7735 library and can easily be changed. This can solve many issues with long SPI busses and ST7735 displays.


Background: I am playing with many (24) ST7735 displays with a DUE. I have the logic and code working but I had difficulties to drive the length of SPI bus needed. I use 74HC541 buffers for the bus which works basically great. Today I tried a new (longer) wiring layout from the DUE to the displays and I had trouble to make it work. The wiring setup (breadboard style) was to have

DUE - 20cm SPI wiring - BUFFER IC - 4 displays on 30cm ribbon cable - BUFFER IC - 4 displays on 30cm ribbon cable

Issue: The last 4 displays didn't initialise. Signals on the SPI bus looked good at 8MHz SPI speed. When I checked the SPI CLK signal during initialisation I noticed a small burst ahead of other signals that wasn't passing my last buffer. It was obviously faster than 8MHz (my SPI bus clock setting) and too much rounded/rippled by cable inductivity/parallel capacity/reflections. .

Then I found this line in the ST77xx library:

#define SPI_DEFAULT_FREQ 32000000 ///< Default SPI data clock frequency

On a DUE this will start SPI with 32MHz which is too high for long wiring. As mentioned, turning the SPI clock down by using

Tft.setSPISpeed(8000000);

doesn't help because initialisation somehow starts anyway at 32MHz. This might be a problem in many applications.

I simply edited the line in the ST77xx library to

#define SPI_DEFAULT_FREQ 8000000 ///< Default SPI data clock frequency

which completely solved my problem. Actually this explains many issues I have had with this setup. Wahtever you write in your code, the first part of the display initialisation happens at 32 MHZ (or highest SPI speed of your MCU) and this might be too fast for your wiring.

Feel free to pass questions, I got quite deep into this.......

1 Like

You got lucky, SPI was not designed to drive long wires to other modules. Expect problems in the future with it.

I have been researching this topic for a while. For SPI devices that only receive data from the MCU the bus can be pretty long and may have multiple buffers in series. In my case I have a buffer IC, then 30cm ribbon cable, with 4 displays attached to it, then again a buffer IC, then again 30cm ribbon cable and so on. This can be prolonged because the absolute timing on the bus is uncritical. I found that it works well when all 3 SPI signals (CLK, MOSI, DC) are buffered so their relative edge timing stays the same. However, for the 30cm ribbon cable 16MHz is the maximum, I use 8 MHz for some headroom. CS is rather uncritical, I provide it by shift registers anyway.

I think for SPI devices that require bidirectional communication (FRam, EEproms, SDCards ...) with a MISO line this setup wont work because every buffer introduces a delay that brings MISO and CLK out of synch.
So I dont agree it is luck, its about understanding the principle of that SPI bus.

The problem here was simply that the Adafruit ST77xx library always starts the initialisation at 32MHz which doesn't work if the wiring is a bit lengthy. This could explain many issues other users have had with ST77xx displays on SPI.
I think it is not a good idea for such a library to start communication at highest speed. Seems to be a trouble maker.

Hi,
Have you checked the supply voltage on the troublesome display?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

Sure, and it is not one troublesome display I have - I had a SPI bus problem caused by to high SPI CLK frequency during display initialisation. On my scope i could see, that the 32MHz bursts on the CLK line at the last 74HC541 buffer input didn't cross the LOW threshold any longer (due to rounding by wiring capacitance, inductivity...) while at 16 or 8MHz this works fine with my wiring. However, the way the Adafruit ST77xx library is written it will always start the bus @ 32MHz (or maximum speed of your MCU). For DUE and other boards with high SPI CLK capability this may quite often be a problem.

During experiments I also found that very stable DC and good grounding is essential for this kind of stuff to work at high frequencies. Small 100nf caps blocking HF on DC at every chip, 220uF caps at every 'hop'. I will ensure that for the PCB layout.

You are lucky, buffering definitely helps. You need to treat the connections as transmission lines, that will help a lot. You can use a CAN transceiver for driver and receiver, just keep then enabled. I have gone over 1000 feet doing this. You would need three on each end. If you can many more to the bus if you like.

Yes, I thought about LVDS but the distances are relatively short for that. In the end my device is a housing that is 65cm wide and has 3 rows of 8 displays each. So it is a star wiring DUE into 3 SPI branches and within each branch (a 55cm PCB with 8 displays) i need to build a chain of 4 displays - Buffer IC - 4 displays.
However, it looks good.
I just added an FRam chip and an SD card to the SPI bus close to the DUE and they work well together with all my displays.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.