st7735 multiple displays and chip select

Status
Not open for further replies.

mark.winger

Active member
I am using a teensy 3.5 to build a midi controller with scribble strips.
Using the adafruit st7735 libraries to control the 1.8" tft shield for prototyping.

It appears that no matter what pin I use for tft_cs in the tft object it always uses pin 10. (used graphicstest.ino as sample). I started with:
#define TFT_CS 10
#define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC 8

The created and array for TFT_CS:
int SelectDisplay[DISPLAY_COUNT] = {21, 22};

Then initialized this way:

for (int i = 0 ; i < DISPLAY_COUNT; i++)
{
tft = new Adafruit_ST7735(SelectDisplay, TFT_DC, TFT_RST);
tft->initR(INITR_BLACKTAB); // Init ST7735S chip, black tab
......
}

No matter what pins I use for select, the initR clears the first display when I initialize the second and I cannot display to it. If I set DISPLAY_COUNT to 1 it works fine. I don't have an oscilloscope available see what the signal lines are doing.

Why does this happen? Do I need to use other pins for DC and Reset as well?

Mark
 
Not sure, just guessing:

"Any digital pin can be used for a SS (slave select) signal. The SPI library does not control the SS signals, because devices differ on when this is used, whether it is held low for multiple transfers or for each individual transfer, and so on. Control SS with digitalWrite()."
source: https://www.pjrc.com/teensy/td_libs_SPI.html#altpins

So, maybe, your sketch should take care that the CS signal is HIGH for the first TFT, when initializing the second one.
More generally, if you use n TFTs then you should disable all of the other n-1 CS lines when dealing with just one specific TFT.

As I understand, this can be done by using the digitalWrite() function (where all of the CS pins are previously declared as OUTPUT ones).

What you think? Could work?
 
Why does this happen?

Teensyduino has a heavily modified copy of the Adafruit_ST7735 library. It does use SPI hardware (not ordinary GPIO) to control the CS and DC pins. If you're using that copy of the library, very likely a conflict in the pin control by SPI.

As a first step, try deleting the copy in hardware/teensy/avr/libraries/Adafruit_ST7735, and then install a fresh copy from Adafruit's github repository. Their original version uses ordinary GPIO to control those pins, so it should be much more flexible for use of 2 or more displays. It's also much slower, but useful for troubleshooting.

If that doesn't help, my second guess would be maybe a bug or simple mistake in your code? I see use of arrays and pointers, but only a tiny code fragment that doesn't even show the variable declarations.

Third guess, probably least likely, could be a wiring mistake or oversight. But do take a look at the CS signals, check with a voltmeter to make sure they really are logic high when not in use. Maybe add pullup resistors just to be safe (from "random" stuff before your code initializes the CS pins).
 
I am using a teensy 3.5 to build a midi controller with scribble strips.
Using the adafruit st7735 libraries to control the 1.8" tft shield for prototyping.

It appears that no matter what pin I use for tft_cs in the tft object it always uses pin 10. (used graphicstest.ino as sample). I started with:
#define TFT_CS 10
#define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC 8

The created and array for TFT_CS:
int SelectDisplay[DISPLAY_COUNT] = {21, 22};

Then initialized this way:

for (int i = 0 ; i < DISPLAY_COUNT; i++)
{
tft = new Adafruit_ST7735(SelectDisplay, TFT_DC, TFT_RST);
tft->initR(INITR_BLACKTAB); // Init ST7735S chip, black tab
......
}

No matter what pins I use for select, the initR clears the first display when I initialize the second and I cannot display to it. If I set DISPLAY_COUNT to 1 it works fine. I don't have an oscilloscope available see what the signal lines are doing.

Why does this happen? Do I need to use other pins for DC and Reset as well?

Mark


As Paul says, the Teensy version is modified to speed up the display if you use certain pins for CS and DC. Unfortunately, there are restrictions in the pin use. You can't use several of the pins because they overlap to same internal resources. In particular, you picked pins 21 and 22, which are two of the pins that overlap.

The special pins are:
  • Pin 2 and Pin 10 overlap;
  • Pin 6 and Pin 9 overlap;
  • Pin 15/A1 does not overlap;
  • Pin 20/A6 and 23/A9 overlap;
  • Pin 21/A7 and 22/A8 overlap.

If you choose either 20 or 23 instead of 21 (or other combinations), it may work.

However, in theory, the fast SPI code should not be chosen because your TFT_DC pin is not one of the special pins.

You might try the following (and change the appropriate wires):

Code:
#define TFT_CS          10
#define TFT_RST        8 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC         9

int SelectDisplay[DISPLAY_COUNT] = {20, 21};

Here is the thread where Paul describes this:

And here is another thread about the ST7735 display mess:

