Wednesday 19 April 2017

BASIC Tech Group - MyNews - 41 Moving from LCD to OLED displays - a new header file

I am planning to mount a number of my projects in some, quite small, instrument boxes. I will build a VFO, an RF METER, an SDR, and a PA/LPF/SWR. These boxes will use 1.3" OLED displays. (Note: works also for the smaller 0.96" OLEDs).

IMG 0992

I plan to tidy up the sketches i have for driving OLED displays and consolidate them in a new header file, I call Oled_128X64_I2C.h. This header includes six functions used for displaying the data I need across many applications. They are

OLED Functions dispBar - display a bar graph at x, y, height h and length l, with a surrounding box
dispFreq - display, in a larger font, the frequency at x, y, in d decimal places
dispMsg - display a general text message at x, y
dispNum - display a general number at x, y, d decimal places
dispDate- display the date day-of-week, day, month, year dispTime - display the time at x, y, hours, minute, seconds
dispStep - display the VFO frequency step when tuning, at x, y

The variables used are shown in the functions' outlines above.

Example

Here is an example of the use of the new header file

// test OLED_128x64_I2C with OLED SH1106 display

#include "Oled_128X64_I2C.h"

// display values - global values used to pass them to dispUpdate() function
double a = 7100000;   // freq
double b = 0;          // centi freq
unsigned int c = 1000; // step
byte hr = 12;          // time
byte mn = 3;
byte sc = 33;
double n = 345.6;      // a number
byte hT = 5;          // bar height and length
byte bL = 45;

void setup() {
  oled.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  dispUpdate();
}

// picture loop, display definition data, what, where
void dispUpdate() {
  oled.firstPage();
  do {
    dispMsg(0, 0, "RF");
    dispBar(15, 3, hT, bL);
    dispFreq(10, 15, a, b, 2);
    dispNum(45, 35, n, 2);
    dispTime(10, 50 , hr, mn, sc);
    dispStep(80, 50, c);
  } while ( oled.nextPage() );
}

You can see how simple it makes writing the sketch. Every thing needed, including the constructor for the 1.3" I2C OLED display is in the header file.

IMG 0991 The result of the code above.

IMG 0983 My desk full of OLED displays for my projects.

Code
// oled_128X64_I2C.h
// V1.5 21-4-17 added small & large versions, and date display
// defines oled pins, creates "oled" object for 128x64 SH1106 display
// step now an unsigned int
// functions usage
// void dispBar(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t h, u8g2_uint_t l)
// void dispFreq(u8g2_uint_t x, u8g2_uint_t y, double f, double cf, uint8_t d)
// void dispMsgS(u8g2_uint_t x, u8g2_uint_t y, char *m)
// void dispMsg(u8g2_uint_t x, u8g2_uint_t y, char *m)
// void dispMsgL(u8g2_uint_t x, u8g2_uint_t y, char *m)
// void dispNum(u8g2_uint_t x, u8g2_uint_t y, double n, uint8_t d)
// void dispNumL(u8g2_uint_t x, u8g2_uint_t y, double n, uint8_t d)
// void dispDate(u8g2_uint_t x, u8g2_uint_t y, byte dw, byte da, byte mo, byte yr)
// void dispTime(u8g2_uint_t x, u8g2_uint_t y, byte h, byte m, byte s)
// void dispTimeL(u8g2_uint_t x, u8g2_uint_t y, byte h, byte m, byte s)
// void dispStep(u8g2_uint_t x, u8g2_uint_t y, unsigned int s)


#include "U8g2lib.h"
#include "Wire.h"

// oled object, SH1106 controller, 128X64, HW I2C and normal orientation R0
U8G2_SH1106_128X64_NONAME_1_HW_I2C oled(U8G2_R0);

//=====FUNCTIONS
// display bar at x, y, h)eight, l)ength (0-128 pixels)
void dispBar(u8g2_uint_t x, u8g2_uint_t y, byte h, byte l) {
  byte n;

  oled.drawFrame(x, y, 100, h+1);
  for ( n = 0; n < l; n++) {
    oled.drawLine(x + n, y, x  + n, y + h);
  }
}

// display freq at x, y, f (Hz), cf (cHz), d)ecimal places (max 3)
void dispFreq(u8g2_uint_t x, u8g2_uint_t y, double f, double cf, byte d) {

  // sets font, cursor position and displays freq
  oled.setFont(u8g2_font_10x20_tf); // font
  oled.setFontPosTop(); // origin top

  f = f / 1000.0;
  cf = cf / 100000.0;

  oled.setCursor(x, y);
  oled.print(f + cf, d);
  oled.print("kHz");
}

// fonts github.com/olikraus/u8g2/wiki/fntgrpx11

