Monday, 13 July 2020

OLED displays for your projects - software

OLED display
For all my projects where I need a display, I use the small 1.3" OLEDs with SH1106 controllers and addressed over a two wire SCL/SDA I2C bus. Like this one from Amazon.

I use the superb display library called U8g2 here. This library is a bit heavy for the Arduino UNO as it uses 10-15Kbytes of memory when complied in a project. But I have never run out of memory in anything I have written...

To use my header Oled.h here and the U8g2 library simply include "Oled.h" in your sketch. This will automatically include the "u8g2lib.h" library itself and the I2C comms library "Wire.h". It will also instantiate an object "oled". So your sketch might simply start like this

#include "Oled.h"

You must begin using the library with a begin call in your setup()

oled.begin();

The basic use of the u8g2 library is to have a "display" function which is called to update the display whenever anything new needs to be displayed. This looks like this in your code

dispUpdate();

the function itself, called the display "loop", is written like this example

void dispUpdate() {                                        // picture loop
  oled.firstPage();
  do {
    dispMsg(30, 0, "VFO HOLD");                            // display title
    dispFreq(15, 23, freq / 100, 0, 2);                    // display frequency
    dispMsgS(58, 52, "Step");                              // disp "Step"
    dispStep(80, 50, freqStep / 100);                      // display step freq
  } while ( oled.nextPage() );
}

All the display functions are put within the "do...while" loop.

DISPLAY FUNCTIONS
I made a pre-defined set of functions in this header which make laying out a display simple with consistent use of fonts. These functions are in my Oled.h header file here. They are:

OLED Header

Includes for 
U8g2lib.h and Wire.h

Instantiation for OLED
U8G2_SH1106_128X64_NONAME_1_HW_I2C oled(U8G2_R0);

Functions & usage
// display bar at x, y, h)eight, l)ength (0-100 pixels)
void dispBar(u8g2_uint_t x, u8g2_uint_t y, byte h, byte l)

// display a horzontal line, start x,y, width w
void dispHline(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w)

// display freq at x, y, of f (Hz) plus cf (cHz), to d)ecimal places (max 3)
void dispFreq(u8g2_uint_t x, u8g2_uint_t y, float f, float cf, byte d)

// display freq small at x, y, of f (Hz) plus cf (cHz), to d)ecimal places (max 3)
void dispFreqS(u8g2_uint_t x, u8g2_uint_t y, float f, float cf, byte d)

// display step at x, y, value s)tep (Hz)
void dispStep(u8g2_uint_t x, u8g2_uint_t y, unsigned int s)

// display small message at at x, y, *m)essage
void dispMsgS(u8g2_uint_t x, u8g2_uint_t y, char *m)

// display message at at x, y, *m)essage
void dispMsg(u8g2_uint_t x, u8g2_uint_t y, char *m)

// display large message at at x, y, *m)essage
void dispMsgL(u8g2_uint_t x, u8g2_uint_t y, char *m)

// display ultra large message at at x, y, *m)essage
void dispMsgUL(u8g2_uint_t x, u8g2_uint_t y, char *m)

// display integer - 32 bit
void dispInt(u8g2_uint_t x, u8g2_uint_t y, uint32_t n)

// display number at x, y, n)umber, d)ecimal places
void dispNum(u8g2_uint_t x, u8g2_uint_t y, float n, byte d)

// display number large at x, y, n)umber, d)ecimal places
void dispNumL(u8g2_uint_t x, u8g2_uint_t y, float n, byte d)

// display number ultra large at x, y, n)umber, d)ecimal places
void dispNumUL(u8g2_uint_t x, u8g2_uint_t y, float n, byte d)

// display date "Mon 21 June 2018"
void dispDate(u8g2_uint_t x, u8g2_uint_t y, byte dw, byte da, byte mo, byte yr)

// display time HH:MM:SS at x), y)
void dispTime(u8g2_uint_t x, u8g2_uint_t y, byte h, byte m, byte s)

// display time large HH:MM:SS at x), y)
void dispTimeL(u8g2_uint_t x, u8g2_uint_t y, byte h, byte m, byte s)

x, y display position (top left, down)
h height, time hour, l length
f Hz 
cf      cHz
d decimal place
*m message
n number
dw day of the week
da day
mo month
yr year
m minute
s second, or step, or screen array pointer

Calling these allows me to quickly format and position the major items I need. Messages are easy, as are numbers. But this also give special formatting for Frequency, Dates and Times. Several sizes can be chosen.

Here's a couple of examples, for a VSWR meter and an Audio level meter.



Should you want to it is easy to add your own functions to the Oled.h header. Use a plain text editor and follow the layout of the existing ones already there. You can use any of the functions in the U8g2 library here.

An example of this being used can be found in this sketch here which displays GPS data.

This library and header will work also with the smaller 0.96" OLEDs
 

No comments: