Zonnestroompanelen in Nederland

duurzaamheid achter de meter

(31) Temperature and humidity displayed with a 128×64 OLED display (SSD1306 driver) on an Arduino Nano

by Floris Wouterlood – The Netherlands –

Summary
We discuss here how to wire a very popular 128×64 pixel two-color monochrome graphic OLED display to an Arduino. The display is based on the SSD1306 chip, and communication runs via the SPI interface. For microcontroller boards like the Arduino a small display can be desirable to show information collected by sensors. For this paper we display on this OLED the output of a DHT11 temperature – relative humidity sensor. The amazing refreshing speed of this display is illustrated with the sketch ‘bouncer’.

Introduction
There are many very small displays on the market based on OLED (organic light-emitting diode) technology. OLEDs consume very little energy, they are cheaper than TFT displays, and compared with LCD they have the big advantage that they do not need background illumination. They also refresh fast.

figure 1: 128×64 OLED display with SSD1306 driver. Note that this one has 7 pins: GND, VDD, SCK, SDA, RES, DC and CS. The interface uses the SPI convention. This display is hybrid monochrome (two color bands): an upper strip of 128×16 yellow pixels and a lower strip of 128×48 whitish blue pixels. Note that full-monochrome 128×64 OLED displays are shipped with a green tag label and that hybrid yellow-whitish blue pixel OLED displays are shipped with a red tag label. The graphic represents the Brainy Bits logo (www.brainy-bits.com).

An OLED device can be considered as an array of individual pixels that can individually be switched ON – they light up – or OFF – just background. Because background is ink black the pixels stand out pretty nicely while readability is perfect. The array configuration makes it possible to display graphic bitmaps: logos, avatars, sprites. For microelectronics like the Arduino where often a small display is desirable to visualize useful information, e.g. time or the output of a particular sensor, an OLED display can be very handy.
Typical OLED displays are 0.96 inch in width, with in most cases screen dimensions of 128×32 or 128×64 pixels. OLED displays can be powered by different driver chips. Most popular are the SH1106 and SSD1306. We discuss here a very popular OLED display for the Arduino: a 128×64 hybrid, two-color display based on the SSD1306 chip. Note that this is not a true color display. It has an upper strip of 16 pixels high where pixels light up yellow. Under this strip is the main area of 48 pixels high where the pixels produce whitish blue light. This particular display uses the SPI protocol to receive instructions from the microcontroller board.
To do a useful thing with this display I have added a DHT11 sensor to collect data to be displayed: relative humidity and temperature (figure 1). The led is to check that the sketch loop is running as it should.

128×64 hybrid color SSD1306 based OLED with SPI interface: pins and connectivity with an Arduino

Connectivity table

OLED pin label
   also known as
  connect to pin on the Arduino
GND GND GND
VDD VCC 3.3V
SCK D0 D13
SDA MOSI D11
RES RES D8
DC DATA D9
CS CS D10

 

Pull up resistors not necessary

OLED displays that receive data via a SPI interface do not need pull-up or pull-down resiustors. In the wiring scheme of figure 2 a 10 kΩ resistor is placed that acts as a pull-up resistor for the DHT11 sensor. Because the OLED display runs on 3.3V the led can use 3.3V as well. This means that the led does not need a resistor in series.

Figure 2: Wiring scheme including a 128×64 OLED and an Arduino (here a Nano). Pins marked SCK, SDA, RES, DC and CS on the display are wired to, respectively, pins D13, D11, D8, D9 and D10 on the Nano. The data pin of the DHT11 sensor is connected to pin D4 on the Nano. The 10 kΩ resistor is a pull-up resistor. The led is controlled via pin D3 on the Nano. Because all devices operate at 3.3V the led works fine with this voltage and does not need a resistor in series.

Electronics and supplies
1x Arduino Nano microcontroller board, 1x 10 kΩ resistor, breadboard, jumper wires, led, 1x DHT11 sensor.

Figure 3: Working version of the 128×64 OLED display mounted together with a Nano and a DHT11 on a breadboard. The 10k pull-up resistor necessary for correct functioning of the DHT11 sensor is visible partly hidden by jumper wires (arrow).

Sketches

Two sketches are supplied here. First comes the sketch that reads the DHT 11 sensor and displays the data on the OLED, as in figures 1-3. The second sketch produces on the display a small ball that bounces back on the edges of the display. At the moment of bouncing a random number influences the angle of the return bounce.

Sketch 1: ‘OLED_128x64_nano_DHT11_led.ino’. The instructions in this sketch initialize the OLED display and the DHT11 sensor, then starts reading the sensor and displays the values for relative humidity and temperature on the OLED display. Wiring is according to figures 2 and 3. Note that there is separate output to Serial Monitor. Several ‘delay’ statements in the sketch can be changed to improve performance.The sketch uses Olikraus’ library U8glib.h. This library can be downloaded from GITHUB. Note the so-called ‘constructor’:

