I want to make a project with a (Nokia 5110) display using u8g2 library. Here I have the code for my program:

#include <Arduino.h>
#include <U8g2lib.h>
#include <TM1637Display.h>
#include <EEPROM.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>

#define LED_PIN 5
#define BUTTON_PIN 6
#define BUZZ_PIN 7
#define BUTTON_L 2
#define BUTTON_R 3
#define BUTTON_START 4

//48x84 disp.
U8G2_PCD8544_84X48_F_4W_SW_SPI u8g2(U8G2_R2, 13, 11, 10, 12, 8); //rotate, clk, DIN, CE, DC, RST //

byte lastButtonState = 0;
byte ledState;
float cpu_gauge = 0.0;
char buffer[40];
int move = 7;
float cpu_gauge_step = 0.5;
byte eeprom_led;

void set_led(){
  if( digitalRead(LED_PIN) == 1 ) ledState = 1;
      if( digitalRead(LED_PIN) == 0 ) ledState = 0;}

void backlight(){
byte buttonState = digitalRead(BUTTON_PIN);  //monitor button state
  if (buttonState != lastButtonState) {  //check if not equal
    lastButtonState = buttonState;       //if prev. true, make equal
      if (buttonState == HIGH) {                
        ledState = (ledState == HIGH) ? LOW : HIGH;
          digitalWrite(LED_PIN, ledState);    }}}

