Connecting an OLED screen

Overview

Typical OLED screen uses I2C type communication with SCL (clock) and SDA (data). The one presented here is a small 0.96" screen with 128x64 definition. There are other size if you need it for your project.

Connecting to Arduino

OLED Pins Arduino Pins
VCC 5V or 3.3V
GND GND
SDA A4
SCL A5

Code example

For connecting a small OLED screen to an Arduino, we will first take a simple "hello" example. For a regular Arduino board, we take A4 (SDA) and A5 (SCL) pins as described above. In text mode, with the selected font size, we will have 8 lines (0 to 7) of 16 characters.

#define OLED
#ifdef OLED
#include <U8x8lib.h>
//you can also power the OLED screen with a digital pin, here pin 8
#define OLED_PWR_PIN 8
// connection may depend on the board. Use A5/A4 for most Arduino boards. 
//On ESP8266-based board we use GPI05 and GPI04. Heltec ESP32 has embedded OLED.
#if defined ARDUINO_Heltec_WIFI_LoRa_32 || defined ARDUINO_WIFI_LoRa_32 || defined HELTEC_LORA
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16);
#elif defined ESP8266 || defined ARDUINO_ESP8266_ESP01
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ 12, /* data=*/ 14, /* reset=*/ U8X8_PIN_NONE);
#else
//reset is not used
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ A5, /* data=*/ A4, /* reset=*/ U8X8_PIN_NONE);
#endif
char oled_msg[20];
#endif

int i=1;
    
void setup() {

  delay(2000);
  Serial.begin(38400);

#ifdef OLED    
#ifdef OLED_PWR_PIN
  pinMode(OLED_PWR_PIN, OUTPUT);
  digitalWrite(OLED_PWR_PIN, HIGH);
#endif
  u8x8.begin();
  u8x8.setFont(u8x8_font_pxplustandynewtv_r);
  u8x8.drawString(0, 0, "Hello friend");
  u8x8.drawString(0, 1, "How are you"); 
#endif  

  Serial.println("Hello friend"); 
}

void loop() {

  delay(500);
  delay(1000);
    
  if (i== 10) {
    Serial.println("Please answer me my friend...");
    i=1;
  }
  else
    i++;

  Serial.println("What can I do for you...?"); 
    
#ifdef OLED
  u8x8.drawString(0, 2, "What can I do   "); 
  u8x8.drawString(0, 3, "for you         ");
  u8x8.drawString(0, 4, "today?          "); 
#endif 

  delay(1000);

#ifdef OLED 
  u8x8.clearLine(2);
  u8x8.drawString(0, 2, "****************"); 
  u8x8.drawString(0, 3, "++++++++++++++++");
  u8x8.clearLine(4);
  u8x8.drawString(0, 5, "////////////////");
  u8x8.drawString(0, 6, "----------------"); 
  u8x8.drawString(0, 7, "////////////////"); 
#endif     

  delay(1000);    
}    

The raw source of the sketch example is visible here. As you can see, the sketch first includes the required library to control the OLED screen, here it is the U8x8lib library. The regular Arduino boards such as Uno or Pro Mini will use pins A4 (for SDA=data) and A5 (for SCL=clock) to communicate with the OLED screen.

Then the OLED screen can be initialized and the font selected. Note how the sketch displays a string on the OLED screen with the u8x8.drawString() function which takes 3 arguments: the starting column, the starting line and the text itself. The origin (0,0) is the top left corner.

As you can also see in the code above, it is possible to connect the OLED VCC pin to a digital pin of the Arduino in order to enable dynamic ON/OFF of the screen if this is desired. In the code, digital pin 8 is used.

Now, we are going to use a more complex example taking the Sensirion SHT example that has been previously shown in the Humidity section. You can take another example by adding the parts that are related to the OLED screen. These parts are identified by #ifdef OLED ... #endif.

#include "Sensirion.h"

#define SHTD_PIN 2
#define SHTC_PIN 3
#define SHT2x

//we can also power the SHT with a digital pin, here pin 6
#define PIN_POWER 6

#ifdef SHT2x
Sensirion sht = Sensirion(SHTD_PIN, SHTC_PIN, 0x40);
#else
Sensirion sht = Sensirion(SHTD_PIN, SHTC_PIN);
#endif

