Now it is getting interesting ...... I solved my boot time issue for many displays and found a nice trick to deal with several displays at once.
Here is a modified schematic:
The pull-up resistors to the displays are now not connected to 3V3 but to a DUE output (24). It means that when this output is LOW and all outputs from the multiplexer are OFF/ high-impedance then all display CS inputs are low/active. By selecting Out 4 of the multiplexer Out 1-3 go into high impedance.
I can then initialize all displays at once, fill the screens at once or write some text into all of them at the same time.
When setting output 24 back to HIGH the displays are again addressed individually by the multiplexer outputs.
Here is the code:
#include <Adafruit_GFX.h> // Core graphics library
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/FreeSansBold12pt7b.h>
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
// Color definitions BLACKTAB are RGB, GREENTAB = BGR (!!)
#define BLACK 0x0000
#define RED 0xF800
#define DRED 0x3000
#define BLUE 0x001F
#define DBLUE 0x0003
#define GREEN 0x07E0
#define DGREEN 0x0180
#define CYAN 0x0198
#define MAGENTA 0xF81F
#define YELLOW 0xFE40
#define WHITE 0xFFFF
#define ORANGE 0xFA80
Adafruit_ST7735 tft = Adafruit_ST7735(10, 8, -1);
char CHR = 0;
void setup(void) {
pinMode(22, OUTPUT);
pinMode(23, OUTPUT);
pinMode(24, OUTPUT); //feeding the pull-up resistors
SetDisplay(4); // set display 1-3 to inactive as long as feed into pull-up resistors is on HIGH
digitalWrite(24, LOW); //the pull-up resistors are now on LOW, all display CS inputs are now LOW / active
tft.initR(INITR_BLACKTAB); //all displays are initialized at once, not in sequence
tft.setSPISpeed(24000000);
tft.setFont(&FreeSansBold12pt7b);
tft.setRotation(3); //I use them horizontally
tft.fillScreen(BLACK);
// now we return to individuall addressing of the displays
digitalWrite(24, HIGH); //the pull-up resistors are on HIGH, from now on only the selected display is active
for(int n = 1; n < 4; n++){ //scroll through the 3 displays
SetDisplay(n); // selects the display
tft.setTextColor(WHITE);
tft.setCursor(5, 18);
tft.print("DISPLAY ");
tft.print(n);
}
} // end setup
void loop() {
for (int M = 1; M < 4; M++){ //Scroll through the three displays
SetDisplay(M);
tft.fillRect(0, 25, 159, 128, BLACK); //fill the variable text area
tft.setCursor(5, 50);
for(int N = 0; N < 32; N++){
//CHR = N;
CHR = N + 32 + ((M-1)*32); //print CHR 32-64 on first display, CHR 65-96 on second display (and so on) ... just a test
tft.print(CHR);
}
}
} // end loop
// This function selects the display by setting two binary outputs to the multiplexer chip
void SetDisplay(int DNo){
if(DNo == 1){
digitalWrite(22, LOW);
digitalWrite(23, LOW); //binary 0
tft.setTextColor(RED);
}
else if(DNo == 2){
digitalWrite(22, HIGH);
digitalWrite(23, LOW); //binary 1
tft.setTextColor(GREEN);
}
else if(DNo == 3){
digitalWrite(22, LOW);
digitalWrite(23, HIGH); //binary 2
tft.setTextColor(BLUE);
}
else if(DNo == 4){ // there is no display #4 in this setup. It sets outputs 1-3 to high-impedance
digitalWrite(22, HIGH);
digitalWrite(23, HIGH); //binary 3 , CS outputs to display 1-3 are now 'high-impedance'.
}
}
The circuit now initializes all displays, rotates them to horizontal and fills them with black color at once in < 500ms. Then by setting output 24 back to HIGH the code returns to individual operation of each display.
I can at any time go back to controlling all displays at once:
SetDisplay(4); //make multiplexer outputs 1-3 high impedance
digitalWrite(24, LOW); //set the CS inputs of all displays to LOW
// do something on all displays at once
// fill screens, write text ......
// then go back to individual operation
SetDisplay(1); //make display 1 active
digitalWrite(24, HIGH); //feed the pull-up resistors with HIGH so that only the active display gets a LOW on CS
//do something on display 1
This is great for clearing all screens when new content shall be written into all displays because filling screens takes time. It now takes roughly 200ms for all displays at once.
This makes the solution practical, even for many displays.
Still need to improve the hardware, the feed into the pull-ups should be properly buffered.
However, this already works brilliant.