// U8GLIB constructor OLED display
U8GLIB_SSD1306_128X64 u8g(OLED_SCK, OLED_MOSI, OLED_CS, OLED_DC, OLED_RES);

That informs the compiler that there is a SSD1306 based OLED display with dimensions 128×64 pixels that uses the pins as expressed in the #defines. If you use in the constructor 128×32 dimensions then the characters on the screen become vertically stretched.

// OLED_128x64_nano_DHT11_led.ino

// essential fragments found on Henry’s Bench – for use with SSD1306 Monochrome OLEDs
// Brainy Bit logo at https://www.brainy-bits.com/
// DHT11 part based on DHT11 example by Ladyada.
// data pin of DHT11 sensor wired to pin D4 on Arduino
// 10k pull up resistor (between data pin DHT11 and 3.3V)
// this sketch by Floris Wouterlood
// august 20, 2019
// public domain

// libraries
#include “U8glib.h”
#include “DHT.h”

// pins on the Arduino
#define OLED_SCK 13
#define OLED_MOSI 11
#define OLED_CS 10
#define OLED_DC 9
#define OLED_RES 8

// DHT11 stuff
float h, t;
DHT DHT_sens (4, DHT11); // datapin sensor to pin 84 Arduino

// U8GLIB constructor OLED display
U8GLIB_SSD1306_128X64 u8g (OLED_SCK, OLED_MOSI, OLED_CS, OLED_DC, OLED_RES);