#define OLED
#ifdef OLED
//you can also power the OLED screen with a digital pin, here pin 8
#define OLED_PWR_PIN 8
#include <U8x8lib.h>
// connection may depend on the board. Use A5/A4 for most Arduino boards. 
//On ESP8266-based board we use GPI05 and GPI04. Heltec ESP32 has embedded OLED.
#if defined ARDUINO_Heltec_WIFI_LoRa_32 || defined ARDUINO_WIFI_LoRa_32 || defined HELTEC_LORA
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16);
#elif defined ESP8266 || defined ARDUINO_ESP8266_ESP01
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ 12, /* data=*/ 14, /* reset=*/ U8X8_PIN_NONE);
#else
//reset is not used
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ A5, /* data=*/ A4, /* reset=*/ U8X8_PIN_NONE);
#endif
char oled_msg[20];
#endif

float h;
float t;
int ret;
int retry=0;
    
void setup() {

  delay(3000);
  Serial.begin(38400);
  //and to power the temperature sensor
  pinMode(PIN_POWER,OUTPUT);
    
#ifdef OLED_PWR_PIN
  pinMode(OLED_PWR_PIN, OUTPUT);
  digitalWrite(OLED_PWR_PIN, HIGH);
#endif

#ifdef OLED
  u8x8.begin();
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  u8x8.drawString(0, 1, "Arduino SHT"); 
#endif   
}

void loop() {

    digitalWrite(PIN_POWER,HIGH);
    delay(1000);
    
    while ( (ret != S_Meas_Rdy) ) {
      ret=sht.measure(&t, &h);
      retry++;
      Serial.print("[");
      Serial.print(ret);
      Serial.print(":");
      Serial.print(retry);
      Serial.print("] ");      
    }

    if (ret != S_Meas_Rdy) {
    Serial.println("Failed to read from SHT sensor!"); 
    
#ifdef OLED
        u8x8.clearLine(4);
        u8x8.clearLine(5);
        u8x8.drawString(0, 4, "error SHT...");  
#endif 
    }
    else {         
        Serial.print("Temperature: ");
        Serial.print(t);
        Serial.print(" degrees Celcius Humidity: ");
        Serial.print(h);
        Serial.println("%"); 

#ifdef OLED
        String tString=String(t);
        String hString=String(h);
        u8x8.clearLine(4);
        sprintf(oled_msg, "t=%s h=%s", tString.c_str(), hString.c_str()); 
        u8x8.drawString(0, 4, oled_msg); 
#endif      
    }
    
    digitalWrite(PIN_POWER,LOW);
    ret=0;
    retry=0;
    delay(5000);
}    

The raw source of the sketch example is visible here. We added a char array (char oled_msg[20]) as a text buffer where complex output can be converted in characters with the sprintf() function. This is convenient because the OLED library can only display simple text buffer, therefore if you need to display complex text with values from variables of your program, use the sprintf() as shown at the end of the example.

It is possible to use other pins on the Arduino board for the SCL and SDA pins. For instance, as most of the small OLED screen from Chinese manufacturers have GND, VCC, SCL and SDA pins (from left to right) then it is convenient to use on the Arduino board (for instance the Arduino Nano or the Arduino ProMini) 4 consecutive pins such as GND, D2, D3 and D4 as illustrated in the figure below for the Arduino Nano.

Here for instance, OLED VCC is connected to digital pin 2 of the Arduino therefore OLED_PWR_PIN should be defined as:

#define OLED_PWR_PIN 2

Then change the definition of the screen object as follows:

U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ 3, /* data=*/ 4, /* reset=*/ U8X8_PIN_NONE);                 	     

If you look at the raw source of the "hello" example previously presented you will see a list of #define statements at the beginning. They are commented as shown below:

// choose Arduino pin for OLED pin GND, VCC, SCL and SDA 
// suitable for Arduino Nano
//#define OLED_GND234
// suitable for Arduino Nano as well, pin 9 as GND
//#define OLED_9GND876
// suitable for Arduino Uno & Arduino MEGA2560, pin 7 as GND
//#define OLED_7GND654
// suitable for Arduino Uno & Arduino MEGA2560
//#define OLED_GND13_12_11

Uncomment the configuration that is suitable for you. For instance, if you want to use the previous configuration described for the Arduino Nano, i.e. 4 consecutive Arduino pins such as GND, D2, D3 and D4 for respectively OLED GND, VCC, SCL and SDA, then uncomment //#define OLED_GND234. You can also use an Arduino digital pin as GND pin by setting this pin to LOW level. //#define OLED_9GND876 and //#define OLED_7GND654 use for instance pin 9 or pin 7 for GND.

Enjoy!