Esp32 menu... please help..!

MENU_3_LAYER_ST7920.zip (18.4 KB)

Hello programming gurus,

I'm upgrading my rc transmitter to esp32 from Arduino
And as i have more memory and speed i wanted to have a menu for details and model selection...i got an menu example from internet but it is compatible with Arduino only because it is using timer and interrupts...and I'm not familiar with these... i want to modify this menu code to work with an esp32

Original setup is using :-
Arduino
Glcd 128*64 (spi mode)
Rotary encoder

And i have tested it as well..

Setup i want :-
Esp32 (i have DOIT esp32 dev module)
Glcd 128*64 (spi mode)
Rotary encoder (STANDARD ONE)

(Glcd works with esp32 )

Can someone please modify this sketch to work with esp32.

// ========================================================
// INCLUDES
// ========================================================

// for display
#include <U8g2lib.h>
// for timer
#include <TimerOne.h>
// for rotary encoder
#include <Rotary.h>

// ========================================================
// pin config
// ========================================================
// Rotary encoder with switch
#define ROTARY_SWITCH 4  // A1
#define ROTARY_PIN1 2
#define ROTARY_PIN2 3
#define ROTARY_ACCEL_OFFSET1 20
#define ROTARY_ACCEL_OFFSET2 50
#define ROTARY_ACCEL_OFFSET3 70
unsigned long rotaryLastMove;
bool rotaryButtonPressed = false;
// ========================================================
// INITS
// ========================================================

// Display
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8);
// Rotary Encoder
Rotary rotary = Rotary(ROTARY_PIN1, ROTARY_PIN2);

// ========================================================
// DEFAULTS
// ========================================================

// Timer
#define TIMER 100

// Display and menu stuff
int displayCurrentPage = 0;
bool setNeedsDisplay = true;

// Main menu fixed to 3 items, left, center, right...
#define MENU_SELECTED_TIMEOUT 40000
#define MENU_POS_Y 62
#define MENU_POS_Y_HIDDEN 76
#define MENU_ANIMATION_PIXEL_STEP 5

String menuItems[3] = {"HOME", "NETWORK", "SETUP"};
int menuActive = 1;             // left active
int menuSelected = menuActive;  // selected
bool menuPageMode = false;      // true => rotary encoder control page and not menu

// Menu animation
bool menuAnimationRunning = false;
int menuPosY = MENU_POS_Y;



// Test slider
int sliderPosX = 64;


// ========================================================
// PAGES STUFF
// ========================================================

#define SETUP_MENU_ITEMS 9
char *setupMenuItems[SETUP_MENU_ITEMS] = {"CHINOOK", "HELI-COPTER", "BI-COPTER", "TRI-COPTER", "QUAD-COPTER", "RC-PLANE", "RC-JET V-1","RC-CAR V-2", "VERSION"};
int setupMenuSelected = 1;



// ========================================================
// SETUP
// ========================================================
 
void setup() {
  // put your setup code here, to run once:

  // Menu Button
  pinMode(ROTARY_SWITCH, INPUT);
  digitalWrite(ROTARY_SWITCH, INPUT_PULLUP);
  // OLED Display
  u8g2.begin();
  setNeedsDisplay = true;
  Timer1.initialize(TIMER);
  Timer1.attachInterrupt(timerEvent);

  //delay(1000);
}

// ========================================================
// LOOP
// ========================================================

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


  if (menuAnimationRunning) {
    if (menuPageMode && menuPosY < MENU_POS_Y_HIDDEN) {
      // do animation
      menuPosY = menuPosY + MENU_ANIMATION_PIXEL_STEP;
      setNeedsDisplay = true;
    }
    if (!menuPageMode && menuPosY > MENU_POS_Y) {
      // do animation
      menuPosY = menuPosY - MENU_ANIMATION_PIXEL_STEP;
      setNeedsDisplay = true;
    }
  }
  if (menuAnimationRunning && (menuPosY == MENU_POS_Y || menuPosY == MENU_POS_Y_HIDDEN)) {
    // looks like animation is done
    menuAnimationRunning = false;
  }

  if (setNeedsDisplay) {
    noInterrupts();
    displayRenderCurrentPage();
    setNeedsDisplay = false;
    interrupts();
  }

}

// ========================================================
// TIMER
// ========================================================

