Меню для LCD 2004 с прокруткой пунктов.
- Войдите на сайт для отправки комментариев
Коллеги, добрый день!
Дошли руки до создания меню для своего проекта на LCD 2004. Взялся за код и встретил несколько неприятных моментов.
Всего будет 5 кнопок (влево, вверх, вправо, вниз и ввод) повесил их на аналоговый пин, тема стандартная.
Вопрос первый: На главном экране очень сильно мерцает текст, который должен будет (по идее) обновляться (часы, температура и др. значения).
Вопрос второй: Если я нажимаю кнопку вниз (всего 5 пунктов меню) 5 раз, то код выполняется правильно. Т.е. стрелочка опускается до 5го пункта а потом переходит (по пятому нажатию) снова на первый пункт. НО! если нажа, к примеру, два раза кнопку вниз а потом попытаться вернуться снова на первый пункт, то тут сразу вылезают мои кривые руки в программировании. Грубо говоря, код рассчитан только на то, чтобы мы нажимали строго 5 или 4 раза вниз (спускаясь к 5му или возвращаясь с пятого к первому пункту меню) или наоборот нажимали вверх и снизу вверх попадали на первый пункт меню. ВОПРОС: Как это побороть?
Ещё не понятно как избавиться от ДЕЛЕЕВ. Пробовал вместо них ставить МИЛЛИСЫ, но что-то не то выходит
В программировании знаний не много, надеюсь на Вашу помощь :)
Спасибо!
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Библиотека дисплея
///////////////////////////////ДИСПЛЕЙ 1602 I2C//////////////////////////////////////////////
LiquidCrystal_I2C lcd(0x3F,20,4); // Адрес I2C (0x3F)
/////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////ДИСПЛЕЙ 1602 I2C//////////////////////////////////////////////
byte tnv[8] = {B00100,B01010,B01010,B01110,B01110,B11111,B11111,B01110,}; // Знак температуры
byte gradus[8] = {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000,}; // Знак градуса
byte vlazhnost[8] = {B00100,B00100,B01110,B01110,B11111,B11111,B11111,B01110,}; // Знак влажности
byte battery[8] = {B01110,B11011,B10001,B11111,B10001,B11111,B10001,B11111,}; // Знак батарейки
byte alarm[8] = {B00100,B01110,B01110,B01110,B01110,B11111,B00000,B00100,}; // Знак Аварии
/////////////////////////////////////////////////////////////////////////////////////////////
byte indexmenu = 0; // индекс для входа в меню
byte direct = 0; // индекс пунктов меню
boolean avariya;
boolean AVT_disinfection;
float set_point = 46.00;
byte set_menu_time = 30; // время нахождения в меню в секундах
byte YR = 0; // год
byte DY = 1; // день
byte MN = 1; // месяц
byte HO = 0; // часы
byte MI = 0; // минуты
int TNV;
int Humidity;
int T1; // Датчик температуры Т1 (подача ЦО)
int T2; // Датчик температуры Т2 (обратка ЦО)
int T3; // Датчик температуры Т3 (подача ЦО ТП)
int T4; // Датчик температуры Т4 (обратка ЦО ТП)
unsigned long currentTime; // время текущее
unsigned long loopTime; // время для опроса датчиков или для времени задержки нахождения в меню
unsigned long PAUZA; // время для опроса датчиков или для времени задержки нахождения в меню
#include <Adafruit_ADS1015.h> // Библиотека ADS1115
Adafruit_ADS1115 ads(0x48); // Адрес I2C ADS1115 (0x48)
#define xGAIN GAIN_TWOTHIRDS // делитель 1 bit = 0.1875 mV
#define x1BIT 0.1875 // значение 1 бита
/////////////////////////////Настройка точности/////////////////////////////
// GAIN_TWOTHIRDS // 2/3x gain +/- 6.144V 1 bit = 0.1875 mV (default)
// GAIN_ONE // 1x gain +/- 4.096V 1 bit = 0.125 mV
// GAIN_TWO // 2x gain +/- 2.048V 1 bit = 0.0625 mV
// GAIN_FOUR // 4x gain +/- 1.024V 1 bit = 0.03125 mV
// GAIN_EIGHT // 8x gain +/- 0.512V 1 bit = 0.015625 mV
// GAIN_SIXTEEN // 16x gain +/- 0.256V 1 bit = 0.0078125 mV
////////////////////////////////////////////////////////////////////////////
int16_t sens_key; // переменная для чтения 3 пина ADS1115
void setup() {
Serial.begin(115200);
Wire.begin();
currentTime = millis(); // фиксируем значение текущего времени
loopTime = currentTime; // приравниваем текущее время для цикла опроса датчиков температуры
avariya = 1;
AVT_disinfection = 1;
///////////////////////////////////ADS1115 I2C чип №0///////////////////////////////////////
ads.begin(); // инициализация библиотеки ADS1115
ads.setGain(xGAIN);
/////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////ДИСПЛЕЙ 2004 I2C//////////////////////////////////////////
lcd.begin(); // включаем LCD 2004
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
lcd.setCursor(0,0);lcd.print(" ");lcd.setCursor(0,1);lcd.print(" ");lcd.setCursor(0,2);lcd.print(" ");lcd.setCursor(0,3);lcd.print(" ");
lcd.setCursor(6,1);
lcd.print("ZDAROVKI");
lcd.setCursor(6,2);
lcd.print("ver: 0.1");
delay(2000);
lcd.setCursor(0,0);lcd.print(" ");lcd.setCursor(0,1);lcd.print(" ");lcd.setCursor(0,2);lcd.print(" ");lcd.setCursor(0,3);lcd.print(" ");
/////////////////////////////////////////////////////////////////////////////////////////////
lcd.createChar(0, gradus); // Подключаем знак градуса
lcd.createChar(1, vlazhnost); // Подключаем знак влажности
lcd.createChar(2, tnv); // Подключаем знак градуса
lcd.createChar(3, battery); // Подключаем знак батарейки
lcd.createChar(4, alarm); // Подключаем знак Колокольчика
}
void loop() {
/*
sens_key = ads.readADC_SingleEnded(3); // читаем результат единичного преобразования
*/
Serial.print("Значение аналогового пина: ");
Serial.print(analogRead(A0));
Serial.println(" ");
Serial.print("Номер кнопки: ");
Serial.print(keybyte());
Serial.println(" ");
Serial.print("indexmenu: ");
Serial.print(indexmenu);
Serial.println(" ");
Serial.print("direct: ");
Serial.print(direct);
Serial.println(" ");
Serial.println(" ");
////////////////////////////Подключаем символы в цикл ЛУП////////////////////////////////////
lcd.createChar(0, gradus); // Подключаем знак градуса
lcd.createChar(1, vlazhnost); // Подключаем знак влажности
lcd.createChar(2, tnv); // Подключаем знак градуса
lcd.createChar(3, battery); // Подключаем знак батарейки
lcd.createChar(4, alarm); // Подключаем знак Колокольчика
/////////////////////////////////////////////////////////////////////////////////////////////
currentTime = millis();
if ( keybyte() != 0 && indexmenu == 0 ){
lcd.setCursor(0,0);lcd.print(F(" "));lcd.setCursor(0,1);lcd.print(F(" "));lcd.setCursor(0,2);lcd.print(F(" "));lcd.setCursor(0,3);lcd.print(F(" "));
indexmenu = 2;} // если нажата одна из кнопок, и мы не были в меню до этого, тогда очищаем экран и попадаем в основное меню
if ( keybyte() != 0 && indexmenu == 2){
loopTime = currentTime;} // если нажата кнопка, и мы находимся в меню, тогда фиксируем время последнего нажатия для того чтобы отсчитать секунды до возврата обратно
if (currentTime >= (loopTime + (set_menu_time * 1000) ) ){
lcd.setCursor(0,0);lcd.print(F(" "));lcd.setCursor(0,1);lcd.print(F(" "));lcd.setCursor(0,2);lcd.print(F(" "));lcd.setCursor(0,3);lcd.print(F(" "));
indexmenu = 0; direct = 0;} // если текущее время больше чем время последнего нажатия в сумме с уставкой времени, тогда очищаем экран и выходим на главный экран
if ( keybyte() == 0 && indexmenu == 0 ) {
/////////////////////////////////////////////////////////////////////////////////////////////
// ГЛАВНЫЙ (Стартовый) экран
/////////////////////////////////////////////////////////////////////////////////////////////
lcd.setCursor(0,1); // Ячейка 1 строка 2
lcd.print(char(2));lcd.print("=");
lcd.setCursor(0,2); // Ячейка 1 строка 3
lcd.print(F("T1="));
lcd.setCursor(0,3); // Ячейка 1 строка 4
lcd.print(F("T2="));
lcd.setCursor(11,1); // Ячейка 12 строка 2
lcd.print(char(1));lcd.print("=");
lcd.setCursor(11,2); // Ячейка 12 строка 3
lcd.print(F("T3="));
lcd.setCursor(11,3); // Ячейка 12 строка 4
lcd.print(F("T4="));
lcd.setCursor(2,1); // Ячейка 3 строка 2
lcd.print(TNV); // Выводим показания температуры tнв
lcd.setCursor(4,1); // Ячейка 7 строка 2
lcd.print(char(0));lcd.print(F("C"));
lcd.setCursor(13,1); // Ячейка 3 строка 2
lcd.print(Humidity); // Выводим показания влажности
lcd.setCursor(15,1); // Ячейка 7 строка 2
lcd.print(F("%"));
lcd.setCursor(3,2); // Ячейка 3 строка 2
lcd.print(T1,1); // Выводим показания температуры Т1 (1 полоска) с одним знаком после запятой
lcd.setCursor(7,2); // Ячейка 7 строка 2
lcd.print(char(0));lcd.print(F("C"));
lcd.setCursor(3,3); // Ячейка 3 строка 3
lcd.print(T2,1); // Выводим показания температуры Т2 (2 полосоки) с одним знаком после запятой
lcd.setCursor(7,3); // Ячейка 7 строка 3
lcd.print(char(0));lcd.print(F("C"));
lcd.setCursor(14,2); // Ячейка 14 строка 2
lcd.print(T3,1); // Выводим показания температуры Т3 (3 полоски) с одним знаком после запятой
lcd.setCursor(18,2); // Ячейка 18 строка 2
lcd.print(char(0));lcd.print(F("C"));
lcd.setCursor(14,3); // Ячейка 14 строка 3
lcd.print(T4,1); // Выводим показания температуры (4 полоски) с одним знаком после запятой
lcd.setCursor(18,3); // Ячейка 18 строка 3
lcd.print(char(0));lcd.print(F("C"));
/////////////////////////////////////////////////////////////////////////////////////////////
}
if (indexmenu == 2) { //если мы заодим в меню - то
if (direct == 0) {
lcd.setCursor(0,1);
lcd.print(">"); // ставим маркер в начало меню - первый пункт
lcd.setCursor(3,0);
lcd.print("MENU"); // Оглавление
lcd.setCursor(1,1);
lcd.print("1. Status"); // объявляем пункт меню 1
lcd.setCursor(1,2);
lcd.print("2. Mode select"); // объявляем пункт меню 2
lcd.setCursor(1,3);
lcd.print("3. Settings"); // объявляем пункт меню 3
direct = 1;
delay(100);
}
if (keybyte() == 5 && direct == 5) { // Возврат на стартовый экран
indexmenu = 0;
}
/*
if (millis() - PAUZA > 200){
PAUZA = millis();
}
*/
// Выбор 2 пункта меню
if (direct == 1 && keybyte()== 4 ) { // если нажали вниз
lcd.setCursor(0,1);
lcd.print(" "); // очищаем ячейку первого пункта
lcd.setCursor(0,2);
lcd.print(">"); // ставим маркер во вторую ячейку
delay(200);
direct = 2;
}
// конец блока
// выбор 3 пункта меню
if (direct == 2 && keybyte()== 4) { // если нажали вниз
lcd.setCursor(0,2);
lcd.print(" "); // очищаем ячейку второго пункта
lcd.setCursor(0,3);
lcd.print(">"); // ставим маркер в третью ячейку
delay(200);
direct = 3;
}
// конец блока
// выбор 4 пункта меню
if (direct == 3 && keybyte()== 4) { // если нажали вниз
lcd.setCursor(1,1);
lcd.print(" ");
lcd.setCursor(1,2);
lcd.print(" ");
lcd.setCursor(1,3);
lcd.print(" ");
lcd.setCursor(1,1);
lcd.print("2. Mode select"); // объявляем пункт меню 2
lcd.setCursor(1,2);
lcd.print("3. Settings"); // объявляем пункт меню 3
lcd.setCursor(1,3);
lcd.print("4. Incidents"); // объявляем пункт меню 3
delay(100);
direct = 4;
}
// конец блока
// выбор 5 пункта меню
if (direct == 4 && keybyte()== 4) { // если нажали вниз
lcd.setCursor(1,1);
lcd.print(" "); // объявляем пункт меню 2
lcd.setCursor(1,2);
lcd.print(" "); // объявляем пункт меню 3
lcd.setCursor(1,3);
lcd.print(" "); // объявляем пункт меню 3
lcd.setCursor(1,1);
lcd.print("3. Settings"); // объявляем пункт меню 1
lcd.setCursor(1,2);
lcd.print("4. Incidents"); // объявляем пункт меню 2
lcd.setCursor(1,3);
lcd.print("5. Exit"); // объявляем пункт меню 3
delay(100);
direct = 5;
}
// конец блока
// Возврат к пункту меню 1 из 5го
if (direct == 5 && keybyte()== 4) { // если нажали вниз
lcd.setCursor(0,1);
lcd.print(">"); // ставим маркер в первую ячейку
lcd.setCursor(0,3);
lcd.print(" "); // очищаем ячейку четвертого пункта
lcd.setCursor(1,1);
lcd.print(" "); // объявляем пункт меню 2
lcd.setCursor(1,2);
lcd.print(" "); // объявляем пункт меню 3
lcd.setCursor(1,3);
lcd.print(" "); // объявляем пункт меню 3
lcd.setCursor(1,1);
lcd.print("1. Status"); // объявляем пункт меню 1
lcd.setCursor(1,2);
lcd.print("2. Mode select"); // объявляем пункт меню 2
lcd.setCursor(1,3);
lcd.print("3. Settings"); // объявляем пункт меню 3
delay(100);
direct = 1;
}
// конец блока
// Возврат к пункту меню 1 из 2го
if (direct == 2 && keybyte()== 2) { // если нажали вверх
lcd.setCursor(0,1);
lcd.print(">"); // ставим маркер во вторую ячейку
lcd.setCursor(0,2);
lcd.print(" "); // очищаем ячейку третьего пункта
lcd.setCursor(1,1);
lcd.print(" ");
lcd.setCursor(1,2);
lcd.print(" ");
lcd.setCursor(1,3);
lcd.print(" ");
lcd.setCursor(1,1);
lcd.print("1. Status"); // объявляем пункт меню 1
lcd.setCursor(1,2);
lcd.print("2. Mode select"); // объявляем пункт меню 2
lcd.setCursor(1,3);
lcd.print("3. Settings"); // объявляем пункт меню 3
delay(200);
direct = 1;
}
// конец блока
// Возврат к пункту меню 1 из 2го
if (direct == 2 && keybyte()== 2) { // если нажали вверх
lcd.setCursor(0,1);
lcd.print(">"); // ставим маркер во вторую ячейку
lcd.setCursor(0,2);
lcd.print(" "); // очищаем ячейку третьего пункта
lcd.setCursor(1,1);
lcd.print(" ");
lcd.setCursor(1,2);
lcd.print(" ");
lcd.setCursor(1,3);
lcd.print(" ");
lcd.setCursor(1,1);
lcd.print("1. Status"); // объявляем пункт меню 1
lcd.setCursor(1,2);
lcd.print("2. Mode select"); // объявляем пункт меню 2
lcd.setCursor(1,3);
lcd.print("3. Settings"); // объявляем пункт меню 3
delay(200);
direct = 1;
}
// конец блока
// Возврат к пункту меню 2 из 3го
if (direct == 3 && keybyte()== 2) { // если нажали вверх
lcd.setCursor(1,1);
lcd.print(" ");
lcd.setCursor(1,2);
lcd.print(" ");
lcd.setCursor(1,3);
lcd.print(" ");
lcd.setCursor(1,1);
lcd.print("2. Mode select"); // объявляем пункт меню 1
lcd.setCursor(1,2);
lcd.print("3. Settings"); // объявляем пункт меню 2
lcd.setCursor(1,3);
lcd.print("4. Incidents"); // объявляем пункт меню 3
delay(200);
direct = 2;
}
// конец блока
// Возврат к пункту меню 3 из 4го
if (direct == 4 && keybyte()== 2) { // если нажали вверх
lcd.setCursor(0,1);
lcd.print(">"); // ставим маркер во вторую ячейку
lcd.setCursor(0,2);
lcd.print(" "); // очищаем ячейку третьего пункта
delay(100);
direct = 3;
}
// конец блока
// Возврат к пункту меню 4 из 5го
if (direct == 5 && keybyte()== 2) { // если нажали вверх
lcd.setCursor(0,2);
lcd.print(">"); // ставим маркер во вторую ячейку
lcd.setCursor(0,3);
lcd.print(" "); // очищаем ячейку третьего пункта
delay(100);
direct = 4;
}
// конец блока
// Возврат к пункту меню 5 из 1го
if (direct == 1 && keybyte()== 2) { // если нажали вверх
lcd.setCursor(0,3);
lcd.print(">"); // ставим маркер в третью ячейку
lcd.setCursor(0,1);
lcd.print(" "); // очищаем ячейку четвертого пункта
lcd.setCursor(1,1);
lcd.print(" ");
lcd.setCursor(1,2);
lcd.print(" ");
lcd.setCursor(1,3);
lcd.print(" ");
lcd.setCursor(1,1);
lcd.print("3. Settings"); // объявляем пункт меню 1
lcd.setCursor(1,2);
lcd.print("4. Incidents"); // объявляем пункт меню 2
lcd.setCursor(1,3);
lcd.print("5. Exit"); // объявляем пункт меню 3
delay(100);
direct = 5;
}
// конец блока
if (AVT_disinfection == 1) { // Функция дезинфекции включена
lcd.setCursor(17,0);
lcd.print("G");
}
if (avariya == 1) { // Сработала авария
lcd.setCursor(19,0);
lcd.print(char(4));
}
return;} // ограничение выполнения дальнейшей программы, пока мы в меню
}
byte keybyte () {
int key = analogRead(A0); // read the value from the sensor
if (key < 7) return 1; // Влево
else if (key < 200) return 2; // Вверх
else if (key < 380) return 3; // Вправо
else if (key < 600) return 4; // Вниз
else if (key < 900) return 5; // Выбор/Ввод
else return 0;
}
Разбор неправильностей того, что у Вас написано тянет не десяток страниц. Я говорю не о мелких ошибках, а об идеологических неправильностях. Единственный способ это исправить - переписать с нуля.
У меня к Вам вопрос. если Вы не умеете программировать, почему не хотите воспользоваться готовой библиотекой, написанной людьми, которые умеют?
Этого добра настолько навалом, что даже как-то неудобно за Вас ссылки искать.
У меня к Вам вопрос. если Вы не умеете программировать, почему не хотите воспользоваться готовой библиотекой, написанной людьми, которые умеют?
Ну скучно же, я вот тоже сам пытаюсь велосипеды изобретать. С течением времени из пяти колес три остаются.))))
"Памагите", соглашусь здесь лишнее. В качестве помощи предложил бы следующее: взять эти четыре сотни строк и начать переписывать по новой, пытаясь одновременно создавать законченные структурные блоки-подпрограммы. Убавит объем программы и растащит на что-то вменяемое эту жуткую свалку из лупа. ИМХО.
Ну скучно же, я вот тоже сам пытаюсь велосипеды изобретать. С течением времени из пяти колес три остаются.))))
Пару дней назад я делал то же самое, тоже меню со скроллингом, тоже изобретая велосипед, т.к. организовать меню с помощью списков или структур не мог - не было понимания как это делать, а чтение теории света в конце туннеля не прибавляло. Теперь , когда ОНО работает, я бы переписал по-другому, но блин велосипед ездит, а у меня еше куча непостроенных велосипедов впереди :)
Указать где у Вас в этом длинном коде ошибка я не могу, хреново я чужой код читаю. Дать кусок своего рабочего - могу, если Вам не лень будет разбираться.
Все получится! Объемляете переменную unsigned long time глобально ( она много где Вам понадобится)
и вместо delay(1000); пишите
Вы мне чужие заслуги не приписывайте.)))
Вы мне чужие заслуги не приписывайте.)))
Большое спасибо за помощь с millis, попробовал, работает отлично!
А по поводу Вашего кода, с удовольствием бы глянул и изучил :)
Ещё раз спасибо!
и вместо delay(1000); пишите
Вы уверены, что это надо делать?
Вы уверены, что это надо делать?
Вы уверены, что это надо делать?
Но ведь работает же, если верить ТС - "отлично", а главное делает то же, что и делей, только с миллисом.)))))
Теоретиццки, если между выполнением присваивания time = millis() и следующей строчкой
while(millis()-time<1000);
произойдет обнуления millis() то цикл будет длится неожиданно долго. :) Тут кык бы да. Но вероятность такого события писец какая низкая, с практицццкой точки зрения. Но помнить надо. Возьмите меня в секту!
А по поводу Вашего кода, с удовольствием бы глянул и изучил :)
Да пожалуйста! Немного адаптировано, показана именно менюшка. Не претендую ни разу на истину и правильность, но так - работает.
Будут вопросы - велкам!
#define PRESS_EVENT 120//Длительность нажатия SELECT #define MENU_LINES 4// Кол-во строк, выводимых на дисплей #define MENU_ITEMS 7//кол-во пунктов меню bool menu_event = 0; //флаг меню unsigned long counter = 0; //counter - переченная, которая инкриментируется в //обработчике прерываний от таймера, если нажата кнопка SELECT //Для экономии оперативной памяти //все пункты меню , подменю, все сообщения выводимые на дисплей //хранятся в ПРОГМЕМ в виде строковых констант. Указатели на строковые //константы хранятся в массиве, так же в ПРОГМЕМ. Индексы этого //массива передается в функцию вывода конкретной строки на дисплей. void setup() { //чего-то тут тяп-ляп } void loop() { //чего-то тут мутим-крутим //если кнопка SELECT нажата не меньше чем положено // - переходим в меню if(counter>PRESS_EVENT){menu_event = 1; menu_screen();} } void menu_screen(){ while (!(PIND & (1 << 5)));//ждем, пока юзер не отпустит //кнопку SELECT, которая на 5м пине. Пин подтянут к питанию counter = 0;//обнулии int menu_position = 0;//положение условного курсора построчно int add = 0; //добавочная переменная для скроллинга u8g2.setFont(u8g2_font_haxrcorp4089_t_cyrillic); u8g2.setFontMode(0); //начало цикла меню, который длится пока установлен флаг меню do { u8g2.firstPage(); do {//формирование страницы на дисплее, библ. u8g2 u8g2.setCursor(30, 7); u8g2.setDrawColor(1); u8g2.print("МЕНЮ");//заглавие страницы u8g2.drawHLine(0, 9, 127); //цикл вывода 4 пунтов меню на страницу //больше не помещается :( for (byte i = 0; i < MENU_LINES; i++) { if (i + add == menu_position) {//если печатуемый //пункт меню совпадает с положением условного курсора //то строка печатается на фоне нарисованного прямоугольника //инверсным цветом u8g2.drawBox(9, 10 + 12 * i, 80, 11); softPrint(10, 18 + 12 * i, 0, 7 + i + add); //передача данных в функцию печати. 1й и 2й аргументы - //координаты X Y, 3й аргумент - цвет, 4й аргумент - //какая именно строка из массива строк печатается } else softPrint(10, 18 + 12 * i, 1, 7 + i + add); //остальные строки печатаются нормальным цветом } } while ( u8g2.nextPage() );//выводим страницу на экран menu_position += getEncoder();//опрашиваем энкодер, если были //изменения - ин/декрименируем условный курсор if (menu_position < 0)menu_position = 0; if (menu_position > MENU_ITEMS - 1)menu_position = MENU_ITEMS - 1; //смотрим, чтоб не вывалился за лимиты if (menu_position > MENU_LINES - 1 + add)add++;//скроллинг строк //если мы встали на 5й пункт меню, то 1ый не печатается //печатаются 2,3,4,5 if (menu_position < add)add--;// и обратно if (counter > PRESS_EVENT) {//если нажат SELECT switch (menu_position) {//в зависимости от того, куда указывал курсор case 0: menu_event = 0;//сброс флага меню для выхода из него counter = 0; last_encoder = encoder.read(); break; case 1: selector_event = 1; counter = 0; selectInput(); break; // установка флага подменю и переход на соответствующую функцию //рисования этого подменю case 2: balance_event = 1; counter = 0; balanceScreen(); break; case 3: tembro_event = 1; counter = 0; tembroScreen(); break; case 4: relay_delay_event = 1; counter = 0; relayDelay(); break; case 5: item1_event = 1; counter = 0; notActivated(); break; case 6: item2_event = 1; counter = 0; notActivated(); break; } } } while (menu_event); }ПС. Это будущий блок управления аудио усилителем. Дисплей графический 12864 ST9720, , кнопок нет ваапще, только энкодер, библиотека u8g2
Спасибо!
Теоретиццки, если между выполнением присваивания time = millis() и следующей строчкой
while(millis()-time<1000);
произойдет обнуления millis() то цикл будет длится неожиданно долго.
разберись, для начала, как поведет себя в такой ситуации unsigned long