Teensy 3.1 - How to connect an SPI 2.42" OLED display 128x64 - SSD1309 from DIY more

Status
Not open for further replies.

C3D

Active member
Teensy 3.1 - How to connect an SPI 2.42" OLED display 128x64 - SSD1309 from DIY more

Hello Forum,

I guess for the experienced users this is easy.

I have a Teensy 3.1 and i try to figure out on how to connect this: Link display.

So here is what i think could be correct:

Chip select . . . . .CS ---> Pin 10 CS
Data command . . DC ---> ?
Reset . . . . . . . . RES --> ?
Data . . . . . . . . .SDA --> Pin 12 DIN
Clock . . . . . . . . SCL --> Pin 13 SCK
Plus + . . . . . . . .VCC --> +3.6V (Or prob. +5V)
Ground . . . . . . . GND --> Ground

Also i would like to know which library i should use in my case. ( My project is done so far with Adafruit_GFX.h. I just needed a bigger display than 0.96" ) :

U8g2
U8g2_for_Adafruit_GFX
U8glib

Thanks in advance! :)
 
Hello @manitou

Thanks for your answer.

Ive got this from your link, but its for Arduino and not the Teensy:

Finally, connect the pins to your Arduino -

GND goes to ground
Vin goes to 5V
DATA to digital 9
CLK to digital 10
D/C to digital 11
RST to digital 13
CS to digital 12

On the Teensy i have for SPI:

7 DOUT
8 DIN
9 CS
10 CS
11 DOUT
12 DIN
13 SCK
14 SCK
15 CS
20 CS
21 CS

Maybe i misunderstand, but can i just use any of these since they are digital anyways??
 
Iam still trying to connect the display.

So this is the code.

Since its not matching with my display pinout names i better ask before i blow up anything.

MOSI = ?? (SDA?)
CLK = SCL ?
DC = DC ok
CS = CS ok
RESET = RES ok

Is this how you would wire it?

Sorry, its the first time i really use SPI and these numbers dont match up at all with the Teensy "Getting started" card.


Code:
// If using software SPI (the default case):
#define OLED_MOSI   9		// 
#define OLED_CLK   10		// 
#define OLED_DC    11		// 
#define OLED_CS    12		// 
#define OLED_RESET 13		// 
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

// Uncomment this block to use hardware SPI
//#define OLED_DC     6
//#define OLED_CS     7
//#define OLED_RESET  8
//Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
//
 
MOSI is SDA

Okay, i hooked everything up, like the sketch sayd and... it works!!!
Thank you, even if i dont understand the mismatching "Green marked" SPI Port labeling on the "Getting started" card.

So one can just plug in anywhere, as long as you #define it in code?? Hmmm
 
There are two variants for SPI in the source, one is the slower method where it just implements the SPI protocol using basic pins and turning things on or off. The first constructor that is not commented out uses this.

The second variant uses hardware specific pins and is the commented out section. In general, this should be faster because the hardware can do things without having the library do it explicitly.

It doesn't help that there are two different names for the SPI ports. In the later Teensys (3.5/3.6/LC) Paul now uses MOSI/MISO/SCLK while in the 3.0/3.1/3.2 era he used the older names DOUT/DIN/SCK. The same pins are used:
  • Pin 11: MOSI0 (LC/3.5/3.6), MOSI, or DOUT (3.0/3.1/3.2);
  • Pin 12: MISO0 (LC/3.5/3.6), MISO, or DIN (3.0/3.1/3.2);
  • Pin 13: SCLK0 (LC/3.5/3.6), SCLK, or SCK (3.0/3.1/3.2).

Pin 11 is used to write to the device, Pin 12 is used to read from the device, and Pin 13 is the clock signal to say to read or write. Devices like displays often times don't connect up pin 12, since there is no data sent back from the display.

There is an alternate for the 3 SPI pins, but unless you need it (using the audio shield), it is best to use the standard pins.

The numbers after MISO<n>, MOSI<n>, and SCLK<n> are because the newer chips now have more than one SPI bus. But a lot of software in the Arduino world firmly believes that there is only one SPI bus, and it doesn't have options to use the other buses. So you should use the standard 11/12/13 pins by default.

There are 3 other pins. Typically these can be any digital pin:
  • CS -- this pin enables the SPI bus for a particular device (whether it is high or low depends on the device). It is used when you have multiple SPI devices on the same bus to tell one device the data is meant for that device;
  • DC -- this pin is optional on some devices. It allows you to tell the device whether the device should be in data or command mode. Typically there is a way to not use the DC bit, and to have a command to switch between modes;
  • Reset -- this pin is used to reset the device. Some devices have a reset pin, some don't.

