Hello! This is my first post on this forum.
I have some trouble with a rotary encoder. My current project is making a menu system with submenus that is controlled using a rotary encoder and displayed on a 16x2 LCD screen. The problem is that I tried using a loading variable (currentMenu in the code below) that should act as check for the current menu I am in. However, printing the value through serial shows me that whenever I press the button, currentMenu resets back to 0 and I cannot cycle through any of the submenu's options. Can you please help me?
This is my code (the menu options are written in Romanian, but that should not be a problem for reading):
#include <LiquidCrystal.h>
#include <rotary.h> // rotary handler
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define A_output 9
#define B_output 8
#define SW_output 7
Rotary r = Rotary(A_output, B_output, SW_output);
int currentMenu;
int columns = 16;
char *menuList[] = {"Motoare", "Contrast", "LED Test", "Opt. lumina", "Despre", "Resetare"};
char *menuListMotor[] = {"Servo1", "Servo2"};
char *menuListOpts[] = {"Pornit", "Oprit"};
int menuItems = 6;
int menuItemsMotor = 2;
int menuItemsOpts = 2;
int CursorLine = 0;
int CursorLineMotor = 0;
int CursorLineContrast = 0;
int ledPin = 4;
int backButton = 2;
int contrastLevel = 10;
int backlightPin = 10;
int brightness = 255;
int fadeLevel = 5;
void (*resetfunc)(void) = 0;
void setup ()
{
digitalWrite(A_output, HIGH);
digitalWrite(B_output, HIGH);
digitalWrite(SW_output, HIGH);
analogWrite(backlightPin, brightness);
analogWrite(6, contrastLevel);
pinMode(backButton, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
lcd.clear();
lcd.begin(16, 2);
lcd.print(" Bun venit! :)");
delay(2000);
print_menu();
currentMenu = 0;
} //end of setup
void loop ()
{
if (currentMenu == 0) {
menu_system();
} else if (currentMenu == 1) {
motor_system();
}
Serial.println(currentMenu);
} //End loop()
void menu_system() {
volatile unsigned char result = r.process();
if (result) {
result == DIR_CCW ? CursorLine = CursorLine - 1 : CursorLine = CursorLine + 1;
if (CursorLine < 0) {
CursorLine = 0;
} else if (CursorLine > menuItems - 1) {
CursorLine = menuItems - 1;
}
print_menu();
}
if (r.buttonPressedReleased(25)) {
lcd.setCursor(0, 0); //(col, row)
lcd.setCursor(0, 1); //(col, row)
selection();
} //endif buttonPressedReleased
}
void motor_system() {
int valueMenu = digitalRead(backButton);
volatile unsigned char result = r.process();
if (result) {
result == DIR_CCW ? CursorLineMotor = CursorLineMotor - 1 : CursorLineMotor = CursorLineMotor + 1;
if (CursorLineMotor < 0) {
CursorLineMotor = 0;
} else if (CursorLineMotor > menuItems - 1) {
CursorLineMotor = menuItems - 1;
}
contrast_menu();
}
if (r.buttonPressedReleased(25)) {
lcd.setCursor(0, 0); //(col, row)
lcd.setCursor(0, 1); //(col, row)
selection_motor();
} //endif buttonPressedReleased
if (valueMenu == LOW) // if button is pressed, turn LED on
{
lcd.setCursor(0, 1);
lcd.print("Iesire");
currentMenu = 0;
}
}
void print_menu()
{
lcd.clear();
lcd.setCursor(0, 0); //(col, row)
lcd.print(" Meniu simplu ");
lcd.setCursor(0, 1); //2nd row
lcd.print("<"); lcd.setCursor(columns - 1, 1); lcd.print(">");
lcd.setCursor(1, 1);
lcd.print(menuList[CursorLine]);
}
void contrast_menu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Selectie motor");
lcd.setCursor(0, 1);
lcd.print("<"); lcd.setCursor(columns - 1, 1); lcd.print(">");
lcd.setCursor(1, 1);
lcd.print(menuList[CursorLineMotor]);
}
void selection()
{
switch (CursorLine) {
case 0:
currentMenu = 1;
contrast_menu();
break;
case 1:
break;
case 2:
//set a flag or do something....
lcd.setCursor(0, 0);
lcd.print("Testare LED! ");
lcd.setCursor(0, 1);
lcd.print(" ");
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
print_menu();
break;
case 3:
lcd.print("Lumina de spate ");
digitalWrite(backlightPin, LOW);
break;
case 4:
lcd.setCursor(0, 0);
lcd.print("Built at (C) ");
lcd.setCursor(0, 1);
lcd.print("FalconVille 2021");
delay(3000);
print_menu();
//set a flag or do something....
break;
case 5:
//set a flag or do something....
lcd.setCursor(0, 0);
lcd.print("Resetare... ");
lcd.setCursor(0, 1);
lcd.print(" ");
delay(2000);
resetfunc();
break;
} //end switch
//delay(2000);
//CursorLine = 0; // reset to start position
} //End selection
void selection_motor() {
switch (CursorLineMotor) {
case 0:
//turn on servo 1
break;
case 1:
//turn on servo 2
break;
default:
break;
}
}
Also, here is the rotary library that I used (This is a version made specifically to make the encoder's button work):
https://easyupload.io/d1v89o