// Brainy Bits logo
const uint8_t brainy_bitmap[] PROGMEM = {

0x00, 0x00, 0x03, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x46,
0x00, 0x00, 0x00, 0x00, 0xFC, 0x47, 0xC0, 0x00, 0x00, 0x01, 0xCE, 0x4C, 0x60, 0x00, 0x00, 0x03,
0x02, 0x58, 0x30, 0x00, 0x00, 0x03, 0x02, 0x58, 0x10, 0x00, 0x00, 0x02, 0x02, 0x58, 0x18, 0x00,
0x00, 0x03, 0x06, 0x4C, 0xOLED_128x64_bouncer.zip18, 0x00, 0x00, 0x07, 0x04, 0x44, 0x18, 0x00, 0x00, 0x0D, 0x80, 0x40,
0x3C, 0x00, 0x00, 0x09, 0xC0, 0x40, 0xE6, 0x00, 0x00, 0x18, 0x78, 0x47, 0xC2, 0x00, 0x00, 0x18,
0x0C, 0x4E, 0x02, 0x00, 0x00, 0x1F, 0x86, 0x4C, 0x7E, 0x00, 0x00, 0x0E, 0xC6, 0xE8, 0xEE, 0x00,
0x00, 0x18, 0x43, 0xF8, 0x82, 0x00, 0x00, 0x10, 0x06, 0x4C, 0x03, 0x00, 0x00, 0x30, 0x0C, 0x46,
0x01, 0x00, 0x00, 0x30, 0x18, 0x46, 0x01, 0x00, 0x00, 0x10, 0x18, 0x43, 0x03, 0x00, 0x00, 0x18,
0x10, 0x43, 0x03, 0x00, 0x00, 0x1C, 0x70, 0x41, 0x86, 0x00, 0x00, 0x0F, 0xE0, 0x40, 0xFE, 0x00,
0x00, 0x09, 0x1E, 0x4F, 0x06, 0x00, 0x00, 0x08, 0x30, 0x43, 0x86, 0x00, 0x00, 0x0C, 0x20, 0x41,
0x86, 0x00, 0x00, 0x06, 0x60, 0x40, 0x8C, 0x00, 0x00, 0x07, 0x60, 0x40, 0xB8, 0x00, 0x00, 0x01,
0xE0, 0x41, 0xF0, 0x00, 0x00, 0x00, 0x38, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xBE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

void draw(void) {

// led control
digitalWrite(3, HIGH);
delay(500);
digitalWrite(3, LOW);

u8g.drawBitmapP( 80, 0, 6, 40, brainy_bitmap); // put bitmap
h = DHT_sens.readHumidity ();
t = DHT_sens.readTemperature ();
u8g.setFont (u8g_font_unifont); // select font
u8g.drawStr (0, 30, “Temp: “); // put string of display at position X, Y
u8g.drawStr (0, 50, “Hum: “);
u8g.setPrintPos (44, 30); // set positionOLED_128x64_nano_DHT11_led.ino
u8g.print (t, 0); // display temperature from DHT11
u8g.drawStr (60, 30, “*C “);

delay (1000); // pause a second
Serial.print (“Humidity: “);
Serial.print (h,0); // set to no decimal
Serial.print (” %\t”);

u8g.setPrintPos(44, 50);
u8g.print(h, 0); // display humidity from DHT11
u8g.drawStr(60, 50, “% “);

Serial.print (“Temperature: “);
Serial.print (t,1); // set to one decimal
Serial.println (” *C”);
delay (1000);
}

void setup (void) {

pinMode (3, OUTPUT);
u8g.setFont(u8g_font_unifont);
u8g.setColorIndex(1); // Instructs the display to draw with a pixel on. 0 = OFF, 1 = ON

DHT_sens.begin();

// Serial Monitor output
Serial.begin (9600);
Serial.println (” “);
Serial.println (“====================================”);
Serial.println (” – DHT11 humidity-temp sensor – “);
Serial.println (“====================================”);
Serial.println (” “);

void loop(void) {
u8g.firstPage();OLED_128x64_bouncer.zip
do {
draw();
} while( u8g.nextPage() );
delay(1000);
}

Sketch 2: ‘Bouncer’. First the 128×64 OLED display is initialized. Next a small filled circle ‘ball’ is produced (radius r is a declared variable) that starts moving around. When it hits a wall a random generator is triggered. The random number determines at what angle the ball bounces bacl. This produces an ever changing pattern of movement being displayed.

// OLED_128x64_bouncer.ino
// for use with SSD1308 Monochrome OLEDs
// this sketch by Floris Wouterlood
// august 20, 2019
// public domain

// libraries
#include “U8glib.h”

// pins on the Arduino OLED_128x64_bouncer.ino
#define OLED_SCK 13
#define OLED_MOSI 11
#define OLED_CS 10
#define OLED_DC 9
#define OLED_RES 8

// U8GLIB constructor OLED display
U8GLIB_SSD1306_128X64 u8g(OLED_SCK, OLED_MOSI, OLED_CS, OLED_DC, OLED_RES);

int x=10;
int y=10;
int updown=3;
int leftright=2;
int multiplier=1;
int setdelay=11;
int c_radius=2;

void draw(void) {

y=y+updown;
x=x+leftright;
multiplier = random (1, 3);

u8g.drawDisc(x,y,c_radius);

// bouncing on one of four the walls
if ((x>128) && (leftright=1)){
leftright=(-1*multiplier);
x=126;
}

if ((x<0) && (leftright=-1)){
leftright=(1*multiplier);OLED_128x64_bouncer.ino
x=2;
}

if ((y>64) && (updown=1)){
updown=(-1*multiplier);
y=62;
}

if ((y<0) && (updown=-1)){
updown=(1*multiplier);
y=2;
}

delay(5);

}

void setup(void) {
pinMode (3, OUTPUT);
u8g.setFont(u8g_font_unifont);
u8g.setColorIndex(1); // Instructs the display to draw with a pixel on. 0 = OFF, 1 = ON
}

void loop(void) {
u8g.firstPage ();
do {
draw ();
} while( u8g.nextPage() );

delay (10);
}

Discussion

I consider the red-label tag, 128×64 OLED display a nice addition to the repertoire of displays available for the Arduino. Thanks to Oliver Kraus (‘Olikrauss’ a complete library is available at https://github.com/olikraus/u8glib/wiki/userreference that documents all functions.. Because every individual pixel in an OLED display can be addressed, simple graphical elements can be designed and displayed such as open and filled circles, circle segments, ellipses, lines, rectangles and triangles. The Brainy Bit logo in sketch #2 is more complex and needs time, effort and much testing to program. In the U8g reference a number of special graphical characters is illustrated. Several font sizes are available It is even possible to pixelize photo images for display in 128×64 in OLED. With the display discussed here, such a bitmapped image will have a 16 pixel high upper yellow band and a lower, 48 pixels high, whitish blue area.
Thanks to the Olikraus library the number of possibilities of displaying mixed graphic/numeric elements are seemingly endless. For prolonged static display however OLEDS seem less suitable. There are reports of ‘burning in’ of pixels in OLED displays and OLED TVs that have been endlessly in ‘ON’ state.
The U8g library does not only work with OLED displays but also with 128×64 LCD graphic displays. Compared with an 128×64 pixel graphic LCD display an OLED display refreshes much faster. The ‘bouncer’ sketch executed with a 128×64 LCD display produces a remarkably slow bouncing ball. On the other hand a 128×64 LCD display is much bigger and that makes it easier to read and for that aspect, an attractive alternative.

Sketches – click to download (sketches are ZIPped)

OLED_128x64_nano_DHT11_led.ino
OLED_128x64_bouncer.ino