8 x 1.44/1.8'' inch 128x128 128x160 TFT Full Color SPI LCD Display Modules over SPI

Status
Not open for further replies.
I've now tried both methods of topology (getting a bit tired of soldering now tbh :) ).
Cables are just butchered Jumper wires - so nothing special or shielded.

Anyways - Both seem to work reliably.
ie data gets sent without corruption.

My one issue is teh speed at which it writes teh data to teh displays.
I appreciate from previous comments, that I may be pushing the limits of this type of bus with my setup - but can anyone suggest any things I can do to speed up the writting to the displays pls.
As the displays are located next to each other in a single row of 8, the data writing appears like a ripple/domino effect from LHS display to RHS display.

I'm sending 2 rows of 4 char strings (max) to each display.
Even teh data writing to one display exhibits the same ripple/domino behaviour.
 
Here's my code for teh data writting - just incase its a code rather HW issue.

Code:
void InstanstAccess_LCDs()
{
    int Text_H = 5;  
    
    for (int n = 1; n < 2; n++)  //n < DispQty; n++) 
    {
        //Draw IA Bank Box
            IA_Bank_Box(n);
    
//        //Display IA Effect Block Names
            mydisp[n].setFont(200);

        //Clear/Blankout previous Effect Name & Xy status
            mydisp[n].setBgColor(BLUE);
            mydisp[n].setColor(BLUE);
            mydisp[n].setMode('C');
            mydisp[n].setTextPosAbs(Text_H, 53);
            mydisp[n].print("                  ");

        if (Disp_FX[n-1] != "")
        {
            if (Disp_FX_Status[n-1] == 1)
            {
                mydisp[n].setBgColor(GREEN);
                mydisp[n].setColor(BLACK);
                mydisp[n].setMode('C');
            }
            else
            {
                mydisp[n].setBgColor(BLUE);
                mydisp[n].setColor(WHITE);
                mydisp[n].setMode('C');
            }
            //Print Effect Name
              mydisp[n].setTextPosAbs(Text_H, 53);
              mydisp[n].print(Disp_FX[n-1]);
              Serial.print(n); Serial.print(" : "); Serial.print(n-1); Serial.print(" : "); Serial.println(Disp_FX[n-1]);
        } 

        mydisp[n].setBgColor(BLUE);
        mydisp[n].setColor(BLUE);
        mydisp[n].setMode('C');
        mydisp[n].setTextPosAbs(Text_H, 105);
        mydisp[n].print("                  ");
                
        if (Disp_FX[n+8-1] != "")
        {
            if (Disp_FX_Status[n+8-1] == 1)
            {
                mydisp[n].setBgColor(GREEN);
                mydisp[n].setColor(BLACK);
                mydisp[n].setMode('C');
            }
            else
            {
                mydisp[n].setBgColor(BLUE);
                mydisp[n].setColor(WHITE);
                mydisp[n].setMode('C');
            }
          
            //Print Effect Name
              mydisp[n].setTextPosAbs(Text_H, 105);
              mydisp[n].print(Disp_FX[n-1+8]);
         }

          if (Disp_FX[n-1] != "")
          {
                 if ( Disp_FX_XorY[n-1] == 0 )
                  {
                      mydisp[n].setBgColor(RED);
                      mydisp[n].setColor(WHITE);
                      mydisp[n].setMode('C');
                      mydisp[n].setFont(18);
                      mydisp[n].setTextPosAbs(125, 48);
                      mydisp[n].print("[Y]");
                      mydisp[n].setFont(200);
                  }
                  else
                  {
                      mydisp[n].setBgColor(BLUE);
                      mydisp[n].setColor(YELLOW);
                      mydisp[n].setMode('C');
                      mydisp[n].setFont(18);
                      mydisp[n].setTextPosAbs(125, 48);
                      mydisp[n].print("[X]");
                      mydisp[n].setFont(200);
                  }
          }

          if (Disp_FX[n+8-1] != "")
          {
                  if ( Disp_FX_XorY[n+8-1] == 0 )
                  {
                      mydisp[n].setBgColor(RED);
                      mydisp[n].setColor(WHITE);
                      mydisp[n].setMode('C');
                      mydisp[n].setFont(18);
                      mydisp[n].setTextPosAbs(125, 98);
                      mydisp[n].print("[Y]");
                      mydisp[n].setFont(200);
                  }
                  else
                  {
                      mydisp[n].setBgColor(BLUE);
                      mydisp[n].setColor(YELLOW);
                      mydisp[n].setMode('C');
                      mydisp[n].setFont(18);
                      mydisp[n].setTextPosAbs(125, 98);
                      mydisp[n].print("[X]");
                      mydisp[n].setFont(200);
                  }
          }   
    }
}
 
My thought is i2c is made for low speed devices where you are only talking to one device. You are talking to 8 devices, so each of the other 7 devices must wait while you update 1. There are ways to increase the speed of the i2c bus (see https://forum.pjrc.com/threads/21680-New-I2C-library-for-Teensy3), but you are just postponing the problem, since you are only talking of doing one transfer at a time.

Ultimately, I suspect the only way to speed things up is to rewrite them so you have one processor per display that reads a simple message from the master teensy, and each processor then does the writing to the display. You are still single threading the write of the messages, but there you would optimize the protocol between the master teensy and the slave processor to send as little data as possible (i.e. just the text, and the slave would do all of the color, etc.). It really depends on how much effort you are wanting to put into this, as this can be a rabbit hole. These slave processors don't necessarily have to be Teensys, though if they aren't Teensys, you have to now program two different environments, and you have to possibly update 9 processors (though I would imagine that after you do the normal development, the display processors wouldn't need to be updated). Of course now you would need to power all 9 processors in addition to the 8 displays.

If you hunt around, you can find 3.3v Arduino Uno clones fairly cheaply. These typically aren't programmed via USB, so you would need a programmer cable. For example:

Even if you use different power supplies, you would need a common ground among all of the processors. Make sure you get 3.3v systems, and not the original 5v system.

If the text is mostly unchanging, you could restructure things so that you only update any display whose information actually changed, and only update the parts of the screen that change.

I could imagine high end displays would have double buffer support, where it displays from one buffer, but the communication builds up the next display in another buffer, and then when everything is in place, you send the command to switch buffers. Looking at the digole programming manual, the only item that jumped out at me is if you had the mono displays, you could send FS0 to stop the refresh from the internal buffer, and FS1 to restart it. So you could go through 8 displays turn off refresh, then go through all 8 displays update the text, and then go through all 8 displays and re-enable the refresh.
 
Thanks Michael.

If the text is mostly unchanging, you could restructure things so that you only update any display whose information actually changed, and only update the parts of the screen that change.

That was going to be one of the things I looked at after hopefully trying afew things on teh i2c side.

My thought is i2c is made for low speed devices where you are only talking to one device.
To help me see if I'm going to be chasing shadows here... could you help me out with your understnading of low speed devices.

Naively maybe - I would not consider this project to be regarded as fast.
ie there is not a constant stream of reading data & then displaying it.
The screens only get updated once per press of a footswitch.
I'm not reading data (as such - ie apart from teh normal to & flow of comms protocol data) from teh i2c displays - just writting data to them.

So would you expect to see this ripple/domino effect the text being written to individual displays & then to each display in turn?

I would say the 8 displays update in less than a sec (although I dont believe I have a way to accurately measure & confirm that).
SO just trying to see if what I'm seeing is expected based on my setup & teh protocol I 'm using.
Or whether the display updates Im seeing are actually unusally slow.
 
Was just looking to the i2c_t3 library you suggested.

Can't confess to understand how the DigoleSerialDisp library was interacting/interfacing with the Wire library - but to get that working I had to ceclare this for each display/address:
Code:
 DigoleSerialDisp mydisp1(&Wire, '\x27');

Does that mean that the DigoleSerialDisp library would need modifying to run witrh the i2c_t3 library.
I can see from teh DigoleSerialDisp.h teh only reference to WIre is
Code:
#include <Wire.h>
.
Would it be as simple as swapping that for i2c_t3.h??

(Sorry for all the amateurish questions - One day I hope I'll understand all this stuff)
 
I was able to get six 1.44" displays running on a Teensy 3.2. I used SCK on 14, MOSI on 11, DC on 21. I used CS on 10, 9, 15, 20 (normal CS pins) plus pins 3 and 4.
With the SPI clock at 24 MHz the displays using pins 3 and 4 showed upside-down images. I tried slowing down the SPI clock and the displays on pins 3 and 4 showed the image right-side up but narrow. I tried 20 MHz (upside down) 16 MHz (narrow), 8 MHz (narrow), and 4 MHz (narrow). Changing the compiler optimization level from "Faster" to "Fast" fixed the problem -- I now have the SPI clock at 20 MHz and all six displays are working correctly.
 
Status
Not open for further replies.
Back
Top