This Arduino project demonstrates how to easily interface an Arduino board with an SH1107 OLED display module featuring a 1.5-inch screen and a 128×128 pixel resolution.
The project illustrates how to display text and draw basic shapes, such as circles and rectangles, on the SH1107 OLED, which is configured to operate in SPI mode.
Abbreviations:
OLED: Organic light Emitting Diode.
PLED: Polymer OLED.
TFT: Thin Film Transistor.
I2C: Inter-Integrated Circuit.
SPI: Serial Peripheral Interface.
IoT: Internet of things.
Overview of the SH1107 OLED Display Module:
The SH1107 is a CMOS OLED/PLED driver and controller commonly used in small to medium-sized dot-matrix display systems based on organic or polymer light-emitting diodes.
It supports a maximum resolution of 128×128 pixels and is specifically designed to drive monochrome OLED panels.
Thanks to its compact size, low power consumption, and built-in controller functionality, the SH1107 is widely used in embedded systems, IoT devices, and consumer electronics.
The SH1107 OLED display module is a compact monochrome graphic display that uses the SH1107 driver chip. These modules typically come with resolutions of 128×64 or 128×128 pixels and are commonly available with either I2C or SPI communication interfaces.
Thanks to their high contrast, wide viewing angles, low power consumption, and small form factor, SH1107 displays are ideal for space-constrained and battery-powered applications. They are frequently used in projects involving microcontrollers such as Arduino, ESP32, Raspberry Pi, and Microchip PIC/dsPIC, among others.
Properties of the SH1107 OLED Display Module:
- Resolution: Typically 128×64 or 128×128 pixels; smaller resolutions may also be available.
- Display Type: Monochrome — displays a single color (commonly white, blue, or yellow) on a black background.
- Interface: Supports I2C and/or SPI communication protocols. I2C is the most commonly used interface.
- Operating Voltage: Typically 3.3V or 5V, depending on the specific module design.
- Power Consumption: Very low, as the OLED display does not require a backlight, making it ideal for battery-powered and energy-efficient applications.
The image below shows an example of an SH1107 OLED display module configured to operate in SPI mode:
The SH1107 OLED display shown above is configured to operate using the SPI interface protocol. Below is the pinout of the display module, which is essential for connecting it to a microcontroller such as an Arduino, ESP32, Raspberry Pi, or Microchip PIC/dsPIC:
- GND: Ground pin, connected to circuit common ground.
- VCC: Power supply pin — typically 3.3V or 5V, depending on the module specs.
- SCL: Serial Clock line of the SPI bus.
- SDA: Serial Data line of the SPI bus.
- RES: Active-low 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 with logic low for Command and high for 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.
Arduino MEGA Interface with SH1107 OLED Display in SPI mode:
The image below shows the circuit schematic for interfacing an Arduino MEGA board with an SH1107 OLED display module operating in SPI mode.
The SH1107 display module used in this project has 7 pins, arranged from left to right as follows:
GND (Ground), VCC, SCL (Serial Clock), SDA (Serial Data), RES (Reset), DC (Data/Command), and CS (Chip Select).
Hardware Required:
This is a summary of the components needed to build this project:
- Arduino MEGA board (based on the ATmega2560 microcontroller – datasheet)
- SH1107 OLED display module (7-pin version, 1.5-inch screen, 128×128 pixel resolution)
- 5 x 2k ohm resistor
- 5 x 1k ohm resistor
- Breadboard
- Jumper wires
Since the SH1107 OLED display operates at a 3.3V logic level and the Arduino MEGA uses 5V logic, a resistive voltage divider was used to reduce the Arduino’s 5V output signals to approximately 3.3V.
While a resistive divider is one of the simplest and most cost-effective methods for logic level shifting, more reliable and efficient solutions—such as logic level shifter modules—can also be used, especially for high-speed communication lines.
Since there are five data lines between the Arduino board and the SH1107 OLED display, five resistive voltage dividers are used, each implemented with a 1 kΩ and 2 kΩ resistor.
Connecting a 5V microcontroller directly to the SH1107 OLED display violates the electrical characteristics specified in the display’s datasheet and may damage the display’s controller circuitry. Using voltage dividers (or proper level shifters) ensures safe and reliable operation.
The SH1107 display module is powered with 3.3V from the Arduino board:
- The GND pin of the SH1107 display is connected to the GND pin of the Arduino.
- The VCC pin of the display is connected to the 3.3V pin on the Arduino.
The remaining signal pins are connected through voltage dividers to protect the logic circuitry of the display. The connections are as follows:
- SCL is connected to digital pin 52 of the Arduino.
- SDA is connected to digital pin 51 of the Arduino.
- RES is connected to digital pin 27 of the Arduino.
- DC is connected to digital pin 25 of the Arduino.
- CS is connected to digital pin 23 of the Arduino.
Note: On the Arduino MEGA (and other boards using the ATmega2560), digital pins 52 and 51 are the hardware SPI pins, corresponding to SCK (Serial Clock) and MOSI (Master-Out Slave-In), respectively.
Arduino MEGA Interface with SH1107 OLED Display in SPI mode – Arduino Code:
To compile and run the Arduino code for this project, you’ll need to install two libraries from Adafruit Industries:
- Adafruit SH1107 OLED Display Library: This is the driver library for the SH1107 display. You can install it using the Arduino IDE Library Manager,
Go to Sketch → Include Library → Manage Libraries…, search for “sh1107”, and install the version published by Adafruit. - Adafruit GFX Library: This library provides graphics primitives (text, shapes, etc.) and is also available through the Library Manager. In the Arduino IDE Library Manager, Search for “Adafruit GFX” and install the library published by Adafruit.
Note: During the installation of the Adafruit SH1107 library, the Arduino IDE may prompt you to install additional dependencies such as Adafruit BusIO. Make sure to accept and install all required dependencies.
Tested Library Versions:
The following library versions were used to develop and successfully test this project:
- Adafruit GFX Library: Version 1.12.1
- Adafruit SH110X OLED Display Library: Version 2.1.13
- Adafruit BusIO: Version 1.17.1
Programming Hints:
The required libraries are included in the Arduino code as follows:
1 2 3 | #include <SPI.h> // Arduino SPI communication library #include <Adafruit_GFX.h> // Adafruit Graphics library #include <Adafruit_SH110X.h> // AdafruitSH110X OLED driver (supports SH1107) |
The SH1107 display is initialized with a resolution of 128×128 pixels and an SPI clock frequency of 8 MHz:
1 2 3 | #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 128 // OLED display height, in pixels Adafruit_SH1107 display = Adafruit_SH1107(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, OLED_DC, OLED_RST, OLED_CS, 8000000UL); |
Before using any display functions (e.g., print(), drawLine(), etc.), the SH1107 OLED display must be properly initialized. If the initialization fails, the screen will remain blank.
Use the begin() function to initialize the display as shown below:
1 | display.begin(); |
Note: The Arduino code provided below is adapted from an example sketch included with the Adafruit SH1107 library.
Minor modifications have been made to suit this project setup (Arduino MEGA + SH1107 in SPI mode).
Full Arduino code:
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 398 | /****************************************************************************** * Interfacing Arduino MEGA board with SH1107 OLED monochrome display. * * Display Resolution: 128×128 pixels * Interface Mode: SPI * * This is free software distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * For more details and tutorials, visit: https://simple-circuit.com/ /*******************************************************************************/ #include <SPI.h> // Arduino SPI communication library #include <Adafruit_GFX.h> // Adafruit Graphics library #include <Adafruit_SH110X.h> // AdafruitSH110X OLED driver (supports SH1107) // Connection between Arduino MEGA and SH1107 OLED display (SPI mode) #define OLED_CS 23 // Chip select pin #define OLED_DC 25 // Data/Command pin #define OLED_RST 27 // Reset pin (use -1 if tied to Arduino RESET) #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 128 // OLED display height, in pixels Adafruit_SH1107 display = Adafruit_SH1107(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, OLED_DC, OLED_RST, OLED_CS, 8000000UL); #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() { Serial.begin(9600); delay(500); // wait for the OLED to power up // Show image buffer on the display hardware. // Since the buffer is intialized with an Adafruit splashscreen // internally, this will display the splashscreen. display.begin(0x3C, true); // Try 0x3D if the display does not respond at 0x3C //display.setContrast (0); // dim display display.display(); delay(2000); // Clear the buffer. display.clearDisplay(); // draw a single pixel display.drawPixel(10, 10, SH110X_WHITE); // Show the display buffer on the hardware. // NOTE: You _must_ call display after making any drawing commands // to make them visible on the display hardware! display.display(); delay(2000); display.clearDisplay(); testdrawline(); // Draw many lines testdrawrect(); // Draw rectangles (outlines) testfillrect(); // Draw rectangles (filled) testdrawcircle(); // Draw circles (outlines) testfillcircle(); // Draw circles (filled) testdrawroundrect(); // Draw rounded rectangles (outlines) testfillroundrect(); // Draw rounded rectangles (filled) testdrawtriangle(); // Draw triangles (outlines) testfilltriangle(); // Draw triangles (filled) testdrawchar(); // Draw characters of the default font testdrawstyles(); // Draw 'stylized' characters testdrawbitmap(); // Draw a small bitmap image testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps } void loop() { } void testdrawline() { int16_t i; display.clearDisplay(); // Clear display buffer for(i=0; i<display.width(); i+=4) { display.drawLine(0, 0, i, display.height()-1, SH110X_WHITE); display.display(); // Update screen with each newly-drawn line delay(1); } for(i=0; i<display.height(); i+=4) { display.drawLine(0, 0, display.width()-1, i, SH110X_WHITE); display.display(); delay(1); } delay(250); display.clearDisplay(); for(i=0; i<display.width(); i+=4) { display.drawLine(0, display.height()-1, i, 0, SH110X_WHITE); display.display(); delay(1); } for(i=display.height()-1; i>=0; i-=4) { display.drawLine(0, display.height()-1, display.width()-1, i, SH110X_WHITE); display.display(); delay(1); } delay(250); display.clearDisplay(); for(i=display.width()-1; i>=0; i-=4) { display.drawLine(display.width()-1, display.height()-1, i, 0, SH110X_WHITE); display.display(); delay(1); } for(i=display.height()-1; i>=0; i-=4) { display.drawLine(display.width()-1, display.height()-1, 0, i, SH110X_WHITE); display.display(); delay(1); } delay(250); display.clearDisplay(); for(i=0; i<display.height(); i+=4) { display.drawLine(display.width()-1, 0, 0, i, SH110X_WHITE); display.display(); delay(1); } for(i=0; i<display.width(); i+=4) { display.drawLine(display.width()-1, 0, i, display.height()-1, SH110X_WHITE); display.display(); delay(1); } delay(2000); // Pause for 2 seconds } void testdrawrect(void) { display.clearDisplay(); for(int16_t i=0; i<display.height()/2; i+=2) { display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SH110X_WHITE); display.display(); // Update screen with each newly-drawn rectangle delay(1); } delay(2000); } void testfillrect(void) { display.clearDisplay(); for(int16_t i=0; i<display.height()/2; i+=3) { // The INVERSE color is used so rectangles alternate white/black display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SH110X_INVERSE); display.display(); // Update screen with each newly-drawn rectangle delay(1); } delay(2000); } void testdrawcircle(void) { display.clearDisplay(); for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) { display.drawCircle(display.width()/2, display.height()/2, i, SH110X_WHITE); display.display(); delay(1); } delay(2000); } void testfillcircle(void) { display.clearDisplay(); for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) { // The INVERSE color is used so circles alternate white/black display.fillCircle(display.width() / 2, display.height() / 2, i, SH110X_INVERSE); display.display(); // Update screen with each newly-drawn circle delay(1); } delay(2000); } void testdrawroundrect(void) { display.clearDisplay(); for(int16_t i=0; i<display.height()/2-2; i+=2) { display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, SH110X_WHITE); display.display(); delay(1); } delay(2000); } void testfillroundrect(void) { display.clearDisplay(); for(int16_t i=0; i<display.height()/2-2; i+=2) { // The INVERSE color is used so round-rects alternate white/black display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, SH110X_INVERSE); display.display(); delay(1); } delay(2000); } void testdrawtriangle(void) { display.clearDisplay(); for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) { display.drawTriangle( display.width()/2 , display.height()/2-i, display.width()/2-i, display.height()/2+i, display.width()/2+i, display.height()/2+i, SH110X_WHITE); display.display(); delay(1); } delay(2000); } void testfilltriangle(void) { display.clearDisplay(); for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) { // The INVERSE color is used so triangles alternate white/black display.fillTriangle( display.width()/2 , display.height()/2-i, display.width()/2-i, display.height()/2+i, display.width()/2+i, display.height()/2+i, SH110X_INVERSE); display.display(); delay(1); } delay(2000); } void testdrawchar(void) { display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SH110X_WHITE); // Draw white text display.setCursor(0, 0); // Start at top-left corner display.cp437(true); // Use full 256 char 'Code Page 437' font // Not all the characters will fit on the display. This is normal. // Library will draw what it can and the rest will be clipped. for(int16_t i=0; i<256; i++) { if(i == '\n') display.write(' '); else display.write(i); } display.display(); delay(2000); } void testdrawstyles(void) { display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SH110X_WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.println(F("Hello, world!")); display.setTextColor(SH110X_BLACK, SH110X_WHITE); // Draw 'inverse' text display.println(3.141592); display.setTextSize(2); // Draw 2X-scale text display.setTextColor(SH110X_WHITE); display.print(F("0x")); display.println(0xDEADBEEF, HEX); display.display(); delay(2000); } void testdrawbitmap(void) { display.clearDisplay(); display.drawBitmap( (display.width() - LOGO_WIDTH ) / 2, (display.height() - LOGO_HEIGHT) / 2, logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1); display.display(); delay(1000); } #define NUMFLAKES 12 #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) { uint8_t f; int16_t icons[NUMFLAKES][4]; // 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, 8); icons[f][DELTAT] = 0; 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.clearDisplay(); // Clear the display buffer 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, SH110X_BLACK); // Erase the snowflake display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SH110X_WHITE); } } display.display(); // Show the display buffer on the screen delay(40); // Pause for 40 ms // Then update coordinates of each flake... for(f = 0; f < NUMFLAKES; f++) { //icons[f][YPOS] += icons[f][DELTAY]; // If snowflake is off the bottom of the screen... if (icons[f][YPOS] >= (display.height())) { // 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, 8); icons[f][DELTAT] = 0; } } } } // End of code. // https://simple-circuit.com/ /********************************************************************* This is an example for our Monochrome OLEDs based on SH1107 drivers This example is for a 128x128 size display using I2C to communicate 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, check license.txt for more information All text above, and the splash screen must be included in any redistribution *********************************************************************/ |
Interfacing Arduino Board with SH1107 OLED Display in SPI Mode – Video:
The video below demonstrates the interfacing of an Arduino MEGA board with an SH1107 OLED display using I2C communication.
The display visual output in SPI mode is identical to that of I2C mode; however, SPI offers significantly faster data transfer, making it a better choice for applications that require higher display refresh rates or more responsive graphics.
Related Projects:
Interfacing Arduino Board with SH1107 OLED Display in I2C Mode
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.