void timerEvent() {
// Menu logic
  unsigned long timeOffset = millis() - rotaryLastMove;
  if (timeOffset > MENU_SELECTED_TIMEOUT) {
    // deselect menu
    menuSelected = menuActive;
    rotaryLastMove = millis();
    setNeedsDisplay = true;
  }
  
  // Rotary Encoder
  unsigned char result = rotary.process();
  if (result) {

    if (!menuPageMode) {
      if (result == DIR_CW) {
        // right
        if (menuSelected < 3) {
          menuSelected++;
        }
      } else {
        // left
        if (menuSelected > 1) {
          menuSelected--;
        }
      }
      setNeedsDisplay = true;
    } else {

      // Acceleration
      byte acceleration = 1;
      unsigned long timeOffset = millis() - rotaryLastMove;
      
      //Serial.println(timeOffset);

      if (displayCurrentPage == 0 || displayCurrentPage == 1) {
        if (timeOffset < ROTARY_ACCEL_OFFSET1) {
          acceleration = 16;
        } else if (timeOffset < ROTARY_ACCEL_OFFSET2) {
          acceleration = 4;
        } else if (timeOffset < ROTARY_ACCEL_OFFSET3) {
          acceleration = 2;
        }
      
        // Development test => control slider
        if (result == DIR_CW) {
          // right
          if (sliderPosX < 128) {
            sliderPosX = sliderPosX + acceleration;
          }
        } else {
          // left
          if (sliderPosX > 0) {
            sliderPosX = sliderPosX - acceleration;
          }
        }
        setNeedsDisplay = true;
      }

      if (displayCurrentPage == 2) {
        if (result == DIR_CW) {
          // right
          setupMenuSelected++;
        } else {
          // left
          setupMenuSelected--;
        }
        if (setupMenuSelected > SETUP_MENU_ITEMS - 1) {
          setupMenuSelected = SETUP_MENU_ITEMS - 1;
        }
        if (setupMenuSelected < 1) {
          setupMenuSelected = 0;
        }
        setNeedsDisplay = true;
      }

    }

    rotaryLastMove = millis();
    
  }

  // Rotary button
  if (buttonEvent()) {
    rotaryLastMove = millis();
    if (menuActive == menuSelected) {
      if (!menuPageMode) {
        // give controls to page (button press on selected page)
        menuPageMode = true;
        menuAnimationRunning = true;
        
        sliderPosX = 64;
        
        setNeedsDisplay = true;
        
        #ifdef DEBUG
        Serial.println("PAGE MODE ON");
        #endif
      } else {
        menuPageMode = false;   
        menuAnimationRunning = true;
        setNeedsDisplay = true;
        sliderPosX = 64;

        setupMenuSelected = 0;
        
        #ifdef DEBUG
        Serial.println("PAGE MODE OFF"); 
        #endif
      }
    }
    if (!menuPageMode) {
      menuActive = menuSelected;
      if (menuActive == 1) {
        displayCurrentPage = 0;
      }
      if (menuActive == 2) {
        displayCurrentPage = 1;
      }
      if (menuActive == 3) {
        displayCurrentPage = 2;
      }
      setNeedsDisplay = true;
    }
  }

  // Action button => reset page mode during development
#ifdef BUTTON1_PIN
  if (digitalRead(BUTTON1_PIN) == 0 && menuPageMode) {
    menuPageMode = false;   
    menuAnimationRunning = true;
    setNeedsDisplay = true;
    sliderPosX = 64;
    #ifdef DEBUG
    Serial.println("PAGE MODE OFF"); 
    #endif
  }
#endif
  
}

// ========================================================
// MENU BUTTON
// ========================================================

bool buttonEvent() {
                                  bool result = false;
                                  bool menuButton = false;
                                  if (digitalRead(ROTARY_SWITCH) == 1) {
                                    menuButton = true;
                                  }
                                  if (menuButton && !rotaryButtonPressed) {
                                    rotaryButtonPressed = true;
                                  } else if (!menuButton && rotaryButtonPressed) {
                                    rotaryButtonPressed = false;
                                    result = true;
                                    // FIXME: debounce for try, check if it's really needed
                                    //delay(4);
                                  }
                                  return result;
                                }

// ========================================================
// DISPLAY - Screen Drawing
// ========================================================

