Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: Menu system on Teensy3 and OLED (SSD1306)

  1. #1
    Junior Member
    Join Date
    Oct 2013
    Posts
    10

    Menu system on Teensy3 and OLED (SSD1306)

    Hi,

    Can anyone offer any advice on any libraries out there I can use to implement a multi level menu system for an OLED screen, I would like to use 5 buttons, left, right, up, down and enter for navigation. I've tried googling but have not found anything out there.

    If there are not any libraries if there are any projects with source code I can reverse engineer I'd love to find out.

    This is the main part of my project and I will build upon the menu once it works smoothly, I will be happy to share my progress as it develops.

    So any help would be greatly appreciated so I can get moving on my project, I'm feeling eager to get on with it.

    The typical use would be

    '=' Top Menu
    '==' Sub Menu
    '===' Menu item

    Menu structure
    = Main menu
    == Set up
    === Set temp
    === Set time
    == Display
    === Show temp
    === Show time

  2. #2
    Junior Member
    Join Date
    Oct 2013
    Posts
    10
    So I have managed to solve this myself, anyone else who is looking for basic code for a menu for a OLED here it is
    Code:
    /*
      OLED Menu System
      
      Created by Dean, 10th October 2013.
      
      Menu Library from http://jonblack.org/
      OLED Library from Adafruit
    */
    
    #include <MenuSystem.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306h.h>
    
    //DEFINES
    #define OLED_DC 8
    #define OLED_CS 10
    #define OLED_CLK 13
    #define OLED_MOSI 11
    #define OLED_RESET 7
    Adafruit_SSD1306h display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
    
    // Menu variables
    MenuSystem ms;
    Menu mm("");
    Menu mu1("Display");
    MenuItem mu1_mi1("Display1");
    MenuItem mu1_mi2("Display2");
    MenuItem mu1_mi3("Display3");
    Menu mu2("Settings");
    MenuItem mu2_mi1("Settings1");
    MenuItem mu2_mi2("Settings2");
    MenuItem mu2_mi3("Settings3");
    
    // Example variables
    const int UpBtn = 5;       // the number of the pushbutton pin
    const int DownBtn = 4;     // the number of the pushbutton pin
    const int SelectBtn = 3;   // the number of the pushbutton pin
    const int BackBtn = 2;     // the number of the pushbutton pin
    int UpButtonState = 0;     // variable for reading the pushbutton status
    int DownButtonState = 0;   // variable for reading the pushbutton status
    int SelectButtonState = 0; // variable for reading the pushbutton status
    int BackButtonState = 0;   // variable for reading the pushbutton status
    bool bRanCallback = false;
    bool bForward = true;
    int line = 10;             // variable for setting display line
    
    // Menu callback function
    // In this example all menu items use the same callback.
    
    void on_display1_selected(MenuItem* p_menu_item)
    {
      //Serial.println("DISPLAY1 Selected");
      display.setCursor(0,55);
      display.print("DISPLAY1 Selected");
      bRanCallback = true;
      bForward = true;
    }
    void on_display2_selected(MenuItem* p_menu_item)
    {
      //Serial.println("DISPLAY2 Selected");
      display.setCursor(0,55);
      display.print("DISPLAY2 Selected");
      //bRanCallback = false;
      bForward = true;
    }
    void on_display3_selected(MenuItem* p_menu_item)
    {
      //Serial.println("DISPLAY3 Selected");
      display.setCursor(0,55);
      display.print("DISPLAY3 Selected");
      bRanCallback = false;
      bForward = true;
    }
    
    void on_settings1_selected(MenuItem* p_menu_item)
    {
      //Serial.println("SETTINGS1 Selected");
      display.setCursor(0,55);
      display.print("SETTINGS1 Selected");
      bRanCallback = true;
      bForward = true;
    }
    void on_settings2_selected(MenuItem* p_menu_item)
    {
      //Serial.println("SETTINGS2 Selected");
      display.setCursor(0,55);
      display.print("SETTINGS2 Selected");
      bRanCallback = false;
      bForward = true;
    }
    void on_settings3_selected(MenuItem* p_menu_item)
    {
      //Serial.println("SETTINGS3 Selected");
      display.setCursor(0,55);
      display.print("SETTINGS3 Selected");
      //bRanCallback = false;
      bForward = true;
    }
    
    // Standard arduino functions
    
    void setup()
    {
      Serial.begin(9600);
      
    // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
      display.begin(SSD1306h_SWITCHCAPVCC);
      
        // initialize the pushbutton pin as an input:
      pinMode(UpBtn, INPUT); 
        // initialize the pushbutton pin as an input:
      pinMode(DownBtn, INPUT); 
          // initialize the pushbutton pin as an input:
      pinMode(SelectBtn, INPUT); 
          // initialize the pushbutton pin as an input:
      pinMode(BackBtn, INPUT); 
      
      display.display(); 		// show splashscreen
      delay(2000);
      display.clearDisplay();   // clears the screen and buffer
      
    // Menu setup
      mm.add_menu(&mu1);
      mu1.add_item(&mu1_mi1, &on_display1_selected);
      mu1.add_item(&mu1_mi2, &on_display2_selected);
      mu1.add_item(&mu1_mi3, &on_display3_selected);
      mm.add_menu(&mu2);
      mu2.add_item(&mu2_mi1, &on_settings1_selected);
      mu2.add_item(&mu2_mi2, &on_settings2_selected);
      mu2.add_item(&mu2_mi3, &on_settings3_selected);
      ms.set_root_menu(&mm);
    }
    
    void loop()
    {
    //OLED set up
      display.display(); 		
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      line=10; //line variable reset
      //Serial.println("");
      
      
    // Display Title
      display.setCursor(0,0);
      display.println("MENU");
      
    // Display the menu
      Menu const* cp_menu = ms.get_current_menu();
      MenuComponent const* cp_menu_sel = cp_menu->get_selected();
      for (int i = 0; i < cp_menu->get_num_menu_components(); ++i)
      {
        MenuComponent const* cp_m_comp = cp_menu->get_menu_component(i);
        //Serial.print(cp_m_comp->get_name());
        display.setCursor(30,line);
        display.print(cp_m_comp->get_name());
        
        if (cp_menu_sel == cp_m_comp){
          //Serial.print("<<< ");
          display.setCursor(0,line);
          display.print(">>> ");
        }
        line=line+10;
        //Serial.println("");
      } 
     
    // read the state of the pushbutton value:
      UpButtonState = digitalRead(UpBtn);
      if (UpButtonState == HIGH) {    
        ms.prev(); 
      } 
      
      DownButtonState = digitalRead(DownBtn);
      if (DownButtonState == HIGH) {   
        ms.next();  
      } 
    
      SelectButtonState = digitalRead(SelectBtn);
      if (SelectButtonState == HIGH) {   
        ms.select();  
      } 
      
      BackButtonState = digitalRead(BackBtn);
      if (BackButtonState == HIGH) {   
        ms.back();  
      } 
     
      
    // Wait for two seconds so the output is viewable
      delay(500);
    }
    Library is available from http://jonblack.org/2012/05/14/ardui...a-menu-system/
    Last edited by Dean; 10-10-2013 at 09:05 PM.

  3. #3
    Junior Member
    Join Date
    Oct 2013
    Posts
    10
    Next on the list,

    How to get the buttons to work as interrupts?
    and add a better way of displaying output notice i.e display.print("DISPLAY2 Selected");

  4. #4

    Menu system on Teensy3 and OLED (SSD1306)

    Hello
    If it's possible, please, post <MenuSystem.h> for this code. The download link, it's not working.
    Thank you in advance.

  5. #5
    Senior Member
    Join Date
    Aug 2014
    Posts
    125
    I think the library is the following: https://github.com/jonblack/arduino-menusystem

  6. #6
    Thank you !!!

  7. #7

    Help!

    Hello of Dean! Can you help me? Немогу to add a new menu item. Can you describe more detailed description? How to add the menu item? Already week I sit above a code. Below my code.

    PHP Code:
    #include <MenuSystem.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>

    //Пины
    #define OLED_MOSI   9
    #define OLED_CLK   10
    #define OLED_DC    11
    #define OLED_CS    12
    #define OLED_RESET 13
    Adafruit_SSD1306 display(OLED_MOSIOLED_CLKOLED_DCOLED_RESETOLED_CS);

    // Menu variables
    MenuSystem ms;
    Menu mm("");
    Menu mu1("Display");
    MenuItem mu1_mi1("Display1");
    MenuItem mu1_mi2("Display2");
    MenuItem mu1_mi3("Display3");
    Menu mu2("Settings");
    MenuItem mu2_mi1("Settings1");
    MenuItem mu2_mi2("Settings2");
    MenuItem mu2_mi3("Settings3");
    Menu mu3("Ethernet");
    MenuItem mu3_mi1("Set1");
    MenuItem mu3_mi2("Set2");
    MenuItem mu3_mi3("Set3");

    // Объявления переменных и констант
    const int buttonPin 0;   // аналоговый вход для кнопок

    int buttonValue 0;   // переменная для значения АЦП кнопки
    int UpButtonState 0;     // переменная для кнопки вверх
    int DownButtonState 0;   // переменная для кнопки вниз
    int SelectButtonState 0// переменная для кнопки выбора
    int BackButtonState 0;   // переменная для кнопки возврата

    bool bRanCallback false;
    bool bForward true;

    int line 30;             // переменная для установки настроек в линию


    // Функция меню обратного вызова
    // В этом примере все пункты меню можно использовать для обратного вызова.

    void on_display1_selected(MenuItemp_menu_item)
    {
      
    Serial.println("DISPLAY1 Selected");
      
    display.setCursor(0,55);
      
    display.print("DISPLAY1 Selected");
      
    bRanCallback true;
      
    bForward true;
    }
    void on_display2_selected(MenuItemp_menu_item)
    {
      
    Serial.println("DISPLAY2 Selected");
      
    display.setCursor(0,55);
      
    display.print("DISPLAY2 Selected");
      
    //bRanCallback = false;
      
    bForward true;
    }
    void on_display3_selected(MenuItemp_menu_item)
    {
      
    Serial.println("DISPLAY3 Selected");
      
    display.setCursor(0,55);
      
    display.print("DISPLAY3 Selected");
      
    bRanCallback false;
      
    bForward true;
    }

    void on_settings1_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS1 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS1 Selected");
      
    bRanCallback true;
      
    bForward true;
    }
    void on_settings2_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS2 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS2 Selected");
      
    bRanCallback false;
      
    bForward true;
    }
    void on_settings3_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS3 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS3 Selected");
      
    //bRanCallback = false;
      
    bForward true;
    }

    void on_set1_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS1 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS1 Selected");
      
    bRanCallback true;
      
    bForward true;
    }
    void on_set2_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS2 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS2 Selected");
      
    bRanCallback false;
      
    bForward true;
    }
    void on_set3_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS3 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS3 Selected");
      
    //bRanCallback = false;
      
    bForward true;
    }
    // Standard arduino functions

    void setup()
    {
      
    Serial.begin(9600);
      
    // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
      
    display.begin(SSD1306_SWITCHCAPVCC);
      
      
      
    display.display();         // show splashscreen
      
    delay(1000);
      
    display.clearDisplay();   // clears the screen and buffer
      
    // Menu setup
      
    mm.add_menu(&mu1);
      
      
    mu1.add_item(&mu1_mi1, &on_display1_selected);
      
    mu1.add_item(&mu1_mi2, &on_display2_selected);
      
    mu1.add_item(&mu1_mi3, &on_display3_selected);
      
      
    mm.add_menu(&mu2);
      
      
    mu2.add_item(&mu2_mi1, &on_settings1_selected);
      
    mu2.add_item(&mu2_mi2, &on_settings2_selected);
      
    mu2.add_item(&mu2_mi3, &on_settings3_selected);
      
      
    mm.add_menu(&mu3);
      
      
    mu3.add_item(&mu3_mi1, &on_set1_selected);
      
    mu3.add_item(&mu3_mi2, &on_set2_selected);
      
    mu3.add_item(&mu3_mi3, &on_set3_selected);
      
      
    ms.set_root_menu(&mm);
    }

    void loop()
    {
      
    buttonValue analogRead(buttonPin);
      
    Serial.println(buttonValue);
      
    //OLED set up
      
    display.display();         
      
    display.clearDisplay();
      
    display.setTextSize(1);
      
    display.setTextColor(WHITE);
      
    line=15//line variable reset
      
    Serial.println("//OLED set up");
      
      
    // Display Title

      
    display.setCursor(10,0);
      
    display.println("MENU CONFIGURATION");
      
    display.setCursor(0,5);
      
    display.print("_____________________");
      
    display.setCursor(110,15);
      
    Serial.println("//OLED");
     
    // Display the menu
      
    Menu const* cp_menu ms.get_current_menu();
      
    MenuComponent const* cp_menu_sel cp_menu->get_selected();
      for (
    int i 0cp_menu->get_num_menu_components(); ++i)
      {
        
    MenuComponent const* cp_m_comp cp_menu->get_menu_component(i);
        
    Serial.println(cp_m_comp->get_name());
        
    display.setCursor(10,line);
        
    display.print(cp_m_comp->get_name());
        
        if (
    cp_menu_sel == cp_m_comp){
          
    Serial.print("<<< ");
          
    display.setCursor(0,line);
          
    display.write(16);
        }
        
    line=line+10;
        
    Serial.println("");
      } 
     
    // read the state of the pushbutton value:
      
    UpButtonState buttonValue;
      if (
    UpButtonState 830 && UpButtonState 840) {    
        
    ms.prev(); 
      } 
      
      
    DownButtonState buttonValue;
      if (
    UpButtonState 860 && UpButtonState 870) {   
        
    ms.next();  
      } 

      
    SelectButtonState buttonValue;
      if (
    UpButtonState 480 && UpButtonState 490) {   
        
    ms.select();  
      } 
      
      
    BackButtonState buttonValue;
      if (
    UpButtonState 319 && UpButtonState 325) {   
        
    ms.back();  
      } 
     
      
    // Wait for two seconds so the output is viewable
      
    delay(1500);

    Click image for larger version. 

Name:	IMG_20150313_105735.jpg 
Views:	901 
Size:	129.7 KB 
ID:	3840

    And it is your working code

    PHP Code:
    #include <MenuSystem.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>

    //Пины
    #define OLED_MOSI   9
    #define OLED_CLK   10
    #define OLED_DC    11
    #define OLED_CS    12
    #define OLED_RESET 13
    Adafruit_SSD1306 display(OLED_MOSIOLED_CLKOLED_DCOLED_RESETOLED_CS);

    // Menu variables
    MenuSystem ms;
    Menu mm("");
    Menu mu1("Display");
    MenuItem mu1_mi1("Display1");
    MenuItem mu1_mi2("Display2");
    MenuItem mu1_mi3("Display3");
    Menu mu2("Settings");
    MenuItem mu2_mi1("Settings1");
    MenuItem mu2_mi2("Settings2");
    MenuItem mu2_mi3("Settings3");

    // Объявления переменных и констант
    const int buttonPin 0;   // аналоговый вход для кнопок

    int buttonValue 0;   // переменная для значения АЦП кнопки
    int UpButtonState 0;     // переменная для кнопки вверх
    int DownButtonState 0;   // переменная для кнопки вниз
    int SelectButtonState 0// переменная для кнопки выбора
    int BackButtonState 0;   // переменная для кнопки возврата

    bool bRanCallback false;
    bool bForward true;

    int line 30;             // переменная для установки настроек в линию


    // Функция меню обратного вызова
    // В этом примере все пункты меню можно использовать для обратного вызова.

    void on_display1_selected(MenuItemp_menu_item)
    {
      
    Serial.println("DISPLAY1 Selected");
      
    display.setCursor(0,55);
      
    display.print("DISPLAY1 Selected");
      
    bRanCallback true;
      
    bForward true;
    }
    void on_display2_selected(MenuItemp_menu_item)
    {
      
    Serial.println("DISPLAY2 Selected");
      
    display.setCursor(0,55);
      
    display.print("DISPLAY2 Selected");
      
    //bRanCallback = false;
      
    bForward true;
    }
    void on_display3_selected(MenuItemp_menu_item)
    {
      
    Serial.println("DISPLAY3 Selected");
      
    display.setCursor(0,55);
      
    display.print("DISPLAY3 Selected");
      
    bRanCallback false;
      
    bForward true;
    }

    void on_settings1_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS1 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS1 Selected");
      
    bRanCallback true;
      
    bForward true;
    }
    void on_settings2_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS2 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS2 Selected");
      
    bRanCallback false;
      
    bForward true;
    }
    void on_settings3_selected(MenuItemp_menu_item)
    {
      
    Serial.println("SETTINGS3 Selected");
      
    display.setCursor(0,55);
      
    display.print("SETTINGS3 Selected");
      
    //bRanCallback = false;
      
    bForward true;
    }

    // Standard arduino functions

    void setup()
    {
      
    Serial.begin(9600);
      
    // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
      
    display.begin(SSD1306_SWITCHCAPVCC);
      
      
      
    display.display();         // show splashscreen
      
    delay(1000);
      
    display.clearDisplay();   // clears the screen and buffer
      
    // Menu setup
      
    mm.add_menu(&mu1);
      
    mu1.add_item(&mu1_mi1, &on_display1_selected);
      
    mu1.add_item(&mu1_mi2, &on_display2_selected);
      
    mu1.add_item(&mu1_mi3, &on_display3_selected);
      
    mm.add_menu(&mu2);
      
    mu2.add_item(&mu2_mi1, &on_settings1_selected);
      
    mu2.add_item(&mu2_mi2, &on_settings2_selected);
      
    mu2.add_item(&mu2_mi3, &on_settings3_selected);
      
    ms.set_root_menu(&mm);
    }

    void loop()
    {
      
    buttonValue analogRead(buttonPin);
      
    Serial.println(buttonValue);
      
    //OLED set up
      
    display.display();         
      
    display.clearDisplay();
      
    display.setTextSize(1);
      
    display.setTextColor(WHITE);
      
    line=15//line variable reset
      //Serial.println("");
      
      
    // Display Title

      
    display.setCursor(10,0);
      
    display.println("MENU CONFIGURATION");
      
    display.setCursor(0,5);
      
    display.print("_____________________");
      
    display.setCursor(110,15);
     
    // Display the menu
      
    Menu const* cp_menu ms.get_current_menu();
      
    MenuComponent const* cp_menu_sel cp_menu->get_selected();
      for (
    int i 0cp_menu->get_num_menu_components(); ++i)
      {
        
    MenuComponent const* cp_m_comp cp_menu->get_menu_component(i);
        
    //Serial.println(cp_m_comp->get_name());
        
    display.setCursor(10,line);
        
    display.print(cp_m_comp->get_name());
        
        if (
    cp_menu_sel == cp_m_comp){
          
    //Serial.print("<<< ");
          
    display.setCursor(0,line);
          
    display.write(16);
        }
        
    line=line+10;
        
    //Serial.println("");
      

     
    // read the state of the pushbutton value:
      
    UpButtonState buttonValue;
      if (
    UpButtonState 830 && UpButtonState 840) {    
        
    ms.prev(); 
      } 
      
      
    DownButtonState buttonValue;
      if (
    UpButtonState 860 && UpButtonState 870) {   
        
    ms.next();  
      } 

      
    SelectButtonState buttonValue;
      if (
    UpButtonState 480 && UpButtonState 490) {   
        
    ms.select();  
      } 
      
      
    BackButtonState buttonValue;
      if (
    UpButtonState 319 && UpButtonState 325) {   
        
    ms.back();  
      } 
     
      
    // Wait for two seconds so the output is viewable
      
    delay(200);

    Click image for larger version. 

Name:	IMG_20150313_110118.jpg 
Views:	3949 
Size:	121.6 KB 
ID:	3841

  8. #8
    Hi,
    Is there any explanation about how the menu works ? especially about
    bRanCallback = false;
    bForward = true;

    I wonder if I can jump to a menu from inside a running program, ie GPS to access the setup ? how would that work ?

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •