[Teensy LC] Dual SSD1351 Displays - Sharing a bus [Solved]

Hello,

I have two SSD1351 displays (https://www.ebay.co.uk/itm/153564959422) and I want to use the both on a Teensy LC. (Genuine, purchased from Cool Components: Teensy LC with bootloader | eBay)

I have them both wired up to share the same SPI bus, Datta/Command, Reset but they have their own select lines:

  • 3.3v power
  • SPI Clock: Pin 11 (MOSI0)
  • SPI Data: Pin 13 (SCK0 / LED)
  • Data / Command: Pin 22
  • Reset: Pin 23
  • Select: Pins 24 & 25

When using the Adafruit_SSD1351 library I can use each display individually without any issue, however if I try to use both displays at the same time I seem to run into issues. If I let the Adafruit_SSD1351 library handle the reset lines, only the display which was setup last works. (Which makes sense, setting up the second display resets the initialisation of the first)

In order to try to get this to work, I've setup a minimal example based around the code from the Adafruit Uncanny Eyes project where the Adafruit_SSD1351 library is told not to handle any resets and this is then done separately:

When doing this, the displays both just display gibberish and the Teensy LC seems to lock up - Re-programming requires the use of the manual programming button and any flashing LEDs stop flashing.

I've attached my minimal sample, but I've included the same code below so you don't have to download it:

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>

const uint16_t DisplayColourBlack = 0x0000;
const uint16_t DisplayColourBlue = 0x001F;
const uint16_t DisplayColourRed = 0xF800;
const uint16_t DisplayColourGreen = 0x07E0;
const uint16_t DisplayColourCyan = 0x07FF;
const uint16_t DisplayColourMagenta = 0xF81F;
const uint16_t DisplayColourYellow = 0xFFE0;
const uint16_t DisplayColourWhite = 0xFFFF;

const uint8_t DisplayDataCommandPin = 22;
const uint8_t DisplayResetPin = 23;
const uint8_t DisplayChipSelectLeftPin = 24;
const uint8_t DisplayChipSelectRightPin = 25;

const uint8_t DisplayWidth = 128;
const uint8_t DisplayHeight = 128;

Adafruit_SSD1351 displayLeft = Adafruit_SSD1351(DisplayWidth, DisplayHeight, &SPI, DisplayChipSelectLeftPin, DisplayDataCommandPin, -1);
Adafruit_SSD1351 displayRight = Adafruit_SSD1351(DisplayWidth, DisplayHeight, &SPI, DisplayChipSelectRightPin, DisplayDataCommandPin, -1);

bool left = true;

void setup() {
  pinMode(DisplayChipSelectLeftPin, OUTPUT);
  digitalWrite(DisplayChipSelectLeftPin, HIGH);
  pinMode(DisplayChipSelectRightPin, OUTPUT);
  digitalWrite(DisplayChipSelectRightPin, HIGH);

  pinMode(DisplayResetPin, OUTPUT);
  digitalWrite(DisplayResetPin, LOW);
  delay(10);
  digitalWrite(DisplayResetPin, HIGH);
  delay(500);

  displayLeft.begin(12000000);
  displayRight.begin(12000000);

  displayLeft.fillScreen(DisplayColourCyan);
  displayRight.fillScreen(DisplayColourMagenta);
}

void loop() {
  if (left) {
    displayLeft.fillScreen(DisplayColourBlack);
    displayLeft.setCursor(0, 0);
    displayLeft.setTextColor(DisplayColourWhite);
    displayLeft.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
  }
  else {
    displayRight.fillScreen(DisplayColourBlack);
    displayRight.setCursor(0,0);
    displayRight.setTextColor(DisplayColourYellow);
    displayRight.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
  }

  left = !left;
  delay(1000);
}

Thanks,
-Andrew.

DualDisplayTest.ino (1.99 KB)

You should be ok. You wiggle the RST pin manually. Your sketch looks fine.

The Adafruit_SSD1351 begin() method should only do a software reset (because you said RST= -1)
So left.begin() should not interfere with right.begin().

I am sure that I have tried multiple ST7735 displays on the same SPI bus with success.
I only have one SSD1351 display.

Incidentally, the Teensy LC looks a bit useless. (compared with Teensy 3.x or Teensy 4.0 )

David.

Hi David, thanks for giving it a once over it's good to know I'm on the right track.

Given than the microcontroller seems to hang quite easily as I adjust the startup sequence it looks like there must be some incompatibility between the Adafruit_SSD1351 library and either the Teensy LC or its SPI peripheral.

I picked the Teensy LC as I've had good experiences with Arm Cortex M0 processors in the past and I didn't need anything too crazy for my project, just the two displays which I've offloaded by using hardware SPI, three RGB LEDs which I'm using Neopixel drivers for and a serial port which again I'm going to use a hardware peripheral for. The only part which is intensive is a little bit of JSON processing but the M0 should be more than enough for that. Maybe next time I'll just go for the larger one as they don't cost very much more. (The Teensy 4.0 with it's crazy M7 processor is actually cheaper than the Teensy 3.6!) The Teensy LC does have the advantage of a built-in level shifter on one of the pins which is great for the Neopixel drivers.

I think I'll have to start dissecting the Adafruit_SSD1351 library to see exactly where it's hanging, hopefully that will point me to the problem.

I've just taken another look at this today and managed to track down the issue to the onboard 3.3V voltage regulator.

The documentation for the Teensy LC just mentions "100mA max" next to the 3.3V pin which I thought meant that there was 100mA available after considering the usage of the processor, however it appears to be 100mA including the processor.

The datasheet for the displays suggest that they require about 42mA when fully on so I first ensured that both displays were fully black except for a 5x5 pixel square on each and then tried this configuration. On the oscilloscope the 3.3V rail was being pulled down to ~1.6V occasionally which reset the CPU but it generally worked and a large capacitor held on the 3.3V rail resolved that issue. I then updated the code to fully turn on the displays and tried the same trick. Without the capacitor the 3.3V rail was being pulled down to ~1.6V every 1.7ms causing a fast reboot loop, but sadly with the capacitor the regulator simply wasn't able to supply enough current to get above ~1.6V so I'm going to need to use an external regulator for the displays.

So there you go, if in doubt check your power supply with an oscilloscope! With hindsight the tell-tail should have been fact that the processor seemed to stop when both displays were on and that the computer kept detecting a new serial device in a loop.