// display small message at at x), y), *m)essage
void dispMsgS(u8g2_uint_t x, u8g2_uint_t y, char *m) {
  // sets font, cursor position and displays message
  oled.setFont(u8g2_font_5x8_tf); // font
  oled.setFontPosTop();
  oled.setCursor(x, y);
  oled.print(m);
}

// display message at at x), y), *m)essage
void dispMsg(u8g2_uint_t x, u8g2_uint_t y, char *m) {
  // sets font, cursor position and displays message
  oled.setFont(u8g2_font_7x13_tf); // font
  oled.setFontPosTop();
  oled.setCursor(x, y);
  oled.print(m);
}
// display large message at at x), y), *m)essage
void dispMsgL(u8g2_uint_t x, u8g2_uint_t y, char *m) {
  // sets font, cursor position and displays message
  oled.setFont(u8g2_font_10x20_tf); // font
  oled.setFontPosTop();
  oled.setCursor(x, y);
  oled.print(m);
}

// display number at x), y), n)umber (double), d)ecimal places
void dispNum(u8g2_uint_t x, u8g2_uint_t y, double n, byte d) {
    // sets font, cursor position and displays number
  oled.setFont(u8g_font_7x14); // fix font for now
  oled.setFontPosTop();
  oled.setCursor(x, y);
  oled.print(n, d);
}

// display number large at x), y), n)umber (double), d)ecimal places
void dispNumL(u8g2_uint_t x, u8g2_uint_t y, double n, byte d) {
    // sets font, cursor position and displays number
  oled.setFont(u8g2_font_10x20_tf); // font
  oled.setFontPosTop();
  oled.setCursor(x, y);
  oled.print(n, d);
}

// display date
void dispDate(u8g2_uint_t x, u8g2_uint_t y, byte dw, byte da, byte mo, byte yr) {
 // sets font, cursor position and displays message
  oled.setFont(u8g_font_7x14); // fix font for now
  oled.setFontPosTop();
  oled.setCursor(x, y);
  
  switch (dw) {
    case 1:
      oled.print("Mon");
      break;
    case 2:
      oled.print("Tue");
      break;
    case 3:
      oled.print("Wed");
      break;
    case 4:
      oled.print("Thu");
      break;
    case 5:
      oled.print("Fri");
      break;
    case 6:
      oled.print("Sat");
      break;
    case 7:
      oled.print("Sun");
      break;
  }

  oled.print(" ");
  oled.print(da);

  oled.print(" ");
  switch (mo)
  {
    case 1:
      oled.print("Jan");
      break;
    case 2:
      oled.print("Feb");
      break;
    case 3:
      oled.print("Mar");
      break;
    case 4:
      oled.print("Apr");
      break;
    case 5:
      oled.print("May");
      break;
    case 6:
      oled.print("Jun");
      break;
    case 7:
      oled.print("Jul");
      break;
    case 8:
      oled.print("Aug");
      break;
    case 9:
      oled.print("Sep");
      break;
    case 10:
      oled.print("Oct");
      break;
    case 11:
      oled.print("Nov");
      break;
    case 12:
      oled.print("Dec");
      break;
  }
  oled.print(" ");
  oled.print("20");
  oled.print(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) {
  // sets font, cursor position and displays message
  oled.setFont(u8g_font_7x14); // fix font for now
  oled.setFontPosTop();
  oled.setCursor(x, y);
  if (h < 10)
    oled.print("0");
  oled.print(h);
  oled.print(":");
  if (m < 10)
    oled.print("0");
  oled.print(m);
  oled.print(":");
  if (s < 10)
    oled.print("0");
  oled.print(s);
}

// display time HH:MM:SS at x), y)
void dispTimeL(u8g2_uint_t x, u8g2_uint_t y, byte h, byte m, byte s) {
  // sets font, cursor position and displays message
  oled.setFont(u8g2_font_10x20_tf); // font
  oled.setFontPosTop();
  oled.setCursor(x, y);
  if (h < 10)
    oled.print("0");
  oled.print(h);
  oled.print(":");
  if (m < 10)
    oled.print("0");
  oled.print(m);
  oled.print(":");
  if (s < 10)
    oled.print("0");
  oled.print(s);
}

// display step at x) y) s)tep
void dispStep(u8g2_uint_t x, u8g2_uint_t y, unsigned int s) {
  // set font, cursor position and display step
  oled.setFont(u8g_font_7x14); // fix font for now
  oled.setFontPosTop();
  
  oled.setCursor(x, y);
  switch (s) // display freqStep
  {
    case 10:
      oled.print(" 10Hz");
      break;
    case 100:
      oled.print("100Hz");
      break;
    case 1000:
      oled.print(" 1kHz");
      break;
    case 10000:
      oled.print(" 10kHz");
      break;
    case 100000:
      oled.print("100kHz");
      break;
    case 1000000:
      oled.print(" 1MHz");
      break;
  }
}

No comments: