Interfacing Arduino with SSD1331 Color OLED Display
Interfacing Arduino with SSD1331 Color OLED Display
Adding a display to an electronic circuit can significantly enhance the functionality, usability, and overall user experience of the electronic project. Whether it’s a simple LCD, an OLED display, or a TFT screen, displays provide visual feedback and interaction capabilities between the circuit and human that are essential for many applications.
As an addition to the above, adding a display to an electronic circuit can help solve project code issues.
This Arduino tutorial shows how to interface Arduino UNO board with SSD1331 color OLED display module that has a size of 0.95-inch and resolution of 96×64 pixel.
The example shows how to print texts and draw shapes (circles, rectangular…) on the SSD1331 OLED display.
Abbreviations:
LCD: Liquid Crystal Display.
OLED: Organic light Emitting Diode.
PLED: Polymer OLED.
TFT: Thin Film Transistor.
SPI: Serial Peripheral Interface.
IoT: Internet of things.
The SSD1331 Color OLED Display Module:
The SSD1331 is a popular OLED/PLED display controller chip commonly used in small colored OLED displays. It supports a maximum resolution of 96×64 pixels and can drive RGB (Red, Green, Blue) OLED panels.
The SSD1331 OLED display module is a compact, color OLED display module that uses the SSD1331 controller. It typically has a resolution of 96×64 pixels and supports 16-bit color (65K colors).
The SSD1331 color OLED display is often used in applications where small, low-power displays are required.
The SSD1331 OLED display module used in this project is the one below:
The SSD1331 display shown above works with SPI interface mode and has 7 pins. Below is the pinout for the display module, which is essential for connecting it to a microcontroller like Arduino, ESP32, Raspberry Pi, or Microchip PIC.
- GND: Ground pin, connected to circuit common ground.
- VCC: Power supply pin, may be 3.3V or 5V (refer to your display datasheet for power supply voltage range, some modules works only with 3.3V).
- SCL: Serial clock pin for the SPI interface. Connected to the SPI clock pin (SCK) of the microcontroller.
- SDA: Serial data pin for the SPI interface. Connected to the SPI data pin (MOSI) of the microcontroller.
- RES: Reset pin. Used to reset the display. If used, it is connected to any general purpose output pin of the microcontroller.
- DC: Data/Command selection pin. Connected to a digital output pin on the microcontroller. It determines whether the data on the bus is a command or actual pixel data.
- CS: Chip Select pin (active low). Connected to a digital pin on the microcontroller. Used to enable or disable the communication with the SSD1331 OLED display.
Interfacing Arduino with SSD1331 Color OLED Display:
This post shows how to interface Arduino board with SSD1331 OLED display. Circuit diagram is shown below.
The SSD1331 color OLED display module shown in project wiring diagram has 7 pins: (from left to right): GND (ground), VCC, SCL (serial clock), SDA (serial data), RES (reset), DC (data/command), and CS (chip select).
Hardware Required:
Required parts are listed below.
- Arduino UNO (or similar) board —> Board details
- SSD1331 OLED display module
- 5 x 2k ohm resistor
- 5 x 1k ohm resistor
- Breadboard
- Jumper wires
Since the SSD1331 OLED display operates at 3.3V logic level and the Arduino uno board at 5V, I used a resistive voltage divider to reduce the 5V output of the Arduino to about 3.3V.
The resistive voltage divider may be the simplest method, but other more efficient ways can be used such as using logic level shifters.
As we have 5 data lines between the Arduino board and the SSD1331 display there are also 5 resistive voltage divider where each one is implemented with two resistors of 1k and 2k.
Connecting a 5V microcontroller directly to the SSD1331 OLED display violates the electrical characteristics written in the display datasheet and may damage the controller circuit of the display.
The SSD1331 display module is supplied with 3.3V from the Arduino board where:
- GND pin of the SSD1331 display is connected to GND pin of the Arduino board, and
- VCC pin of the display is connected to pin 3.3V of the Arduino board.
Other pins are connected as follows (each one through voltage divider):
- SCL pin is connected to Arduino digital pin 13.
- SDA pin is connected to Arduino digital pin 11.
- RES pin is connected to Arduino digital pin 8.
- DC pin is connected to Arduino digital pin 9.
- CS pin is connected to Arduino digital pin 10.
Note that pins 13 and 11 of the Arduino uno and similar boards are hardware SPI pins of the ATmega328P microcontroller, for SCK (Serial Clock) and MOSI (Master-Out Slave-In), respectively.
Interfacing Arduino with SSD1331 Color OLED Display Code:
Project Arduino code is just an example of graphics test provided by Adafruit Industries, with some modifications.
To be able to compile project Arduino code, two libraries from Adafruit Industries are required:
The first library is a driver for the SSD1331 OLED display and it can be installed from Arduino IDE library manager (Sketch —> Include Library —> Manage Libraries…, in the search box write “ssd1331” and install the one from Adafruit).
The second library is Adafruit graphics library which can be installed also from Arduino IDE library manager.
During the installation of the Adafruit SSD1331 display library, Arduino IDE may ask for installing some other libraries form Adafruit Industries (dependencies).
Project code was tested with the following library versions:
Adafruit GFX Library: Version 1.11.11.
Adafruit SSD1331 OLED driver: Version 1.2.2.
Adafruit BusIO: Version 1.17.0.
The used libraries are included in the Arduino code as shown below:
1
2
3
|
#include <Adafruit_GFX.h> // Adafruit Graphics library
#include <Adafruit_SSD1331.h> // Adafruit SSD1331 display driver
#include <SPI.h> // Arduino SPI library
|
The connection between the SSD1331 display and the Arduino board is as shown in the above wiring diagram, it is defined in the Arduino code as shown below:
1
2
3
4
|
// Connection between Arduino and SSD1331 display
#define CS_PIN 10 // Chip select pin
#define DC_PIN 9 // Data/Command pin
#define RST_PIN 8 // Or set to -1 and connect to board RESET pin
|
The SSD1331 OLED is library is initialized with the previous defined connections and hardware SPI pins:
1
|
Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, CS_PIN, DC_PIN, RST_PIN);
|
The SSD1331 OLED display must be initialized before any print operation, if the initialization failed then the display will show only black screen. The initialization function of the display is the one below:
1
|
display.begin();
|
For more details about Arduino SPI communication, see the following page:
Arduino & Serial Peripheral Interface (SPI)
Rest of code is described through comments.
Full Arduino code:
Project Arduino code is below. Use the following URL to browse the code on GitHub:
Arduino-SSD1331-OLED
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
|
/*****************************************************************
* Interfacing Arduino with SSD1331 color display (96×64 pixel).
* This is a free software with NO WARRANTY.
* https://simple-circuit.com/
/*****************************************************************/
#include <Adafruit_GFX.h> // Adafruit Graphics library
#include <Adafruit_SSD1331.h> // Adafruit SSD1331 display driver
#include <SPI.h> // Arduino SPI library
// Connection between Arduino and SSD1331 display
#define CS_PIN 10 // Chip select pin
#define DC_PIN 9 // Data/Command pin
#define RST_PIN 8 // Or set to -1 and connect to board RESET pin
// Option 1: Hardware SPI pins must be used (for UNO SCLK = 13 and MOSI = 11)
Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, CS_PIN, DC_PIN, RST_PIN);
// Option 2: Software SPI, comment the above line and uncomment the below lines, slower than hardware SPI
/*
#define SCLK_PIN 13 // Clock pin
#define MOSI_PIN 11 // Master-Out Slave-In pin
Adafruit_SSD1331 display = Adafruit_SSD1331(CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN);
*/
// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
float p = 3.1415926;
#define NUMFLAKES 10 // Number of snowflakes in the animation example
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
0b00000001, 0b11000000,
0b00000001, 0b11000000,
0b00000011, 0b11100000,
0b11110011, 0b11100000,
0b11111110, 0b11111000,
0b01111110, 0b11111111,
0b00110011, 0b10011111,
0b00011111, 0b11111100,
0b00001101, 0b01110000,
0b00011011, 0b10100000,
0b00111111, 0b11100000,
0b00111111, 0b11110000,
0b01111100, 0b11110000,
0b01110000, 0b01110000,
0b00000000, 0b00110000 };
void setup(void) {
Serial.begin(9600);
display.begin();
Serial.println(“init”);
uint16_t time = millis();
display.fillScreen(BLACK);
time = millis() – time;
Serial.println(time, DEC);
delay(500);
lcdTestPattern();
delay(2000);
display.fillScreen(BLACK);
display.setCursor(0,0);
display.print(“Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa”);
delay(2000);
// tft print function!
tftPrintTest();
delay(4000);
//a single pixel
display.drawPixel(display.width()/2, display.height()/2, GREEN);
delay(500);
// line draw test
testlines(YELLOW);
delay(500);
// optimized lines
testfastlines(RED, BLUE);
delay(500);
testdrawrects(GREEN);
delay(1000);
testfillrects(YELLOW, MAGENTA);
delay(1000);
display.fillScreen(BLACK);
testfillcircles(10, BLUE);
testdrawcircles(10, WHITE);
delay(1000);
testroundrects();
delay(500);
testtriangles();
Serial.println(“done”);
delay(2000);
testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
}
void loop() {
}
void testlines(uint16_t color) {
display.fillScreen(BLACK);
for (int16_t x=0; x < display.width()–1; x+=6) {
display.drawLine(0, 0, x, display.height()–1, color);
}
for (int16_t y=0; y < display.height()–1; y+=6) {
display.drawLine(0, 0, display.width()–1, y, color);
}
display.fillScreen(BLACK);
for (int16_t x=0; x < display.width()–1; x+=6) {
display.drawLine(display.width()–1, 0, x, display.height()–1, color);
}
for (int16_t y=0; y < display.height()–1; y+=6) {
display.drawLine(display.width()–1, 0, 0, y, color);
}
// To avoid ESP8266 watchdog timer resets when not using the hardware SPI pins
delay(0);
display.fillScreen(BLACK);
for (int16_t x=0; x < display.width()–1; x+=6) {
display.drawLine(0, display.height()–1, x, 0, color);
}
for (int16_t y=0; y < display.height()–1; y+=6) {
display.drawLine(0, display.height()–1, display.width()–1, y, color);
}
display.fillScreen(BLACK);
for (int16_t x=0; x < display.width()–1; x+=6) {
display.drawLine(display.width()–1, display.height()–1, x, 0, color);
}
for (int16_t y=0; y < display.height()–1; y+=6) {
display.drawLine(display.width()–1, display.height()–1, 0, y, color);
}
}
void testdrawtext(char *text, uint16_t color) {
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
for (uint8_t i=0; i < 168; i++) {
if (i == ‘\n’) continue;
display.write(i);
if ((i > 0) && (i % 21 == 0))
display.println();
}
}
void testfastlines(uint16_t color1, uint16_t color2) {
display.fillScreen(BLACK);
for (int16_t y=0; y < display.height()–1; y+=5) {
display.drawFastHLine(0, y, display.width()–1, color1);
}
for (int16_t x=0; x < display.width()–1; x+=5) {
display.drawFastVLine(x, 0, display.height()–1, color2);
}
}
void testdrawrects(uint16_t color) {
display.fillScreen(BLACK);
for (int16_t x=0; x < display.height()–1; x+=6) {
display.drawRect((display.width()–1)/2 –x/2, (display.height()–1)/2 –x/2 , x, x, color);
}
}
void testfillrects(uint16_t color1, uint16_t color2) {
display.fillScreen(BLACK);
for (int16_t x=display.height()–1; x > 6; x-=6) {
display.fillRect((display.width()–1)/2 –x/2, (display.height()–1)/2 –x/2 , x, x, color1);
display.drawRect((display.width()–1)/2 –x/2, (display.height()–1)/2 –x/2 , x, x, color2);
}
}
void testfillcircles(uint8_t radius, uint16_t color) {
for (uint8_t x=radius; x < display.width()–1; x+=radius*2) {
for (uint8_t y=radius; y < display.height()–1; y+=radius*2) {
display.fillCircle(x, y, radius, color);
}
}
}
void testdrawcircles(uint8_t radius, uint16_t color) {
for (int16_t x=0; x < display.width()–1+radius; x+=radius*2) {
for (int16_t y=0; y < display.height()–1+radius; y+=radius*2) {
display.drawCircle(x, y, radius, color);
}
}
}
void testtriangles() {
display.fillScreen(BLACK);
int color = 0xF800;
int t;
int w = display.width()/2;
int x = display.height()–1;
int y = 0;
int z = display.width();
for (t = 0 ; t <= 7; t+=1) {
display.drawTriangle(w, y, y, x, z, x, color);
x-=4;
y+=4;
z-=4;
color+=100;
}
}
void testroundrects() {
display.fillScreen(BLACK);
int color = 100;
int i;
int t;
for(t = 0 ; t <= 4; t+=1) {
int x = 0;
int y = 0;
int w = display.width();
int h = display.height();
for(i = 0 ; i <= 8; i+=1) {
display.drawRoundRect(x, y, w, h, 5, color);
x+=2;
y+=3;
w-=4;
h-=6;
color+=1100;
}
color+=100;
}
}
void tftPrintTest() {
display.fillScreen(BLACK);
display.setCursor(0, 5);
display.setTextColor(RED);
display.setTextSize(1);
display.println(“Hello World!”);
display.setTextColor(YELLOW, GREEN);
display.setTextSize(2);
display.print(“Hello Wo”);
display.setTextColor(BLUE);
display.setTextSize(3);
display.print(1234.567);
delay(1500);
display.setCursor(0, 5);
display.fillScreen(BLACK);
display.setTextColor(WHITE);
display.setTextSize(0);
display.println(“Hello World!”);
display.setTextSize(1);
display.setTextColor(GREEN);
display.print(p, 5);
display.println(” Want pi?”);
display.print(8675309, HEX); // print 8,675,309 out in HEX!
display.print(” Print HEX”);
display.setTextColor(WHITE);
display.println(“Sketch has been”);
display.println(“running for: “);
display.setTextColor(MAGENTA);
display.print(millis() / 1000);
display.setTextColor(WHITE);
display.print(” seconds.”);
}
/**************************************************************************/
/*!
@brief Renders a simple test pattern on the LCD
*/
/**************************************************************************/
void lcdTestPattern(void)
{
uint8_t w,h;
display.setAddrWindow(0, 0, 96, 64);
for (h = 0; h < 64; h++) {
for (w = 0; w < 96; w++) {
if (w > 83) {
display.writePixel(w, h, WHITE);
} else if (w > 71) {
display.writePixel(w, h, BLUE);
} else if (w > 59) {
display.writePixel(w, h, GREEN);
} else if (w > 47) {
display.writePixel(w, h, CYAN);
} else if (w > 35) {
display.writePixel(w, h, RED);
} else if (w > 23) {
display.writePixel(w, h, MAGENTA);
} else if (w > 11) {
display.writePixel(w, h, YELLOW);
} else {
display.writePixel(w, h, BLACK);
}
}
}
display.endWrite();
}
#define XPOS 0 // Indexes into the ‘icons’ array in function below
#define YPOS 1
#define DELTAY 2
#define DELTAT 3
void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
int8_t f, icons[NUMFLAKES][4];
uint16_t _color[NUMFLAKES];
// Initialize ‘snowflake’ positions
for(f = 0; f < NUMFLAKES; f++) {
icons[f][XPOS] = random(1 – LOGO_WIDTH, display.width());
icons[f][YPOS] = –LOGO_HEIGHT;
icons[f][DELTAY] = random(1, 6);
icons[f][DELTAT] = 0;
_color[f] = random(BLUE, WHITE);
Serial.print(F(“x: “));
Serial.print(icons[f][XPOS], DEC);
Serial.print(F(” y: “));
Serial.print(icons[f][YPOS], DEC);
Serial.print(F(” dy: “));
Serial.println(icons[f][DELTAY], DEC);
}
display.fillScreen(BLACK); // Clear the display
for(;;) { // Loop forever…
// Draw each snowflake:
for(f = 0; f < NUMFLAKES; f++) {
icons[f][DELTAT] += 1;
if (icons[f][DELTAT] >= icons[f][DELTAY]) {
icons[f][YPOS] += 1;
icons[f][DELTAT] = 0;
display.drawBitmap(icons[f][XPOS], icons[f][YPOS] – 1, bitmap, w, h, BLACK); // Erase the snowflake
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, _color[f]); // Draw the snowflake at the new position
}
}
delay(50); // Wait 50 milliseconds
// Then update coordinates of each flake…
for(f = 0; f < NUMFLAKES; f++) {
// If snowflake is off the bottom of the screen…
if ( icons[f][YPOS] >= (display.height() + 4) ) {
// Reinitialize to a random position, just off the top
icons[f][XPOS] = random(1 – LOGO_WIDTH, display.width());
icons[f][YPOS] = –LOGO_HEIGHT;
icons[f][DELTAY] = random(1, 6);
icons[f][DELTAT] = 0;
_color[f] = random(BLUE, WHITE);
}
}
}
}
// End of code.
// https://simple-circuit.com/
/***************************************************
This is a example sketch demonstrating the graphics
capabilities of the SSD1331 library for the 0.96″
16-bit Color OLED with SSD1331 driver chip
Pick one up today in the adafruit shop!
——> http://www.adafruit.com/products/684
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
|
Interfacing Arduino with SSD1331 OLED Display Video:
The following video shows a test hardware circuit of Arduino board with SSD1331 OLED display.