1

I hope this the right place to post this question :)

I'm trying to display a menu on a SSD1351 OLED display, to which I communicate with U8glib. I'm trying to obtain an Init screen, then, with a long press on a button (Menu), get in to a menu with 3 options (let's say option1, option2 and back). I got it working this way:

#include <Button.h>  // https://github.com/JChristensen/Button.git
#include "U8glib.h"
#include <Wire.h>

#define PULLUP true
#define INVERT true
#define DEBOUNCE_MS 20

Button ok(2, PULLUP, INVERT, DEBOUNCE_MS);
Button menu(5, PULLUP, INVERT, DEBOUNCE_MS);
Button down(3, PULLUP, INVERT, DEBOUNCE_MS);
Button up(4, PULLUP, INVERT, DEBOUNCE_MS);
U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7);
uint8_t screen = 0;
uint8_t menu_current = 0;
void setup() {
  u8g.setFont(u8g_font_unifont);
  u8g.setDefaultForegroundColor();
  drawScreen();
}

void loop() {
  ok.read();
  menu.read();
  up.read();
  down.read();
  if (menu.pressedFor(1000) && screen == 0) {
    screen = 1;
    menu_current = 0;
    drawScreen();
  }
  if (screen == 1) {
    if (up.wasReleased()) {
      if (menu_current > 0) {
        menu_current--;
        drawScreen();
      }
    }
    if (down.wasReleased()) {
      if (menu_current < 2) {
        menu_current++;
        drawScreen();
      }
    }
    if (ok.wasReleased()) {
      switch (menu_current) {
        case 0:
          screen = 2;
          break;
        case 1:
          screen = 3;
          break;
        case 2:
          screen = 0;
          break;
          break;
      }
      drawScreen();
    }
  }
  if (screen == 2 || screen == 3) {
    if (menu.wasReleased()) {
      screen = 1;
      menu_current = 0;
      drawScreen();
    }
  }
}

void drawScreen() {
  u8g.firstPage();
  do {
    whatToDraw();
  } while (u8g.nextPage());
}

void whatToDraw() {
  switch (screen) {
    case 0: {
        u8g.drawStr(0, u8g.getFontLineSpacing(), F("Init"));
      } break;
    case 1: {
      const char *menu_strings[3] = { "option1", "option2", "Back" };
      uint8_t i, h;
      u8g_uint_t w, d;
      u8g.setFontRefHeightText();
      u8g.setFontPosTop();
      h = u8g.getFontAscent() - u8g.getFontDescent();
      w = u8g.getWidth();
      for ( i = 0; i < 3; i++ ) {
        d = (w - u8g.getStrWidth(menu_strings[i])) / 2;
        u8g.setDefaultForegroundColor();
        if ( i == menu_current ) {
          u8g.drawBox(0, i * h + 1, w, h);
          u8g.setDefaultBackgroundColor();
        }
        u8g.drawStr(d, i * h, menu_strings[i]);
      }
    }
    break;
    case 2: {
      u8g.drawStr(0, u8g.getFontLineSpacing(), F("Option1"));
    }
    break;
    case 3: {
      u8g.drawStr(0, u8g.getFontLineSpacing(), F("Option2"));
    }
    break;
    break;
  }
}

Everything seems to be working except the back option: when I select it, the display gets blanked instead of visualizing screen 0 ("Init"). Variables seem to be set correctly. Does anybody have an idea why this isn't working?

Thank you :)

Dario

EDIT: copied the whole sketch as requested :)

9
  • Please, post your whole sketch, so others can test your code.
    – user31481
    Jul 22 '17 at 17:54
  • I don't see any back option; only up, down, ok and menu. What button was that?
    – user31481
    Jul 22 '17 at 18:29
  • I didn't define a back back physical button. "Back" is one of the options visualized in the menu. I'd like to be able to select it (highlight it with up and down buttons) and click the Ok button, to revert to Init screen :)
    – noospy
    Jul 22 '17 at 18:38
  • Correct me. Your test case is: screen 0; press menu; screen 1; press down; press down; Press OK over option BACK and then screen goes blank?
    – user31481
    Jul 22 '17 at 20:00
  • I only miss an u8g2.begin(), but all your execution paths include a drawScreen() call, and you always put something in the screen. You don't modify global vars inside de drawScreen() and it's the only place where you touch the screen. Good problem.
    – user31481
    Jul 22 '17 at 20:12
1

Summary: I tested @noospy project (with some modifications) and it works flawlessly.

Menu and buttons

I had to rename Button.h to ButtonM.h due name conflict with another button library. Also, I'm using new version U8g2, so I had to change some types and eliminate some calls. Finally, I used the I2C version of the OLED screen.

This is my adapted code:

#include <ButtonM.h>  // https://github.com/JChristensen/Button.git
#include "U8g2lib.h"
#include <Wire.h>

#define PULLUP true     
#define INVERT true    
#define DEBOUNCE_MS 20   

Button ok(2, PULLUP, INVERT, DEBOUNCE_MS);  
Button menu(5, PULLUP, INVERT, DEBOUNCE_MS);
Button down(3, PULLUP, INVERT, DEBOUNCE_MS);
Button up(4, PULLUP, INVERT, DEBOUNCE_MS);

//U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7);
// Screen
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

uint8_t screen = 0;
uint8_t menu_current = 0;

void setup() {    
    u8g.begin(); // Added
    u8g.setFont(u8g_font_unifont);       
//  u8g.setDefaultForegroundColor();

    drawScreen(); 
}

void loop() {
    ok.read();
    menu.read();
    up.read();
    down.read();

    if (menu.pressedFor(1000) && screen == 0) {       
        screen = 1;    
        menu_current = 0;
        drawScreen();
    }

    if (screen == 1) {
        if (up.wasReleased()) {       
            if (menu_current > 0) {
                menu_current--;
                drawScreen();
            }
        }

        if (down.wasReleased()) {       
            if (menu_current < 2) {
                menu_current++;
                drawScreen();
            }
        }

        if (ok.wasReleased()) {       
            switch (menu_current) {          
                case 0: 
                    screen = 2;
                    break;
                case 1:
                    screen = 3;
                    break;
                case 2:
                    screen = 0;
                    break;
                break;
            }
            drawScreen();
        }
    }

    if (screen == 2 || screen == 3) {
        if (menu.wasReleased()) {
            screen = 1;
            menu_current = 0;
            drawScreen();
        }
    }
}

void drawScreen() {
    u8g.firstPage();  
    do {
        whatToDraw();
    } while( u8g.nextPage() );
}

void whatToDraw() {
    switch (screen) {
        case 0: {                           
            u8g.drawStr(0,getFontLineSpacing(),"Init");
        } break;
        case 1: {   
            const char *menu_strings[3] = { "option1", "option2", "Back" };
            uint8_t i, h;
            int w, d;

            u8g.setFontRefHeightText();
            u8g.setFontPosTop();

            h = u8g.getFontAscent()-u8g.getFontDescent();
            w = u8g.getWidth();
            for( i = 0; i < 3; i++ ) {
                d = (w-u8g.getStrWidth(menu_strings[i]))/2;
//                u8g.setDefaultForegroundColor();
                if ( i == menu_current ) {
                    u8g.drawBox(0, i*h+1, w, h);
//                    u8g.setDefaultBackgroundColor();
                }
                u8g.drawStr(d, i*h, menu_strings[i]);
            }
         } break;

         case 2: {                         
             u8g.drawStr(0,getFontLineSpacing(),"Option1");
         } break;

         case 3: {                        
             u8g.drawStr(0,getFontLineSpacing(),"Option2");
         } break;

         break;
    }
}

int getFontLineSpacing() {
  return 24;
}

Hardware

  1. Arduino Pro Mini 3.3v 8MHz
  2. 1306 0.96 inch White Color I2C IIC Communication 128 * 64 OLED Display.
  3. 4x push buttons with 1K pullup resistors.

So, I don't know what your problem is, but your code is impecable.

1
  • Thank you! Well, at least now I know it's not a coding issue. I'll try with your same hardware and report back!
    – noospy
    Jul 25 '17 at 19:09
0

You can consider using one of the existing menu libraries, there are some available on github. Just pick the one that best fits your needs

https://github.com/search?utf8=%E2%9C%93&q=arduino+menu&type=

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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