void displayRenderCurrentPage() {
                                // OLED Display update
                                u8g2.firstPage();
                                do {
                              
                                  if (displayCurrentPage == 0) {
                                    u8g2.setFont(u8g2_font_8x13B_tr);
                                    u8g2.drawStr(0, 12, "HOME");
                                  }
                              
                                  if (displayCurrentPage == 1) {
                                    u8g2.setFont(u8g2_font_8x13B_tr);
                                    u8g2.drawStr(0, 12, "SETTINGS");
                                  }
                              
                                  if (displayCurrentPage == 2) {
                                    if (!menuPageMode) {
                                      u8g2.setFont(u8g2_font_8x13B_tr);
                                      u8g2.drawStr(0, 10, "models available");
                                      u8g2.setFont(u8g2_font_5x7_tr);
                                      u8g2.drawStr(0, 18, "1) CHINOOK");
                                      u8g2.drawStr(0, 25, "2) HELICOPTER");
                                      u8g2.drawStr(0, 32, "3) BI-COPTER");
                                      u8g2.drawStr(0, 39, "4) TRI-COPTER");
                                      u8g2.drawStr(0, 46, "5) QUADCOPTER");
                                      u8g2.drawStr(70, 18, "6) AIRPLANE");
                                      u8g2.drawStr(70, 25, "7) RC-JET");
                                      u8g2.drawStr(70, 32, "8) RC-CAR");
                                    } else {
                                      drawPageMenu();
                              
                                      if (setupMenuSelected == 0) {
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.drawStr(0, 28, "CHINOOK");
                                        u8g2.drawStr(0, 38, "PRESS TO SELECT");
                                      }
                                      if (setupMenuSelected == 1) {
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.drawStr(0, 28, "HELICOPTER");
                                        u8g2.drawStr(0, 38, "PRESS TO SELECT");
                                      }
                                        if (setupMenuSelected == 2) {
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.drawStr(0, 28, "BI-COPTER");
                                        u8g2.drawStr(0, 38, "PRESS TO SELECT");
                                      }
                                        if (setupMenuSelected == 3) {
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.drawStr(0, 28, "TRI-COPTER");
                                        u8g2.drawStr(0, 38, "PRESS TO SELECT");
                                      }
                                        if (setupMenuSelected == 4) {
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.drawStr(0, 28, "QUADCOPTER");
                                        u8g2.drawStr(0, 38, "PRESS TO SELECT");
                                      }
                                        if (setupMenuSelected == 5) {
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.drawStr(0, 28, "AIRPLANE");
                                        u8g2.drawStr(0, 38, "PRESS TO SELECT");
                                      }
                                      if (setupMenuSelected == 6) {
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.drawStr(0, 28, "RC-JET");
                                        u8g2.drawStr(0, 38, "PRESS TO SELECT");
                                      }
                                      if (setupMenuSelected == 7) {
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.drawStr(0, 28, "RC-CAR");
                                        u8g2.drawStr(0, 38, "PRESS TO SELECT");
                                      }
                                      if (setupMenuSelected == 8) {
                                        // Version & Info
                                        u8g2.setFont(u8g2_font_5x7_tr);
                                        u8g2.setCursor(0, 28);
                                        u8g2.print("RC TRANSMITTER");
                                        u8g2.setCursor(0, 38);
                                        u8g2.print("SW-VER. - 0.1");
                                        u8g2.setCursor(0, 48);
                                        u8g2.print("HW-VER. - 2.0");
                                        u8g2.setCursor(0, 58);
                                        u8g2.print("BY- VARUN SINGH");
                                      }
                                    }
                                  }
                              
                                  if (displayCurrentPage == 0 || displayCurrentPage == 1) {
                                    u8g2.setFont(u8g2_font_5x7_tr);
                                    if (menuPageMode) { 
                                      u8g2.drawStr(0, 28, "ROTARY CONTROL ON PAGE");
                                      u8g2.setCursor(0, 46);
                                      u8g2.print("VALUE ");
                                      u8g2.print(sliderPosX);
                                    } else {
                                      u8g2.drawStr(0, 28, "ROTARY CONTROL ON MENU");
                                    }
                                    drawSlider(31);
                                  }
                              
                                  drawMenuBar();
                                  
                                } while ( u8g2.nextPage() );
                              }

void drawPageMenu() {

                                    u8g2.setFont(u8g2_font_5x7_tr);
                                    if (displayCurrentPage == 2) {
                                      // center text
                                      u8g2.drawRBox(36, 0, 58, 10, 2);  //(x,y,w,h,r)
                                      u8g2.setDrawColor(0);
                                      u8g2.setCursor(38, 8);
                                      u8g2.print(setupMenuItems[setupMenuSelected]);
                                      u8g2.setDrawColor(1);
                                  
                                      bool drawLeftTriangle = false;
                                      bool drawRightTriangle = false;
                                  
                                      if (setupMenuSelected < SETUP_MENU_ITEMS - 1) {
                                        drawRightTriangle = true;
                                      }
                                      if (setupMenuSelected > 0) {
                                        drawLeftTriangle = true;
                                      }
                                  
                                      if (drawLeftTriangle) {
                                        // Triangle left
                                        u8g2.drawTriangle(4, 1, 4, 9, 0, 5);
                                      }
                                      if (drawRightTriangle) {
                                        // Triangle right
                                        u8g2.drawTriangle(128 - 5, 1, 128 - 5, 9, 127, 5);
                                      }
                                      //u8g2.drawHLine(0, 10, 128);
                                    }
                                    
                                  }

void drawSlider(int yPos) {
                                        u8g2.drawFrame(0, yPos, 128, 6);
                                        if (sliderPosX < 1) {
                                          sliderPosX = 0;
                                        }
                                        if (sliderPosX > 128) {
                                          sliderPosX = 128;
                                        }
                                        u8g2.drawVLine(sliderPosX, yPos, 6);
                                      }

void drawMenuBar() {
                                      
                                      int textY = menuPosY;
                                      u8g2.setFont(u8g2_font_5x7_tr);
                                      u8g2.setDrawColor(1);
                                      
                                      if (textY < MENU_POS_Y_HIDDEN) {

                                        
                                        // left menu==================================================================================================
                                       
                                        if (menuActive == 1) {
                                          u8g2.drawRBox(0, 53, 25, 11, 2);      //(x,y,w,h,r)
                                          u8g2.setDrawColor(0);
                                        } 
                                        if (menuActive != menuSelected && menuSelected == 1) {
                                          u8g2.drawRFrame(0, 53, 25, 11, 2);    //(x,y,w,h,r)
                                          u8g2.setDrawColor(1);
                                        }
                                        u8g2.setCursor(3, 62);
                                        u8g2.print("HOME");
                                        u8g2.setDrawColor(1);
                                        
                                        // center menu=================================================================================================
                                       
                                        if (menuActive == 2) {
                                          u8g2.drawRBox(45, 53, 40, 11, 2);      //(x,y,w,h,r)
                                          u8g2.setDrawColor(0);
                                        } 
                                        if (menuActive != menuSelected && menuSelected == 2) {
                                          u8g2.drawRFrame(45, 53, 40, 11, 2);    //(x,y,w,h,r)
                                          u8g2.setDrawColor(1);
                                        }
                                      
                                        u8g2.setCursor(48, 62);
                                        u8g2.print("SETTING");
                                        u8g2.setDrawColor(1);
                                        // right menu==================================================================================================
                                        
                                        if (menuActive == 3) {
                                          u8g2.drawRBox(104, 53, 24, 11, 2);      //(x,y,w,h,r)
                                          u8g2.setDrawColor(0);
                                        }
                                        if (menuActive != menuSelected && menuSelected == 3) {
                                          u8g2.drawRFrame(104, 53, 24, 11, 2);    //(x,y,w,h,r)
                                          u8g2.setDrawColor(1);
                                        }
                                        u8g2.setCursor(107, 62);
                                        u8g2.print("MODE");
                                        u8g2.setDrawColor(1);
                                      }
                                      
                                    }

Please post your sketch here following the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

What sketch did you post, in code tags, that you'd like modified to work with an ESP32?

@varun_r19
you may try this "ESP32 Rotary Encoder Library" :

I have included a zip file containing code

Please post the code in code tags.

I have tried to replicate the code using this library with
my whole knowledge. But i really don't understand the code how menu is created....

someone please help!!!!!!!!!!!!!!!

In your zip file, open the sketch file in an IDE or notepad++, ctrl-a, ctrl-c, then back here, click the </> icon, ctrl-v, and post.

Simple.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.