void status_bar(){
  if (cpu_gauge > cpu_gauge_step*1) u8g2.drawBox(2,13,6,8); //x, y , size in x, size in y
    if (cpu_gauge > cpu_gauge_step*2) u8g2.drawBox(2 + 1*move,13,6,8);     
      if (cpu_gauge > cpu_gauge_step*3) u8g2.drawBox(2 + 2*move,13,6,8);   
        if (cpu_gauge > cpu_gauge_step*4) u8g2.drawBox(2 + 3*move,13,6,8);   
          if (cpu_gauge > cpu_gauge_step*5) u8g2.drawBox(2 + 4*move,13,6,8);     
            if (cpu_gauge > cpu_gauge_step*6) u8g2.drawBox(2 + 5*move,13,6,8);     
              if (cpu_gauge > cpu_gauge_step*7) u8g2.drawBox(2 + 6*move,13,6,8);      
                if (cpu_gauge > cpu_gauge_step*8) u8g2.drawBox(2 + 7*move,13,6,8);  
                  if (cpu_gauge > cpu_gauge_step*9) u8g2.drawBox(2 + 8*move,13,6,8);      
                    if (cpu_gauge >= cpu_gauge_step*10) u8g2.drawBox(2 + 9*move,13,6,8); 

void setup(void) {
  pinMode(LED_PIN, OUTPUT);
    pinMode(BUTTON_PIN, INPUT);
      pinMode(BUZZ_PIN, OUTPUT);
       pinMode(BUTTON_L, INPUT);
        pinMode(BUTTON_R, INPUT);
          pinMode(A7, INPUT);
            pinMode(BUTTON_START, INPUT);
              eeprom_led = EEPROM.read(0);
                digitalWrite(LED_PIN, eeprom_led);
                  set_led(); //sets the led state to 1 or 0 depending on digital write


void loop(void) {
    /*pomiar = EEPROM[ 0 ];
    int pomiar = digitalRead(BUTTON_START);

  cpu_gauge = analogRead(A7) * (5.0/1022);

  do {
  u8g2.drawRFrame(0,12,74,10,3); //pos X,Y  length, width, corner
      char pomiar_str[5];
        dtostrf(cpu_gauge,0,2, pomiar_str);
          sprintf(buffer, "LOAD: %sV", pomiar_str);

        sprintf(buffer, "led: %d", ledState);
  if (cpu_gauge > 4.80){
          u8g2.drawGlyph(27, 48, 0x0040);}

  } while ( u8g2.nextPage() );}

I have succesfully made a program, that:

-Has a pushbutton, to turn off, and on the backlight with each press
-Writes to the EEPROM the state of the LED, and reads it at startup
-Displays an analogRead value, from the potentiometer and also displays a progress bar of the given value
-Displays the state of the backlight
-Turns on the buzzer, if the analogRead value exceedes some value
-Displays an indicator, if the buzzer is turned on

Now, let's assume that what this program does, is called option "A", and A in this example works all the time, because there is nothing else. I want to create a menu, that would have option A, B, C, D. Assume that formatting and pushbutton actions, doesn't matter for now.

A: Is what was described before.
B: Clock. Just display a clock.
C: Stopwatch.
D: Setting the time.

I see two ways of creating such menu.

1: Is to build a selectable/scrollable menu that would have labels, and by choosing, and pressing a button, we would enter desired function.
2: Ditch the selectable menu. One pushbutton will switch from option A to D. Something like a casio watch.

I'd prefer the second option, I think it'll be easier to do

What I don't understand, is the U8G2 reference manual. I don't really understand the concept of the buffer, sendBuffer, userInterfaceSelectionList, and some more stuff, that I can't name for now.

My understanding is, that i have to make some array, of functions. Like:

Array [] = {default_display();, clock();, stopwatch();, setting();)

And with a button, I'd go thru this array like so:

Array = 0;
 If (digitalRead(some_button_pin) == High){
  Array + 1;}
If (Array > 3){
 Array = 0;}

And in those funtions, it would have implemented options, like the backlight turned on, or something else, whatever,

Now I don't know if that makes any sense. If it's transferable into code. I don't know if I need to clear the display, and how do I do that only once before entering the option. How do I make it, so that all the variables related to clock, the stopwatch still work even if I'm not displaying it. I'm honestly lost, and I just need guidance with this, becuase I have only had C for 1 semester at Electrical Engineering. I'm not a programist, but I really want to make it work, but it just isn't explained in the way like I don't know, pulldown resistors, where you can make some assumptions, and with them explain how something works. No, it looks like this:

void u8g2_SetBufferPtr(u8g2_t *u8g2, uint8_t *buf)

And yeah, I just don't know how do I go around it, how do I navigate in it. Thank you for any help.

  • your code is very badly formatted ... for example, the if statements inside void status_bar() function are not nested, they should all be indented the same amount ... same with the program lines in the setup() function
    – jsotola
    Dec 12, 2022 at 0:31
  • I'm sorry, I wasn't teached/haven't studied coding ethics, in sense of formatting. Code was easily readable to me, and I could easily find the parts I needed :) Next time I will use Autoformatting before posting
    – kshysztof
    Dec 12, 2022 at 0:47
  • btw why do you use software SPI for the display?
    – Juraj
    Dec 14, 2022 at 17:37
  • Because it's a 5110 display, and it only supports SPI communication, as far as I know
    – kshysztof
    Dec 14, 2022 at 17:44

1 Answer 1


I have figured it out. First thing that has to be said. If you're used to creating function definitions before the setup, you can't do that with u8g2 library. You can create function definitions after calling u8g2.begin in setup. Now there are two ways how you can do it, in the "Casio watch" fashion, but first create a varaible that will read how many times you've clicked, and store that somewhere, and add a condition, that will revert it to 1 after some amount of clicks. 1st way: Create a switch case, where the variable will be your switch, and in the cases (x to n) write what you want, graphics, text, whatever. Now the problem that I've had, is that when I've pasted the same code, and changed only some minor text, the whole thing glitched. It went through 1 and 2, normally, and then everything from case 3 and 4 was merged toghether, and case 4 was empty, and so was the screen. I couldn't fix it, so I came up with the second approach. Create as many IF conditions, as you have menu option. So it goes like this: If (menu_counter == 1){ //your input to the screen// } And so for the rest. As far as I have tested this, it works, even if the code is the same for both IF statements. Now I'd have to implement the menu selection list on top. Leaving the answer to my own question, hopefully someone will find it useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.