/* myU8G2Display Helper routines for U8g2lib
PM wiegand, July 2024
This file is a demonstration sketch. Copy and paste the functions below (except for setup and loop of course) into your own sketch
Usage:
1. use #define myU8G2Display your_dispay_name to have the compiler replace the default display names with your own
2. use the desired constructor with your_display_name as the object name, and specify buffer size as F, 1 or 2
3. .begin() the display object and
4. .setFont before using the helper functions
5. The functions just write to the buffer. Remember to send the buffer(s) to the display using either .sendBuffer() for 'F' or firstPage()/nextPage() for "1" or "2"
*/
//#define FULL //for demo sketch: uncomment if using F in the constructor (full page mode)
#define PAGED //for demo sketch: uncomment if using 1 or 2 in the constructor (loop and send partial pages each time using smaller buffer)
#include <U8g2lib.h> //the constructor HW_I2C part will tell the u8g2 library to load wire.h so you don't need to explicity include it
#define myU8G2Display oled //put the name of your diplay here (I used 'oled' in the constructor below)
#ifdef FULL
U8G2_SSD1306_128X64_NONAME_F_HW_I2C oled(U8G2_R0, /* reset=*/U8X8_PIN_NONE); //I used 'oled' as the name for my display
#endif
#ifdef PAGED
U8G2_SSD1306_128X64_NONAME_1_HW_I2C oled(U8G2_R0, /* reset=*/U8X8_PIN_NONE); //I used 'oled' as the name for my display
#endif
void drawFancyString(unsigned int x, unsigned int y, char* myString, bool invert = false, bool underline = false) {
//provides for inverted or underlined text at any x and y position on the display
//set invert to true for black on white lettering. Set underline to true for white on black underlined text
//because of defaults, this must be placed above any code that calls it.
unsigned int boxWidth = myU8G2Display.getStrWidth(myString);
unsigned int boxHeight = myU8G2Display.getMaxCharHeight();
boxHeight = boxHeight + 3; //adjust this if desired: puts box boundaries a bit outside of text
if (invert == true) {
myU8G2Display.setDrawColor(1); //pixel is on
myU8G2Display.drawBox(x, y, boxWidth, boxHeight);
myU8G2Display.setDrawColor(0); //now set pixel to dark
myU8G2Display.drawStr(x, y, myString); //draw dark on light box background
myU8G2Display.setDrawColor(1); //be nice and set color back to normal
} else {
myU8G2Display.setDrawColor(1); //not inverted so don't need to draw box. Just normal print
myU8G2Display.drawStr(x, y, myString);
}
if (underline == true) {
myU8G2Display.setDrawColor(1);
myU8G2Display.drawHLine(x, y + oled.getAscent() + 2, boxWidth); //adjust if desired, puts underline one pixel below bottom of non-descended text
}
}
unsigned int drawCenteredString(unsigned int y, char* myString, bool invert = false, bool underline = false, bool rJustified = false) {
//provides horizontal centering (or right justified) on the display. Returns the starting x-position, which can be used to align other text to the centered text
//to provide black on white lettering set invert to true. To underline set underline to true, rJustified = true means RJ instead of center
//Note because of defaults, this function must be placed above any code that calls it.
unsigned int centered_x = (myU8G2Display.getDisplayWidth() - myU8G2Display.getStrWidth(myString)) / 2; //calculation for centered text
if (rJustified == true) {
centered_x = (myU8G2Display.getDisplayWidth() - myU8G2Display.getStrWidth(myString)); //calculation for right justified text
}
unsigned int boxWidth = myU8G2Display.getStrWidth(myString);
unsigned int boxHeight = myU8G2Display.getMaxCharHeight();
boxHeight = boxHeight + 3;
if (invert == true) {
myU8G2Display.setDrawColor(1);
myU8G2Display.drawBox(centered_x, y, boxWidth, boxHeight);
myU8G2Display.setDrawColor(0);
myU8G2Display.drawStr(centered_x, y, myString);
myU8G2Display.setDrawColor(1);
} else {
myU8G2Display.setDrawColor(1);
myU8G2Display.drawStr(centered_x, y, myString);
}
if (underline == true) {
myU8G2Display.setDrawColor(1);
myU8G2Display.drawHLine(centered_x, y + oled.getAscent() + 2, boxWidth);
}
return centered_x; //return the starting x position of centered string
}
unsigned int newLine(unsigned int oldYPos, unsigned int sep = 1) {
//calculates the y position in pixels for a new line, given the position of the old line
unsigned int lineHeight = myU8G2Display.getMaxCharHeight() + sep; // gives a small separation between ines if invert is used, 1 is good for normal text
unsigned int newYPos = oldYPos + lineHeight;
return newYPos;
}
unsigned int centerVertical(unsigned int numLines) {
//allows centering 1 or more lines vertically on the display. Provide the number of lines to center.
//returns the y position for the first line in the group. Use newLine to get the y positions of the other lines
unsigned int lineHeight = myU8G2Display.getMaxCharHeight() + 3;
unsigned int dispUsed = lineHeight * numLines;
unsigned int dispLeft = myU8G2Display.getDisplayHeight() - dispUsed;
unsigned int startYPos = dispLeft / 2;
return startYPos;
}
void setup() {
Serial.begin(9600);
oled.begin();
oled.setFontPosTop(); // 0,0 is top left of display. We want the top of the font to also be at 0 for first line
//myU8G2Display.setFlipMode(1); //uncomment this if your display is mounted upside down
}
void loop() {
int bufferNum = 0;
oled.clearBuffer(); //start with a blank display
oled.setFont(u8g2_font_pressstart2p_8r); // choose a suitable font
oled.setCursor(0, 0); //start printing as upper left corner of display
oled.firstPage();
#ifdef PAGED //using paged mode so we need to tell compiler to compile the do loop
do {
#endif
oled.print("VCenter 3 lines:"); //can just use normal print statement for this
unsigned int startYPos = centerVertical(3); //want to center the next three lines vertically on the display. startYPos is the y for the first line
drawFancyString(0, startYPos, "Inverted", true, false); //draw black on solid white background
unsigned int newYPos = newLine(startYPos); //calculate the y position for the next line based on current font height
unsigned int cx = drawCenteredString(newYPos, "rJustified", false, false, true); //draw this string centered horizontally, save the starting x for next line
newYPos = newLine(newYPos);
drawFancyString(cx, newYPos, "Underlined", false, true); //use starting x from previous line to align the two lines
#ifdef FULL //using the full page mode, don't need the do loop but we do need the send buffer command
oled.sendBuffer(); //this actually causes the display to show the text for a full (nonbuffered) constructor. Use firstpage/nextpage approach if your constructor specifies buffering
Serial.println("Sent 1K buffer to display");
#endif
#ifdef PAGED
bufferNum++;
Serial.println("buffer page " + String(bufferNum) + " sent to display");
} while (oled.nextPage());
#endif
do {
} while (true); //this waits forever. Could also comment this out and the display will be constantly re-drawing the same thing
}