Help connecting OLED displays

Status
Not open for further replies.

magma

Member
I have bought two of these.

41bvWaXzBqL._SX466_.jpg
1.5inch-rgb-oled-module-3.jpg

and I was planning to use them connected to a T3.6.

So my first question is, is this possible?

I cannot find any tutorial or forum thread, explaining how to connect at least one of this displays to Teensy.
Could anyone point me some direction?

I am fine connecting wires and messing with libraries, but I am no electrician neither software developer, so I apologize for beeing such a noob.
 
My assumption is you should be able to connect one up.

It uses SPI interface. So could hook it up to one of the SPI busses on the T3.6.

There are probably multiple libraries that support this. For example you might want to look at:
https://github.com/sumotoy/SSD_13XX
 
Did the seller of these products give you any tech info? Even just knowing which controller chip is inside the display will save a lot of guesswork.
 
Thank you so much for helping me on this.

@Paul yes the driver is SSD1351

@KurtE thanks for pointing this library.

My quest now is what to connect where.. looking at the connections on the SSD_13XX Github page

RST connected to 3v3 with 4k7 -> 10k resistor (I am using one 10k)

SCL, SCLD -> SCLK --- it is the CLK on the OLED -----> I suppose will connect to pin 13 ?

SDA, SDIN -> MOSI --- it is the DIN on the OLED ------> I suppose will connect to pin 11 ?

DC, RS -> DC pin on MCU --- DC on the OLED ------> ???

there is still the CS on the OLED, should this be connected?


This is my head right now.... :)
Screen-Shot-2018-09-01-at-22.12.28.jpg
 

Attachments

  • Screen-Shot-2018-09-01-at-22.05.34.jpg
    Screen-Shot-2018-09-01-at-22.05.34.jpg
    156.2 KB · Views: 98
Last edited:
I have not seen the full specs for your chip to know if it IO pins support 3.3v, but I am assuing that it does. As it also talked about connecting to Raspberry PI.

I am assuming by default configured for 4 pin SPI and not 3 pin... It mentioned about resister jumper...

Code:
RST connected to 3v3 with 4k7 -> 10k resistor (I am using one 10k)

SCL, SCLD -> SCLK --- it is the CLK on the OLED -----> I suppose will connect to pin 13 ?

SDA, SDIN -> MOSI --- it is the DIN on the OLED ------> I suppose will connect to pin 11 ?

DC, RS -> DC pin on MCU --- DC on the OLED ------> ???

there is still the CS on the OLED, should this be connected?
My assumptions from the picture at the back of your display.
VCC -> 3.3v
GND -> GND
DIN -> 11 (MOSI)
CLK -> 13 (SCLK)
Reset - Not sure, but some times on some displays, I had better hardware luck when I used an IO pin and specified it...

CS - Chip select - Needed to tell board that the SPI communication is for this display
DC - Data/Command - Needed to tell board that the SPI bytes are commands or data...

To get decent speed on these displays, these should both be Hardware CS pins and not the same logical Hardware CS channel... That is, the hardware CS pins on SPI object are:
(10, 2, 26),( 9, 6), (20, 23), (21, 22), 15, 45,

Again should be two of the above pins, but the two can not both be from the same () set.
 
I've hooked those two displays up to a Teensy 3.5, and 3.6. I tend to use the Adafruit uncanny eyes program rather than the standard library.

I've discovered that if you are blasting data out to the screens (like uncanny eyes does) using the DMA CS/DC pins, you want to set the SPI bus speed to 18Mhz or slower. By comparison, the Adafruit OLED displays can only run at 11Mhz. I find I can no longer drive the OLED displays from a Teensy 3.2, without getting screen corruption no matter what CPU or spi bus speed I used.

On the uncanny eyes program, you can share the D/C pin and the reset pin, but the CS pin must be different. If you are using other software, you may need to check if it uses SPI transactions, and whether it waits for the DMA to drain on the first screen before switching to the second.

I had bad luck with the wavelan displays. I had one display go bad on me (I suspect I connected ground or power to the wrong pin by accident, and I messed up another with bad soldering. I eventually went back to the Adafruit displays.
 
KurtE and Michael thanks so much for the information!
I'm going to digest all the info and post the updates..
 
I tried the connections with both screens and they don't give any life signal.. also tried on a Teensy 3.2 and it's the same...

I am using a predefined output pin for the reset.

Do you think I am doing something wrong or missing something?

IMG_7305.jpg
 
You might try posting what software you used and what actual pins you used. Note, I didn't use a resistor when I did mine. Unfortunately, I am away from home right now. I will back for one day on Tuesday, and then go away again until the next Tuesday, so I probably won't be able to try anything on my remaining OLED (I think I still have one floating around).
 
I am using the pins defined by the lybrary

MOSI: 11
MISO: 12
SCK: 13
CS: 10
DC: 9
RST: 6 (tried with and without resistor)

The program I am using is called 'basicSetup', it prints on the console: "serial ok, testing lib..." but nothing appears on the screen

Code:
#include <SPI.h>
#include <SSD_13XX.h>

/*
Teensy3.x and Arduino's
You are using 4 wire SPI here, so:
MOSI:  11//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
MISO:  12//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
SCK:   13//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
ESP8266-----------------------------------
Use:
#define __CS  16  //(D0)
#define __DC  5   //(D1)
#define __RST 4   //(D2)

SCLK:D5
MOSI:D7
*/
#define __CS1 	10
#define __DC 	9
/*
Teensy 3.x can use: 2,6,10,15,20,21,22,23
Arduino's 8 bit: any
DUE: check arduino site
If you do not use reset, tie it to +3V3
*/

uint8_t errorCode = 0;

SSD_13XX tft = SSD_13XX(__CS1, __DC);

void setup() {
	Serial.begin(38400);
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);
	long unsigned debug_start = millis();
	while (!Serial && ((millis() - debug_start) <= 5000));
	Serial.println("serial ok, testing lib...");
	tft.begin();
	//the following it's mainly for Teensy
	//it will help you to understand if you have choosed the
	//wrong combination of pins!
	errorCode = tft.getErrorCode();
	if (errorCode != 0) {
		Serial.print("Init error! ");
		if (bitRead(errorCode, 0)) Serial.print("MOSI or SCLK pin mismach!\n");
		if (bitRead(errorCode, 1)) Serial.print("CS or DC pin mismach!\n");
	}
	else {
		tft.print("Ready!");
	}
}


void loop(void) {

}
 
As for Reset pin, I would not try handling it myself, but instead let the library handle it. I believe the constructor you are using allows a third parameter which is the reset pin.

Also did you follow the instructions in the github readme?

That mentions:
Uncomment in settings file: #include "../_display/SSD_1351_128x128.h"
 
As for Reset pin, I would not try handling it myself, but instead let the library handle it. I believe the constructor you are using allows a third parameter which is the reset pin.

Also did you follow the instructions in the github readme?


OMG it's working!! :D

I haven't followed the instructions to change the settings file, and added a 3rd parameter for the reset pin.

I've been struggling with this for days, can't thank you enough to all of you!!
 
Hello Magma,

I'm also using one of these waveshare Oled's on a Teensy 3.6.
I also use the Lib from Sumotoy.
What I found is that I have to select max 96MHz for Clockspeed of the T3.6 to keep it working.
In my case I connect the RST simply to the 3V3 of the Teensy and it works with that. Ofcourse in my case only single Oled screen.

Foto later tonight, I'm at work right now.

Regards, Otto
 
Hello Magma,

I'm also using one of these waveshare Oled's on a Teensy 3.6.
I also use the Lib from Sumotoy.
What I found is that I have to select max 96MHz for Clockspeed of the T3.6 to keep it working.
In my case I connect the RST simply to the 3V3 of the Teensy and it works with that. Ofcourse in my case only single Oled screen.

Foto later tonight, I'm at work right now.

Regards, Otto

In my testing, I found I needed to lower the SPI bus speed to 11Mhz to keep my Wavelan displays running on Teensy 3.5 at higher processor clock rates. It should apply to the Teensy 3.6 as well (in the past when I was investigating the SPI bus speeds for the Adafruit displays, I used a Teensy 3.6, but I'm currently using a 3.5 -- I will likely switch back to a 3.6 when I get back to doing Teensy projects). The displays just can't handle data coming to them too fast. For whatever reason, the Adafruit display seems to need the SPI bus speed reduced even further.

I don't use the Sumotoy libraries, but I poked around a bit. If you go into the file _includes/_cpuCommons.h, lines 42 through 49 are:

Code:
#elif defined(__MKL26Z64__)	|| defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
		//#include <avr/pgmspace.h>
		//#define _FORCE_PROGMEM__
		#define _smCharType	unsigned char
		static const uint32_t _common_max_SPI_speed 		= 30000000;
		#if !defined(__MKL26Z64__)
			#define _SPI_MULTITRANSFER	//enable burst multy byte transfer  
               #endif

Change the _common_max_SPI_speed value to 11000000 (or 8000000 if you plan to use the Adafruit displays):

Code:
#elif defined(__MKL26Z64__)	|| defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
		//#include <avr/pgmspace.h>
		//#define _FORCE_PROGMEM__
		#define _smCharType	unsigned char
		[COLOR="#FF0000"]static const uint32_t _common_max_SPI_speed 		= 11000000;[/COLOR]
		#if !defined(__MKL26Z64__)
			#define _SPI_MULTITRANSFER	//enable burst multy byte transfer  
               #endif

It is a shame that sumotoy seems to have disappeared/died/etc. two years ago.
 
Hello,

here my setup, it's a small GPS system for the car/bike. This is version 2, version one had a ssd1306 128x64 SPI Oled.
This time I wanted a bit more real estate and went for this screen. Happy I got it finally working.

This is the program, I guess because of my short wiring it works. Happily running @:
Setting.jpg

Code:
#include <SPI.h>
#include <SSD_13XX.h>



/*
Teensy3.x and Arduino's
You are using 4 wire SPI here, so:
 MOSI:  11//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
 MISO:  12//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
 SCK:   13//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
 the rest of pin below:
 */
#define __CS1 	10
#define __DC 	9
/*
Teensy 3.x can use: 2,6,10,15,20,21,22,23
Arduino's 8 bit: anY
DUE: check arduino site
If you do not use reset, tie it to +3V3
ESP8266-----------------------------------
Use:
#define __CS  16  //(D0)
#define __DC  5   //(D1)
#define __RST 4   //(D2)

 SCLK:D5
 MOSI:D7
*/



SSD_13XX tft = SSD_13XX(__CS1, __DC);


float p = 3.1415926;



void testlines(uint16_t color) {
	tft.clearScreen();
	for (int16_t x = 0; x < tft.width() - 1; x += 6) {
		tft.drawLine(0, 0, x, tft.height() - 1, color);
	}
	for (int16_t y = 0; y < tft.height() - 1; y += 6) {
		tft.drawLine(0, 0, tft.width() - 1, y, color);
	}
	tft.clearScreen();
	for (int16_t x = 0; x < tft.width() - 1; x += 6) {
		tft.drawLine(tft.width() - 1, 0, x, tft.height() - 1, color);
	}
	for (int16_t y = 0; y < tft.height() - 1; y += 6) {
		tft.drawLine(tft.width() - 1, 0, 0, y, color);
	}

	tft.clearScreen();
	for (int16_t x = 0; x < tft.width() - 1; x += 6) {
		tft.drawLine(0, tft.height() - 1, x, 0, color);
	}
	for (int16_t y = 0; y < tft.height() - 1; y += 6) {
		tft.drawLine(0, tft.height() - 1, tft.width() - 1, y, color);
	}
	tft.clearScreen();
	for (int16_t x = 0; x < tft.width() - 1; x += 6) {
		tft.drawLine(tft.width() - 1, tft.height() - 1, x, 0, color);
	}
	for (int16_t y = 0; y < tft.height() - 1; y += 6) {
		tft.drawLine(tft.width() - 1, tft.height() - 1, 0, y, color);
	}
	delay(500);
}


void testdrawtext(char *text, uint16_t color) {
	tft.setTextScale(1);
	tft.setTextColor(WHITE);
	tft.setCursor(0, 0);

	for (uint8_t i = 0; i < 168; i++) {
		if (i == '\n') continue;
		tft.write(i);
		if ((i > 0) && (i % 21 == 0))
			tft.println();
	}
}

void testfastlines(uint16_t color1, uint16_t color2) {
	tft.clearScreen();
	for (int16_t y = 0; y < tft.height() - 1; y += 5) {
		tft.drawFastHLine(0, y, tft.width() - 1, color1);
	}
	for (int16_t x = 0; x < tft.width() - 1; x += 5) {
		tft.drawFastVLine(x, 0, tft.height() - 1, color2);
	}
}

void testdrawrects(uint16_t color) {
	tft.clearScreen();
	for (int16_t x = 0; x < tft.height() - 1; x += 6) {
		tft.drawRect((tft.width() - 1) / 2 - x / 2, (tft.height() - 1) / 2 - x / 2, x, x, color);
	}
}

void testfillrects(uint16_t color1, uint16_t color2) {
	tft.clearScreen();
	for (int16_t x = tft.height() - 1; x > 6; x -= 6) {
		tft.fillRect((tft.width() - 1) / 2 - x / 2, (tft.height() - 1) / 2 - x / 2, x, x, color1);
		tft.drawRect((tft.width() - 1) / 2 - x / 2, (tft.height() - 1) / 2 - x / 2, x, x, color2);
	}
}

void testfillcircles(uint8_t radius, uint16_t color) {
	for (uint8_t x = radius; x < tft.width() - 1; x += radius * 2) {
		for (uint8_t y = radius; y < tft.height() - 1; y += radius * 2) {
			tft.fillCircle(x, y, radius, color);
		}
	}
}

void testdrawcircles(uint8_t radius, uint16_t color) {
	for (int16_t x = 0; x < (tft.width() - 1) + radius; x += radius * 2) {
		for (int16_t y = 0; y < (tft.height()) - 1 + radius; y += radius * 2) {
			tft.drawCircle(x, y, radius, color);
		}
	}
}

void testtriangles() {
	tft.clearScreen();
	int color = 0xF800;
	int t;
	int w = tft.width() / 2;
	int x = tft.height();
	int y = 0;
	int z = tft.width();
	for (t = 0; t <= 15; t += 1) {
		tft.drawTriangle(w, y, y, x, z, x, color);
		x -= 4;
		y += 4;
		z -= 4;
		color += 100;
	}
}

void testroundrects() {
	tft.clearScreen();
	int color = 100;
	int i;
	int t;
	for (t = 0; t <= 4; t += 1) {
		int x = 0;
		int y = 0;
		int w = tft.width();
		int h = tft.height();
		for (i = 0; i <= 24; i += 1) {
			tft.drawRoundRect(x, y, w, h, 5, color);
			x += 2;
			y += 3;
			w -= 4;
			h -= 6;
			color += 1100;
		}
		color += 100;
	}
}

void tftPrintTest() {
	tft.clearScreen();
	tft.setCursor(0, 5);
	tft.setTextColor(RED);
	tft.setTextScale(1);
	tft.println("Hello World!");
	tft.setTextColor(YELLOW, GREEN);
	tft.setTextScale(2);
	tft.print("Hello Wo");
	tft.setTextColor(BLUE);
	tft.setTextScale(3);
	tft.print(12.57);
	delay(1500);
	tft.setCursor(0, 5);
	tft.clearScreen();
	tft.setTextColor(WHITE);
	tft.setTextScale(0);
	tft.println("Hello World!");
	tft.setTextScale(1);
	tft.setTextColor(GREEN);
	tft.print(p, 5);
	tft.println(" Want pi?");
	tft.print(8675309, HEX);
	tft.print(" Print HEX");
	tft.setTextColor(WHITE);
	tft.println("Sketch has been");
	tft.println("running for: ");
	tft.setTextColor(MAGENTA);
	tft.print(millis() / 1000);
	tft.setTextColor(WHITE);
	tft.print(" sec.");
}


void randomRect(bool fill) {
	tft.clearScreen();
	uint8_t k, c;
	for (k = 0; k < 16; k++) {
		for (c = 0; c < 32; c++) {
			uint8_t cx, cy, x, y, w, h;
			//  center
			cx = random(0, tft.width());
			cy = random(0, tft.height());
			//  size
			w = random(0, 30 + 6);
			h = random(0, 20 + 4);
			//  upper-left
			x = cx - w / 2;
			y = cy - h / 2;
			if (x < 0) x = 0;
			if (y < 0) y = 0;
			//  adjust size
			if (x + w > tft.width()) w = tft.width() - x;
			if (y + h > tft.height()) h = tft.height() - y;
			if (fill) {
				tft.fillRect(x, y, w, h, random(0x0010, 0xFFFF));
			}
			else {
				tft.drawRect(x, y, w, h, random(0x0010, 0xFFFF));
			}

		}
		tft.clearScreen();
	}
}

void randomCircles(bool fill) {
	tft.clearScreen();
	uint8_t k, c;
	for (k = 0; k < tft.height(); k++) {
		for (c = 0; c < tft.height() / 2; c++) {
			//  coordinates
			uint8_t x = random(0, 120 + 3), y = random(0, 90 + 2), r = random(0, 40 + 1);
			if (x - r <  0) r = x;
			if (x + r >(tft.width() - 1)) r = (tft.width() - 1) - x;
			if (y - r <  0) r = y;
			if (y + r >(tft.height() - 1)) r = (tft.height() - 1) - y;
			if (fill) {
				tft.fillCircle(x, y, r, random(0x0010, 0xFFFF));
			}
			else {
				tft.drawCircle(x, y, r, random(0x0010, 0xFFFF));
			}
		}
		if (!fill)tft.clearScreen();
	}
}


void randomLines() {
	tft.clearScreen();
	uint8_t k, c;
	for (k = 0; k < tft.height(); k++) {
		for (c = 0; c < tft.height() / 2; c++) {
			uint8_t x1 = random(0, tft.width()), y1 = random(0, tft.height()), x2 = random(0, tft.width()), y2 = random(0, tft.height());
			tft.drawLine(x1, y1, x2, y2, random(0x0010, 0xFFFF));
		}
		tft.clearScreen();
	}
}


void randomPoints() {
	tft.clearScreen();
	int k, c;
	for (k = 0; k < 128; k++) {
		for (c = 0; c < 1000; c++) {
			uint8_t x = random(0, tft.width()), y = random(0, tft.height());
			tft.drawPixel(x, y, random(0x0010, 0xFFFF));
		}
		tft.clearScreen();
	}
}

void setup(void) {
  tft.begin();
  SPI.beginTransaction(SPISettings(1200000, MSBFIRST, SPI_MODE0));

  uint16_t time = millis();
  time = millis() - time;

//  lcdTestPattern();
//  delay(1000);

  tft.clearScreen();
  tft.setCursor(0,0);
  tft.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa");
  delay(1000);

  tftPrintTest();
  delay(2000);

  //a single pixel
  tft.drawPixel(tft.width()/2, tft.height()/2, GREEN);
  delay(500);

  // line draw test
  testlines(YELLOW);
  delay(500);    

  // optimized lines
  testfastlines(RED, BLUE);
  delay(500);    

  testdrawrects(GREEN);
  delay(1000);

  testfillrects(BLUE, YELLOW);
  delay(1000);

  randomRect(0);
  delay(100);
  randomCircles(0);
  delay(100);
  randomLines();
  delay(100);
  randomPoints();
  delay(500);
  
  tft.clearScreen();
  testfillcircles(10, BLUE);
  testdrawcircles(10, WHITE);
  delay(1000);

  testroundrects();
  delay(500);

  testtriangles();
  delay(500);

}

void loop() {
  testlines(random(0x0010,0xFFFF));
  randomLines();
  //randomCircles(1);
  randomCircles(0);
  randomRect(1);
  randomRect(1);
  randomRect(1);
  randomRect(1);
  randomRect(1);
  randomRect(0);
  randomRect(0);
  randomRect(0);
  randomRect(0);
  randomRect(0);
  randomRect(0);
  randomPoints();
}


gps-s.jpg

Regards, from Belgium, Otto
 
Last edited:
Status
Not open for further replies.
Back
Top