Overview

This project reads values from the serial monitor and displays the readings on a 128x64 I2C OLED. An OLED (Organic Light-Emitting Diode) is an alternative to an LCD. While an LCD restricts you to printing characters, an OLED allows you to manipulate individual pixels and display text and graphics.

Components

Component NamePurpose
Arduino NanoThis will be the microcontroller
128X64 I2C OLEDThis will be the OLED display

Circuit Diagram

nano_serial_oled_fritzing

Assembly

I2C OLED Pin Connections

Nano PinI2C OLED Pin
A4SDA
A5SCL
5VVCC
GNDGND

Code

 
/*
  Project: OLED display - I2C connection 
  Project Description:
  This sketch writes data from the serial monitor input to an OLED display module.
  This sketch is for a 128x64 pixels screen.
 
  Author: STEMVentor Educonsulting
  
  This code is copyrighted. Please do not reuse or share for any purpose other than for learning with subscribed STEMVentor programs.
  This code is for educational purposes only and is not for production use.
*/
 
// LIBRARIES
 
#include <Wire.h> //used for communicating with I2C devices
 
// install the adafruit ssd1306 library
#include <Adafruit_GFX.h>  
#include <Adafruit_SSD1306.h>
 
// PIN DEFINITIONS
 
// GLOBAL VARIABLES
  // Define the display size
  const byte screenWidth = 128;// OLED display width, in pixels
  const byte screenHeight = 64;// OLED display height, in pixels
 
// Used for reading a string.
String receivedString;
 
/* INITIALIZE OBJECTS
 * Libraries usually follow an object-oriented approach that requires
 * an instance of the class to call its methods.
 */
/* 
 * All I2C components have an address, the default is usually 0x27
 * If that doesn't work, see this:https://playground.arduino.cc/Main/I2cScanner/
 * The init statement accepts the address and the number of columns and rows.
 */
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(screenWidth, screenHeight, &Wire, -1);
// -1 specifically indicates that there is no reset pin used for the display. Some OLED displays have a reset pin that can be connected to a GPIO pin on the microcontroller to manually reset the display. 
// When the reset pin is not used, you pass -1 to indicate this.
 
/* LOCAL FUNCTIONS */
 
// Read an entire string (this is a blocking function and waits until timeout).
void readString()
{
  Serial.println("Enter a data string to be displayed on OLED:");
  while (Serial.available() == 0) {}     //wait for data available
  receivedString = Serial.readString(); //read until timeout
  receivedString.trim();                // remove any \r \n whitespace at the end of the String
}
 
/*
  Function to print to display on a single row.
  Takes the row number and the text to display on that row (max 20 chars, rest will be truncated).
  The entire display is cleared if the clear_all flag is true, else only the row is cleared (the default).
 */
void printTodisplayByRow(int row, String text, bool clear_all = false)
{
  const char* twenty_spaces = "                                        ";  //40 blank spaces
 
  if(clear_all){ 
    display.clearDisplay(); //clears the entire display
  } 
 
  display.setCursor(0, (row-1)*8);
  display.print(twenty_spaces); //clears the row
  display.setCursor(0, (row-1)*10); //cursor has to be set again after printing spaces
  display.print(text);
}
 
void printToDisplay(String text)
{
  display.clearDisplay(); //clears the display
  display.setCursor(20,10 ); //sets cursor to these pixels to start from
  display.println(text); //sends it to the display 
  display.display(); //displays it on the display
  Serial.println("Data string has been displayed on OLED display");
}
 
void oledSetup()
{
  // Initializing wire
  Wire.begin();
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for most OLED I2C.
    Serial.println(F("SSD1306 allocation failed"));
  }
 
  display.clearDisplay();
  display.setTextSize(1); //sets the text size ( can be 0 , 1  ,2 )
  display.setTextColor(WHITE); //sets the text colour 
  // Use the function to display text on each line indiviudally.
  printTodisplayByRow(1, "OLED display Ready!", true);
  printTodisplayByRow(2, "Enter some text.", false);
  display.display();
}
/* SETUP CODE: runs once when the board starts up or resets */ 
void setup() {
  // Start the serial communication with baud rate suitable for your components.
  Serial.begin(9600);
  oledSetup();
  Serial.println("The board is ready !");
}
 
/* MAIN LOOP: runs repeatedly at a very high frequency (1000s of times a second) */
void loop() {
  readString();
  printToDisplay(receivedString);
}