Teensyduino has a heavily modified copy of the Adafruit_ST7735 library. It does use SPI hardware (not ordinary GPIO) to control the CS and DC pins. If you're using that copy of the library, very likely a conflict in the pin control by SPI.

As a first step, try deleting the copy in hardware/teensy/avr/libraries/Adafruit_ST7735, and then install a fresh copy from Adafruit's github repository. Their original version uses ordinary GPIO to control those pins, so it should be much more flexible for use of 2 or more displays. It's also much slower, but useful for troubleshooting.

Unfortunately if you take the current Adafruit_ST7735 release, you will also need a new version of Adafruit_GFX. The new Adafruit_ST7735 library uses a define in Adafruit_GFX. Note, this is based on 1.44. I haven't yet installed 1.45. But I will try it tonight when I get home.
 
I tried the suggestions above to no success. I did find a solution.

I had partial success by using gpio pins to control the cs pins. I set select for a device and set font, size, and text and deselect. This did not work for initialization. It dawned on me that the reset pin would reset without being selected. So when I did initR it would reset all displays. So I wired the display reset to a gpio pin and reset on startup of the teensy, Now the code all seems to work.

I don't have all the hardware with me to finish this(I am traveling just have the teensy and 1 display to debug with) I will be back home with some time available in a few weeks. I will respond again when I get to that point.
 
I have some displays from sparkfun (1.8 tft) the appears the only serial mode it supports is 9 bits (I asked sparkfun if this is true and they said they did not have that info. I suspect this is true because the 7735 pin spi4w which specifies 8 or 9 bit is not shown in the pinout of the display).

Paul said in an older thread that the teensys do support 9 bit mode. But the question is do the adafruit libraries I have been using work with 9-bit serial. I hope to try this tomorrow but just wondering if anyone knows if this will work before I start. (don't want to waste a lot of time on a dead end).

Thanks for any info about this.
 
I've never seen a library which really does SPI with 9 bits for those displays. That doesn't mean it isn't out there somewhere, but the normal is the 8 bit protocol with the extra D/C pin.
 
What comes to my mind is that, maybe, different instances of the Adafruit_ST7735 classes share the same CS variable. But I didn't find any trace of this in the adafruit libs... :(

Could you post your test code here?
What about using two distinct RESET lines?
 
What comes to my mind is that, maybe, different instances of the Adafruit_ST7735 classes share the same CS variable. But I didn't find any trace of this in the adafruit libs... :(

Could you post your test code here?
What about using two distinct RESET lines?

My code for the display is embedded within a large control surface project with motorized faders and rotary encoders. Thats why I posting smaller snippets of code to avoid the off topic code.

My solution was simply to use a different pin for reset of all displays. Then I manually do 1 reset(for all displays), then initialize each display. Since the reset pin specified in the tft objects is not connected to anything, the reset sent by the object during initialization is a noop.
 
I've never seen a library which really does SPI with 9 bits for those displays. That doesn't mean it isn't out there somewhere, but the normal is the 8 bit protocol with the extra D/C pin.

In an older thread you mentioned enabling 9 bit serial in a macro. How does 9 bit vs 8 bit differ from the teensy perspective? Is it simply the d/c pin being embedded in the protocol instead of being a hardware pin?

If that is the case it does not seem like it would be to difficult to "hack" the library to add the dc bit to the writes. What do you think?
 
Last edited:
multiple st7735 t4.1

My code for the display is embedded within a large control surface project with motorized faders and rotary encoders. Thats why I posting smaller snippets of code to avoid the off topic code.

My solution was simply to use a different pin for reset of all displays. Then I manually do 1 reset(for all displays), then initialize each display. Since the reset pin specified in the tft objects is not connected to anything, the reset sent by the object during initialization is a noop.

Yeah, I just tripped on this same problem. Initializing multiple screens I forgot that the reset call is part of the constructor. So when I get to initialize the 2nd screen, the first one resets if everything (MOSI,spiclk,DC,/rst) is in parallel and unless you're stepping through line by line it's really easy to screw up. I lost 2 days on that.
 
I have been idle on this for a long time but I am actively working on it now. I am controlling 32 displays now and I am having trouble with one. I have banks of 8 and can unplug and move them around. It could be a wiring problem but here is the problem. Display 28 is using pin 13 as the chip select. The display will display stuff but is erratic. It usually ends up with data from the last display, partial display, or nothing at all. I have a suspicion that the led connected to pin 13 may be causing my problem (slow or week signal). Can I remove the led. (not even sure where it is on the board).
 
Never mind. After considerable headaches, I finally found a poor solder connection that was causing the problem. (I'm getting too old to see the tiny little flaws) :eek:
 
Status
Not open for further replies.
Back
Top