Не остается в подменю
Так что всем привет. Я создаю простое меню с несколькими подменю на своем жидкокристаллическом экране. Но я столкнулся с небольшой проблемой, я не могу остаться в своем подменю. Когда я нажимаю кнопку выбора, он переходит в раздел подменю и через 1-2 секунды возвращается в главное меню.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
int upButton = 10;
int downButton = 11;
int selectButton = 12;
int menu = 1;
void setup() {
lcd.begin();
lcd.backlight();
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
pinMode(selectButton, INPUT_PULLUP);
updateMenu();
}
void loop() {
if (!digitalRead(downButton)){
menu++;
updateMenu();
delay(100);
while (!digitalRead(downButton));
}
if (!digitalRead(upButton)){
menu--;
updateMenu();
delay(100);
while(!digitalRead(upButton));
}
if (!digitalRead(selectButton)){
executeAction();
updateMenu();
delay(100);
while (!digitalRead(selectButton));
}
}
void updateMenu() {
switch (menu) {
case 0:
menu = 1;
break;
case 1:
lcd.clear();
lcd.print(">MenuItem1");
lcd.setCursor(0, 1);
lcd.print(" MenuItem2");
break;
case 2:
lcd.clear();
lcd.print(" MenuItem1");
lcd.setCursor(0, 1);
lcd.print(">MenuItem2");
break;
case 3:
lcd.clear();
lcd.print(">MenuItem3");
lcd.setCursor(0, 1);
lcd.print(" MenuItem4");
break;
case 4:
lcd.clear();
lcd.print(" MenuItem3");
lcd.setCursor(0, 1);
lcd.print(">MenuItem4");
break;
case 5:
menu = 4;
break;
}
}
void executeAction() {
switch (menu) {
case 1:
action1();
break;
case 2:
action2();
break;
case 3:
action3();
break;
case 4:
action4();
break;
}
}
void action1() {
lcd.clear();
lcd.print(">Executing #1");
delay(1500);
}
void action2() {
lcd.clear();
lcd.print(">Executing #2");
delay(1500);
}
void action3() {
lcd.clear();
lcd.print(">Executing #3");
delay(1500);
}
void action4() {
lcd.clear();
lcd.print(">Executing #4");
delay(1500);
}
Спасибо заранее
@Jānis, 👍0
Обсуждение1 ответ
возьмите, например, одну из функций действия подменю
void action1() {
lcd.clear();
lcd.print(">Executing #1");
delay(1500);
}
функция action1()
будет вызвана, когда для параметра menu
будет установлено значение 1.
Допустим, вы хотите 10 раз мигнуть светодиодом в функции action1 ()
. В функции action1()
вы должны добавить необходимую логику / код для выполнения. после завершения выполнения кода элемент управления выйдет из функции action1 ()
. затем ваш код звучит примерно так:
void action1() {
lcd.clear();
lcd.print(">Executing #1");
for(int i =0; i<10; i++)
{
ledstate = !ledstate; //предположим, что начальное значение ledstate равно нулю
digitalWrite(LED_BUILTIN, !ledstate);
delay(500);
}
}
Если вы хотите остаться в функции action1()
навсегда, вы можете сделать следующее:
void action1() {
lcd.clear();
lcd.print(">Executing #1");
while(1);
}
Но вы видите, что контроль никогда не выйдет из этой функции. Это означает, что вы, возможно, не сможете снова прочитать состояние кнопки или перейти в другие меню. Я предполагаю, что вы не используете прерывания. это означает, что ваш код застрянет здесь навсегда. Чтобы выйти из этой функции, единственным способом будет сброс системы. Тем не менее, если это то, что вам нужно сделать, вы можете изучить функции сна для экономии энергии вместо функции while(1)
.
У вас должен быть план выхода из функции. Пока вы находитесь в функции action1 ()
, попробуйте следить за кнопками, если определенные кнопки нажаты, вы можете обнаружить это и затем выйти из цикла while
while(digitalRead(button1)
{
//некоторые повторяющиеся действия по кодированию
}
как только кнопка 1 станет МЕНЬШЕ
, условие в функции while
завершится ошибкой.
Я надеюсь, что мой ответ дал вам несколько способов решить вашу проблему.
- Как заставить ЖК-экран прокручивать текст , позволяя вводить кнопки?
- Проблема с кнопкой
- Закодируйте и подключите ЖК-дисплей и кнопку
- Как запрограммировать кнопку джойстика, чтобы сбросить все?
- Новичок в Arduino и ищет направление для исследования идеи проекта
- Печать string and integer LCD
- Определение того, была ли нажата и отпущена кнопка
- Отправка значения с одного Arduino на другой
Вы понимаете код, который вы включили? Он делает именно то, что вы описываете. В вашем коде нет подменю, определенных в коде, есть только главное меню и действия (которые отображают что-то на экране и возвращаются в главное меню через 1,5 секунды). Вы также забыли задать вопрос., @StarCat
Да, я меняю подменю как действие. Мой вопрос в том, чего мне не хватает?, @Jānis
Что вы хотите, чтобы ваш код выполнял? Если вы хотите иметь подменю, вам следует добавить код для отображения подменю и просмотреть их., @StarCat
Я что, когда я перехожу к действию 1, я остаюсь в действии 1 (не выхожу из него через 1,5 с)., @Jānis
Вот почему я спросил, понимаете ли вы, что такое код. Каждое "пустое действие 1() .. действие 4 ()" отображает что-то и ожидает в течение 1,5 секунд (="задержка(1500);"), а затем немедленно возвращается в главное меню. Если вы хотите изменить это, вам следует изменить "действие 1 ()" на " действие 4 ()", чтобы делать то, что вы хотите., @StarCat
Как вы планируете выйти из actionx в главное меню? Если при нажатии выберите, затем поместите распаковку и нажмите внутри действия., @Dorian
Кстати, вам не нужно отменять отпирание кнопки. Поместите небольшую задержку в основной цикл., @Dorian