Now to get further in the weeds, a few device drivers have special optimizations if you use CS and DC from a restricted set of pins on the first SPI bus. The SSD1306 is one of these devices, but if you select other pins, it should still work, it might not be as fast as it could be. The restricted pins are:
  • Pins 9, 10, 15/AC1, 20/AC6, and 21/AC7;
  • You don't want to use pins 2, 6, 22/AC8, or 23/AC9 for SPI if you are using the other pins, as it actually overlaps (i.e. you can use either pin 2 or pin 10, but you can't use both).
 
Last edited:
Hello Michael,

Wow, thanks for the detailed answer and your effort. Very much appreciated!


So if i rewire like in the code below it works also, but should be in "hardware mode" now?
Is this correct?



Code:
//#include <SPI.h>
//#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Teensy 3.1 hardware SPI:
#define OLED_MOSI  11 		// = DOUT = Display SDA
#define OLED_CLK   14		// = SCK  = Display SCL
#define OLED_DC     9		//        = Display DC
#define OLED_CS    10		//        = Display CS
#define OLED_RESET 15		//        = Display RES
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

One last question.
Why are some labels greyed out on the "Getting started" card??

Thanks! :)
 
Hello Michael,

Wow, thanks for the detailed answer and your effort. Very much appreciated!


So if i rewire like in the code below it works also, but should be in "hardware mode" now?
Is this correct?



Code:
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

In order to use the hardware SPI interface, you need to use the constructor that does not take the MOSI/CLK arguments, i.e.:

Code:
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);

One last question.
Why are some labels greyed out on the "Getting started" card??

Thanks! :)

If by greyed out you mean in a reduced font, those are the alternate pins. For example:
  • pin 7 is the alternate pin for MOSI/DOUT (instead of 11);
  • pin 8 is the alternate pin for MISO/DIN (instead of 12);
  • pin 14/AC0 is the alternate pin for SCLK/SCK (instead of 13).

The SPI documentation (https://www.pjrc.com/teensy/td_libs_SPI.html) has a section on using the alternate pins.
 
One last question.
Why are some labels greyed out on the "Getting started" card??

With The Teensy most pins can be configured to do several different things (example pin 10 can be a simple digital pin, could be the Transmit pin for Serial2, can be a Chip select pin for SPI and can be PWM...)

With this many of the specific functions can be configured to be handled by a few different IO pins.
Example for SPI on the T3.2/1 you can configure SPI to have the Clock pin on either pin 13 or Pin 14. The default is 13, which is why it's text is shown not grayed. Where as pin 14 is gray as it is not the default pin to do this function.

If in this example you wish to use pin 14 instead of pin 13, you would add a call to: SPI.setSCK(14);
Which tells the system to use pin 14 for this function...

Assuming you wisth to use pin 14 instead of 13, I would change your code to be more like:
Code:
//#include <SPI.h>
//#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Teensy 3.1 hardware SPI:
#define OLED_MOSI  11 		// = DOUT = Display SDA
#define OLED_CLK   14		// = SCK  = Display SCL
#define OLED_DC     9		//        = Display DC
#define OLED_CS    10		//        = Display CS
#define OLED_RESET 15		//        = Display RES
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
...
void setup() {
...
    SPI.setSCK(14);
    display.begin(SSD1306_SWITCHCAPVCC);  // Not sure if this is correct parameter but is in one of the examples
...
 
@All

I changed my code as seen below, and it works also.
Which opens even some more questions to me.

Why can i comment out #include <SPI.h> and #include <Wire.h> and it still works?


@Michael

If the constructor does not take MOSI and CLK arguments (i can comment them even out) how can that even work?
I mean SCK and DOUT are not even defined. (Okay SCK IS defined with SPI.setSCK(14); i guess)

@KurtE

I used display.begin(SSD1306_SWITCHCAPVCC, 0x3C); before which works but also your version display.begin(SSD1306_SWITCHCAPVCC); works.


Code:
//#include <SPI.h>
//#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Teensy 3.1 hardware SPI:
//#define OLED_MOSI  11 	// = DOUT = Display SDA
//#define OLED_CLK   14         // = SCK  = Display SCL
#define OLED_DC     9		//        = Display DC
#define OLED_CS    10		//        = Display CS
#define OLED_RESET 15	//        = Display RES
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
//Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);


void setup() {
	SPI.setSCK(14);
	display.begin(SSD1306_SWITCHCAPVCC);
	//display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

Thanks! :)

PS: I dont want to use Pin 13 since the LED would be always ON.
 
Last edited:
Why you can comment out SPI.h and it still works...

Over the last few years, the Arduino compiler has gotten better, to not necessarily need all of the header files used by libraries to be included by the main INO file... But I still do just in case.

Note: The begin call I put in previous one came from the examples that were included with the Teensyduino version of that library. Which one you need, maybe depends on your display...

Edit: As for not needing/wanting the MOSI/CLK arguments to be defined.

That is because that library has a constructor that when you use that form, implies that you are using hardware SPI. And SPI knows which pins are to be used for (MOSI, MISO, SCK)...
 
@Michael

If the constructor does not take MOSI and CLK arguments (i can comment them even out) how can that even work?
I mean SCK and DOUT are not even defined. (Okay SCK IS defined with SPI.setSCK(14); i guess)

As I said, there are two methods. The first method is the slow method where it does the SPI bus transactions by sending each bit down the wire by toggling MOSI and SCLK, then doing a busy wait for the timeout, then sending the next bit.

The second method uses the hardware SPI where the SPI library set things up, and the hardware does most of the SPI bit-banging on its own. If you do that, you must use the dedicated (MOSI, MISO, and SCLK) pins that may be different on different hardware platforms. The Teensy generally uses the pin conventions of the Arduino Uno for things like SPI and I2C.

And if you use the dedicated pins for CS/DC, it will do more of the transfer by setting up internal DMA (direct memory access) tables.

PS: I dont want to use Pin 13 since the LED would be always ON.
Your choice, but that's what the Uno used for its default SPI configuration. It is harmless in that MOSI is only used to write data, so it blinks (really fast) as data goes through it. If it had been MISO (the input line), it would have been different since the resistor on the LED might have interfered with reading the pin status.
 
Okay, now i understand the topic a lot better.

One last question.

If i use Pin 14 for SCK instead of the default Pin 13.
Will this still be hardware SPI then ? (Since i use the command SPI.setSCK(14);)
 
Okay, now i understand the topic a lot better.

One last question.

If i use Pin 14 for SCK instead of the default Pin 13.
Will this still be hardware SPI then ? (Since i use the command SPI.setSCK(14);)

Yes, either of the 13 and 14 pins can be the SCLK pin, when you use the setSCK function.
 
This was a very helpful thread and I'm only reviving it because I banged my head against a related issue.
I have a SPI OLED and had assigned teensy (LC) pins 0 and 1 to the RST and D/C pins of my display. No joy in mudville. When I changed these to pins 20 and 21 things worked. (And indeed the SPI in hardware mode is much zippier than i2c).

I'm curious to learn why pin 0 and 1 failed at this task. Presumably something to do with Serial?

Thanks again for this very-helpful thread.
 
...
I'm curious to learn why pin 0 and 1 failed at this task. Presumably something to do with Serial?
...

Not sure? USB Serial is Native on unique pins so not related to that - like on an UNO. T_LC:: Unless Serial1 is made active those pins #0/#1 should have no problem as long as they are usable as digital pins like RST & D/C should be? #20/#21 are (#20PWM)/Analog capable and not Touch -

What SPI OLED ? What library?
 
This is the SPI OLED: https://www.amazon.com/gp/product/B087CW1YLK.
I'm using the Adafruit_SSD1306 library version 2.2.1.
I'm building in Serial + MIDI mode (which might be related?)

Littering the code with printlns, I found that when using the pins 0 and 1 the library would hang in display.begin() around here:

Code:
  // Serial.println("display begin 5 done reset");
  TRANSACTION_START

  // Init sequence
  static const uint8_t PROGMEM init1[] = {
    SSD1306_DISPLAYOFF,                   // 0xAE
    SSD1306_SETDISPLAYCLOCKDIV,           // 0xD5
    0x80,                                 // the suggested ratio 0x80
    SSD1306_SETMULTIPLEX };               // 0xA8
  // Serial.println("display 5 init sequence a"); // << last message
  ssd1306_commandList(init1, sizeof(init1));
 
This post is a duplicate of :: pjrc.com/threads/63190-pins-for-the-teensy3-6-and-teensy4-0-1-Data-Command-alternatives

Hello engineers,

could someone tell me which alternative pins can be used for the Data/Command lines?

I tried in my previous MAX31855 post pin 9 and pin 10, swapped them and the display still freezes over.

is there an alternative pin to this DC pin?or how to switch between Data and Command? because Data will be used for the MAX31855? and Command for the TFT?

thanks for your help and reading.

Bastiaan
 
Last edited by a moderator:
Status
Not open for further replies.
Back
Top