ардуино меню лсд , arduino menu lcd

vov4ik
Offline
Зарегистрирован: 10.09.2013

Эта тема как просто сделать меню на лсд, в тех проектах где используются простые не дорогие экранчики, появляется необходимость сделать меню для изменения переменных участвующих в работе, начинающим очень сложно даже представить с чего начать.

Первое что необходимо создать топологию, какие переменные необходимы для изменения.

В любой программе нужно начертить то что будет из себя предстовлять меню.

Как видно в меню я использую 20 блоков пароль, начальное меню и две эдинтичные ветки по девять блоков.

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
// переменные необходимые для работы проекта
byte BC_MIN = 71; byte BM_MIN = 71;
byte BC_MAX = 79; byte BM_MAX = 79;
unsigned long BC_TIME = 20000; unsigned long BM_TIME = 20000;
byte BC_DYNAMICS = 20; byte BM_DYNAMICS = 20;
boolean BC_TIME_D = 1; boolean BM_TIME_D = 1;
boolean BC = 1; boolean BM = 1;
// переменные для работы меню
byte PASSWORD = 0;
byte key = 21;
byte tim = 4;
byte pas = 0;
byte vst = 10;
byte mix = 1;
byte del = 250;
// boolean d = 1;
boolean lcd_0 = 0; boolean lcd_1 = 0;
char* myStrings[]={"PASSWORD","MENU","OUT","<<<<", "OFF / ON","OFF","ON","MIN / MAX","MIN","MAX","TIME","DYNAMICS","                ",// 0-12
"BC", "BC (OFF / ON)", "BC (MIN / MAX)","BC TIME","BC MIN","BC MAX","BC TIME(OFF/ON)","BC DYNAMICS",// 13-20
"BM", "BM (OFF / ON)", "BM (MIN / MAX)","BM TIME","BM MIN","BM MAX","BM TIME(OFF/ON)","BM DYNAMICS"}; // 21-26

void setup() {
// Serial.begin(9600);
  lcd.begin(16,2);
  pinMode(10, INPUT);pinMode(11, INPUT);pinMode(12, INPUT);//10 - ; 11 + ; 12 *
  digitalWrite(10, HIGH);digitalWrite(11, HIGH);digitalWrite(12, HIGH);  
}
void loop() {
if (lcd_0 == 1) {
lcd.setCursor(0,0); lcd.print(myStrings[12]); 
lcd.setCursor(((16 - (String(myStrings[vst])).length())/2), 0); lcd.print(String(myStrings[vst]));
lcd_0 = 0;} 
if (lcd_1 == 1) {
lcd.setCursor(0,1); lcd.print(myStrings[12]); 
lcd.setCursor(((16 - (String(myStrings[vst])).length())/2), 1); lcd.print(String(myStrings[vst]));
lcd_1 = 0;} 
  delay(200);

  if (digitalRead(12) == 0){pas++; if (pas >= 8){key = 1;lcd_0 = 1;vst = 0;pas = 0;PASSWORD = 0;lcd.clear();delay(800);}} else{pas = 0;} 
  switch (key) {
    case 1: //"    PASSWORD"
    if (digitalRead(10) == 0){PASSWORD--;}
    if (digitalRead(11) == 0){PASSWORD++;}
    if (digitalRead(12) == 0){if (PASSWORD == 247){key = 2;lcd_0 = 1;vst = 1;}else {lcd.clear();key = 21;}}
    lcd.setCursor(7, 1);lcd.print(PASSWORD);lcd.print("  ");
 break;
   case 2: // MENU
   delay(del);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 3;}
   if (digitalRead(11) == 0){mix++;} if (mix == 4){mix = 1;}  
   if (mix == 1){lcd_1 = 1;vst = 13;} // BC
   if (mix == 2){lcd_1 = 1;vst = 21;} // BM
   if (mix == 3){lcd_1 = 1;vst = 2;}  // OUT
   if (digitalRead(12) == 0 && mix == 1 && BC == 1){key = 3 ;mix = 1;lcd_0 = 1;vst = 13;} // BC
   if (digitalRead(12) == 0 && mix == 1 && BC == 0){key = 4 ;mix = 1;lcd_0 = 1;vst = 14;} // BC (OFF / ON)
   if (digitalRead(12) == 0 && mix == 2 && BM == 1){key = 12;mix = 1;lcd_0 = 1;vst = 21;} // BM
   if (digitalRead(12) == 0 && mix == 2 && BM == 0){key = 13;mix = 1;lcd_0 = 1;vst = 22;} // BM (OFF / ON)
   if (digitalRead(12) == 0 && mix == 3){key = 21;mix = 1;lcd.clear();}
 break;
   case 3: // BC
   delay(del);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 4;}
   if (digitalRead(11) == 0){mix++;} if (mix == 5){mix = 1;}  
   if (mix == 1){lcd_1 = 1;vst = 4;}  // OFF / ON
   if (mix == 2){lcd_1 = 1;vst = 7;}  // MIN / MAX
   if (mix == 3){lcd_1 = 1;vst = 10;}  // TIME
   if (mix == 4){lcd_1 = 1;vst = 3;} // <<<<
   if (digitalRead(12) == 0 && mix == 1){key = 4;mix = 1;lcd_0 = 1;vst = 14;} // BC (OFF / ON)
   if (digitalRead(12) == 0 && mix == 2){key = 5;mix = 1;lcd_0 = 1;vst = 15;} // BC (MIN / MAX)
   if (digitalRead(12) == 0 && mix == 3){key = 6;mix = 1;lcd_0 = 1;vst = 16;} // BC TIME
   if (digitalRead(12) == 0 && mix == 4){key = 2;mix = 3;lcd_0 = 1;vst = 1;}  // MENU
 break;
   case 4: // BC (OFF / ON)
   delay(del);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 2;}
   if (digitalRead(11) == 0){mix++;} if (mix == 3){mix = 1;}
   if (mix == 2){lcd_1 = 1;vst = 5;} // OFF
   if (mix == 1){lcd_1 = 1;vst = 6;} // ON
   if (digitalRead(12) == 0 && mix == 2){key = 2;BC = 0;mix = 3;lcd_0 = 1;vst = 1;} // MENU
   if (digitalRead(12) == 0 && mix == 1){key = 3;BC = 1;mix = 4;lcd_0 = 1;vst = 13;} // BC
 break;
   case 5: // BC (MIN / MAX)
   delay(del);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 3;}
   if (digitalRead(11) == 0){mix++;} if (mix == 4){mix = 1;}
   if (mix == 1){lcd_1 = 1;vst = 8;} // MIN 
   if (mix == 2){lcd_1 = 1;vst = 9;} // MAX
   if (mix == 3){lcd_1 = 1;vst = 3;} // <<<<
   if (digitalRead(12) == 0 && mix == 1){key = 7;mix = 1;lcd_0 = 1;lcd_1 = 0;vst = 17;} // BC MIN
   if (digitalRead(12) == 0 && mix == 2){key = 8;mix = 1;lcd_0 = 1;lcd_1 = 0;vst = 18;} // BC MAX
   if (digitalRead(12) == 0 && mix == 3){key = 3;mix = 4;lcd_0 = 1;lcd_1 = 0;vst = 13;} // BC
 break;
   case 6: // BC TIME
   delay(del);lcd.noCursor();
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 4;}
   if (digitalRead(11) == 0){mix++;} if (mix == 5){mix = 1;}  
   if (mix == 1){lcd_1 = 1;vst = 4;}  // OFF / ON
   if (mix == 2){lcd_1 = 1;vst = 10;} // TIME
   if (mix == 3){lcd_1 = 1;vst = 11;}  // DYNAMICS"
   if (mix == 4){lcd_1 = 1;vst = 3;} // <<<<
   if (digitalRead(12) == 0 && mix == 1){key = 9 ;mix = 1;lcd_0 = 1;vst = 19;} // BC TIME(OFF/ON)
   if (digitalRead(12) == 0 && mix == 2){key = 10;mix = 1;lcd_0 = 1;vst = 16;tim = 3;lcd_1 = 0;lcd.setCursor(0,1); lcd.print(myStrings[12]);} // BC TIME
   if (digitalRead(12) == 0 && mix == 3){key = 11;mix = 1;lcd_0 = 1;vst = 20;lcd_1 = 0;lcd.setCursor(0,1); lcd.print(myStrings[12]);} // BC DYNAMICS
   if (digitalRead(12) == 0 && mix == 4){key = 3 ;mix = 4;lcd_0 = 1;vst = 13;} // BC
 break;
   case 7: // BC MIN
   delay(del);
   if (digitalRead(10) == 0){BC_MIN--;} if (BC_MIN == 49){BC_MIN++;}
   if (digitalRead(11) == 0){BC_MIN++;} if (BC_MIN == (BC_MAX - 4)){BC_MIN--;}
   if (digitalRead(12) == 0){key = 5;mix = 1;lcd_0 = 1;vst = 15;} // BC (MIN / MAX)
   lcd.setCursor(5, 1);lcd.print(BC_MIN / 10);lcd.print(".");lcd.print(BC_MIN % 10);lcd.print(" Ph");
 break;
   case 8: // BC_MAX
   delay(del);
   if (digitalRead(10) == 0){BC_MAX--;} if (BC_MAX == (BC_MIN+4)){BC_MAX++;}
   if (digitalRead(11) == 0){BC_MAX++;} if (BC_MAX == 101){BC_MAX--;}
   if (digitalRead(12) == 0){key = 5;mix = 3;lcd_0 = 1;vst = 15;} // BC (MIN / MAX)
   lcd.setCursor(5, 1);lcd.print(BC_MAX / 10);lcd.print(".");lcd.print(BC_MAX % 10);lcd.print(" Ph");
 break;
    case 9: // BC / TIME (OFF / ON)
   delay(400);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 2;}
   if (digitalRead(11) == 0){mix++;} if (mix == 3){mix = 1;}
   if (mix == 1){lcd_1 = 1;vst = 5;} // OFF
   if (mix == 2){lcd_1 = 1;vst = 6;} // ON
   if (digitalRead(12) == 0 && mix == 1){key = 6;BC_TIME_D = 0;mix = 4;lcd_0 = 1;vst = 16;} // BC TIME
   if (digitalRead(12) == 0 && mix == 2){key = 6;BC_TIME_D = 1;mix = 4;lcd_0 = 1;vst = 16;} // BC TIME
 break;
   case 10: // BC TIME
   delay(del);
   if (digitalRead(10) == 0 && BC_TIME >= pow (10,tim)){BC_TIME -= pow (10,tim);}
   if (digitalRead(11) == 0){BC_TIME += pow (10,tim);}
   if (digitalRead(12) == 0 && tim == 0){key = 6;mix = 4;lcd_0 = 1;vst = 16;} // BC TIME
   if (digitalRead(12) == 0){tim--;}
   if (BC_TIME < 5000){BC_TIME = 5000;} if (BC_TIME > 99000){BC_TIME = 99000;}
   lcd.setCursor(5, 1);if (BC_TIME < 10000){lcd.print("0");}lcd.print(BC_TIME);lcd.print(" mS");lcd.setCursor((9-tim), 1);lcd.cursor();
break;
   case 11: //"  BC DYNAMICS"
   delay(del); 
   if (digitalRead(10) == 0 && BC_DYNAMICS != 1){BC_DYNAMICS--;}
   if (digitalRead(11) == 0 && BC_DYNAMICS != 250){BC_DYNAMICS++;}
   if (digitalRead(12) == 0){key = 6;mix = 4;lcd_0 = 1;vst = 16;} // BC TIME
   lcd.setCursor(7, 1);lcd.print(BC_DYNAMICS);lcd.print(" ");
 break;
   case 12: // BM
   delay(del);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 4;}
   if (digitalRead(11) == 0){mix++;} if (mix == 5){mix = 1;}  
   if (mix == 1){lcd_1 = 1;vst = 4;}  // OFF / ON
   if (mix == 2){lcd_1 = 1;vst = 7;}  // MIN / MAX
   if (mix == 3){lcd_1 = 1;vst = 10;}  // TIME
   if (mix == 4){lcd_1 = 1;vst = 3;} // <<<<
   if (digitalRead(12) == 0 && mix == 1){key = 4;mix = 1;lcd_0 = 1;vst = 22;} // BM (OFF / ON)
   if (digitalRead(12) == 0 && mix == 2){key = 5;mix = 1;lcd_0 = 1;vst = 23;} // BM (MIN / MAX)
   if (digitalRead(12) == 0 && mix == 3){key = 6;mix = 1;lcd_0 = 1;vst = 24;} // BM TIME
   if (digitalRead(12) == 0 && mix == 4){key = 2;mix = 3;lcd_0 = 1;vst = 1;}  // MENU
 break;
   case 13: // BM (OFF / ON)
   delay(del);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 2;}
   if (digitalRead(11) == 0){mix++;} if (mix == 3){mix = 1;}
   if (mix == 2){lcd_1 = 1;vst = 5;} // OFF
   if (mix == 1){lcd_1 = 1;vst = 6;} // ON
   if (digitalRead(12) == 0 && mix == 2){key = 2;BM = 0;mix = 3;lcd_0 = 1;vst = 1;} // MENU
   if (digitalRead(12) == 0 && mix == 1){key = 3;BM = 1;mix = 4;lcd_0 = 1;vst = 21;} // BM
 break;
   case 14: // BM (MIN / MAX)
   delay(del);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 3;}
   if (digitalRead(11) == 0){mix++;} if (mix == 4){mix = 1;}
   if (mix == 1){lcd_1 = 1;vst = 8;} // MIN 
   if (mix == 2){lcd_1 = 1;vst = 9;} // MAX
   if (mix == 3){lcd_1 = 1;vst = 3;} // <<<<
   if (digitalRead(12) == 0 && mix == 1){key = 7;mix = 1;lcd_0 = 1;lcd_1 = 0;vst = 25;} // BM MIN
   if (digitalRead(12) == 0 && mix == 2){key = 8;mix = 1;lcd_0 = 1;lcd_1 = 0;vst = 26;} // BM MAX
   if (digitalRead(12) == 0 && mix == 3){key = 3;mix = 4;lcd_0 = 1;lcd_1 = 0;vst = 21;} // BM
 break;
   case 15: // BM TIME
   delay(del);lcd.noCursor();
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 4;}
   if (digitalRead(11) == 0){mix++;} if (mix == 5){mix = 1;}  
   if (mix == 1){lcd_1 = 1;vst = 4;}  // OFF / ON
   if (mix == 2){lcd_1 = 1;vst = 10;} // TIME
   if (mix == 3){lcd_1 = 1;vst = 11;}  // DYNAMICS"
   if (mix == 4){lcd_1 = 1;vst = 3;} // <<<<
   if (digitalRead(12) == 0 && mix == 1){key = 9 ;mix = 1;lcd_0 = 1;vst = 27;} // BM TIME(OFF/ON)
   if (digitalRead(12) == 0 && mix == 2){key = 10;mix = 1;lcd_0 = 1;vst = 24;tim = 3;lcd_1 = 0;lcd.setCursor(0,1); lcd.print(myStrings[12]);} // BM TIME
   if (digitalRead(12) == 0 && mix == 3){key = 11;mix = 1;lcd_0 = 1;vst = 28;lcd_1 = 0;lcd.setCursor(0,1); lcd.print(myStrings[12]);} // BM DYNAMICS
   if (digitalRead(12) == 0 && mix == 4){key = 3 ;mix = 4;lcd_0 = 1;vst = 21;} // BM
 break;
   case 16: // BM MIN
   delay(del);
   if (digitalRead(10) == 0){BM_MIN--;} if (BM_MIN == 49){BM_MIN++;}
   if (digitalRead(11) == 0){BM_MIN++;} if (BM_MIN == (BM_MAX - 4)){BM_MIN--;}
   if (digitalRead(12) == 0){key = 5;mix = 1;lcd_0 = 1;vst = 23;} // BM (MIN / MAX)
   lcd.setCursor(5, 1);lcd.print(BM_MIN / 10);lcd.print(".");lcd.print(BM_MIN % 10);lcd.print(" Ph");
 break;
   case 17: // BM_MAX
   delay(del);
   if (digitalRead(10) == 0){BM_MAX--;} if (BM_MAX == (BM_MIN+4)){BM_MAX++;}
   if (digitalRead(11) == 0){BM_MAX++;} if (BM_MAX == 101){BM_MAX--;}
   if (digitalRead(12) == 0){key = 5;mix = 3;lcd_0 = 1;vst = 23;} // BM (MIN / MAX)
   lcd.setCursor(5, 1);lcd.print(BM_MAX / 10);lcd.print(".");lcd.print(BM_MAX % 10);lcd.print(" Ph");
 break;
   case 18: // BM / TIME (OFF / ON)
   delay(del);
   if (digitalRead(10) == 0){mix--;} if (mix == 0){mix = 2;}
   if (digitalRead(11) == 0){mix++;} if (mix == 3){mix = 1;}
   if (mix == 1){lcd_1 = 1;vst = 5;} // OFF
   if (mix == 2){lcd_1 = 1;vst = 6;} // ON
   if (digitalRead(12) == 0 && mix == 1){key = 6;BM_TIME_D = 0;mix = 4;lcd_0 = 1;vst = 24;} // BM TIME
   if (digitalRead(12) == 0 && mix == 2){key = 6;BM_TIME_D = 1;mix = 4;lcd_0 = 1;vst = 24;} // BM TIME
 break;
   case 19: // BM TIME
   delay(del);
   if (digitalRead(10) == 0 && BM_TIME >= pow (10,tim)){BM_TIME -= pow (10,tim);}
   if (digitalRead(11) == 0){BM_TIME += pow (10,tim);}
   if (digitalRead(12) == 0 && tim == 0){key = 6;mix = 4;lcd_0 = 1;vst = 24;} // BM TIME
   if (digitalRead(12) == 0){tim--;}
   if (BM_TIME < 5000){BM_TIME = 5000;} if (BM_TIME > 99000){BM_TIME = 99000;}
   lcd.setCursor(5, 1);if (BM_TIME < 10000){lcd.print("0");}lcd.print(BM_TIME);lcd.print(" mS");lcd.setCursor((9-tim), 1);lcd.cursor();
break;
   case 20: //"  BM DYNAMICS"
   delay(del); 
   if (digitalRead(10) == 0 && BM_DYNAMICS != 1){BM_DYNAMICS--;}
   if (digitalRead(11) == 0 && BM_DYNAMICS != 250){BM_DYNAMICS++;}
   if (digitalRead(12) == 0){key = 6;mix = 4;lcd_0 = 1;vst = 24;} // BM TIME
   lcd.setCursor(7, 1);lcd.print(BM_DYNAMICS);lcd.print(" ");
 break;
   case 21: //"PA6OTA"
   delay(del);
   lcd.clear();lcd.home();
   lcd.print("PA6OTA");
   break;
  }
}
У атмеги328 тяпает 12 354 bytes (40%), вроде как много но это пока черновик и для лучшего понимания как и что делается, в дальнейшем прилизывании убавится.
 
Теперь по порядку.
Создаются переменные которые необходимо изменять, переменные для работы меню добавляются постепенно по мере их необходимости.
Создается массив надписей которые будут участвовать в меню char* myStrings[]={ }
В сетапе иницилизируются кнопки (лично мне нравится сразу програмно подтягивать к +5в), трёх кнопок для управления вполне хватает, 10 и 11 вне меню во время работы можно использовать по своему усмотрению.
if (lcd_0 == 1) {
lcd.setCursor(0,0); lcd.print(myStrings[12]); 
lcd.setCursor(((16 - (String(myStrings[vst])).length())/2), 0); lcd.print(String(myStrings[vst]));
lcd_0 = 0;}
данная под программа необходима для меню первой стороки, производит очиску, команда myStrings[vst])).length()) вычисляет вычисляет сколько букв в слове из массива myStrings[] под номером vst, простое деление на два с последующим вычитании из 16 оцентрует нужнуе слово, к примеру если надо чтоб в первой строке написалось BC MIN мне всеголиш надо написать lcd_0 = 1;vst = 17; , точно так-же и для второй строки другая подпрограмма где указывается lcd_1 = 1;.
 
Всё меню построенно на switch...case меню работает в перых 20, основная программа в 21.
Вход в меню осуществляется долгим нажатием на 12 пин в программе это 
if (digitalRead(12) == 0){pas++; if (pas >= 8){key = 1;lcd_0 = 1;vst = 0;pas = 0;PASSWORD = 0;lcd.clear();delay(800);}} else{pas = 0;}
Далее четыре вида меню:
переход из меню в другое меню case 2, 3, 5, 6, 12, 13, 15 ;
изменение boolean переменной case 4, 9, 13, 18;
изменение byte переменной case 1, 7, 8, 11, 16, 17, 20;
изменение unsigned long переменной case 10, 19.
 
В меню пароля после нажатия 12-пин происходит сравнение паролю по умолчанию 247.
В меню с переменной boolean вместо 0, 1 подставляются значения OFF, ON соответственно.
В меню 7, 8, 16, 17 число разделяется для визуальной подстановкой точки и дополняется надписью, к примеру значение 74 то на лсд будет 7.4 Ph и ограничивается чтоб значение межды минимум и максимум не уменьшилось меньше пети и было в границе от 50 до 100.
В меню 10 и 19 постепенное изменение числа с использованием подсведки курсора.

P.S. Если кому-то покажется что можно было использовать какую ни буть библиотеку, то лично я для своих хотелок ничего нужного не нашол. Надеюсь что это кому-нибуть поможет, что не за зря я тут целый час распинался расписывая данную тему.

fagot
Offline
Зарегистрирован: 28.04.2015

vov4ik, очень интересная тема, я тоже долго искал пример меню но ничего не нашел. На текстовом дисплее у менятеперь своя методика. Мне нравится 4 кнопки для управления. Столкнулся с проблемой создания меню на 5110. У вас есть наработки меню для 5110? 

Р.S. клавиатура у меня подключена к 1 пину её опрос это отдельная продцедура: 

byte key(){    // для кнопок 
    int val = analogRead(0);
    delay (10);
    if (val < 50) return 5;        //next кнопка меню
    else if (val < 150) return 3;  //up увеличение значения отображаемого параметра
    else if (val < 350) return 4;  //down уменьшение значения отображаемого параметра
    else if (val < 500) return 2;  //prev кнопка возврата
    else if (val < 800) return 1;  //в меню и запись параметров и состояния в EEPROM
    else return 0;                 //
}

 

 
 

 

Andrey-S
Offline
Зарегистрирован: 02.01.2015
vvadim
Offline
Зарегистрирован: 23.05.2012

безкорыстная работа это есть хорошо.

но раз делали для новичков неплохо было бы нормально блок-схему нарисовать да и код ваш нечитабельный - форматнули бы перед тем как выложить

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

для изменения значений переменных я использую функцию (собственнонаписанную, на написание которой у меня ушли все мои скудные (пока) познания в программировании):

int change_valum											
(char name[],int begin_valum,int min, int max,bool print) 
{
  int valum=begin_valum;
  bool press_1 = false;
  bool press_2 = false;
  String sname=name;
  bool screen_update = false;
  bool screen_update_2 = false;
  while(!screen_update_2)                    
  {
    screen_update=false;
    if(print)
    {
      lcd.clear();
      lcd.setCursor(8-sname.length()/2,0);
      lcd.print(name);
      lcd.setCursor(7,1);
      lcd.print(valum);
    }
    while(!screen_update)						
    {														
      if (b_2.click_down)
      {										
        valum+=1;					
        valum=constrain(valum,min,max);						
        screen_update=true;
        if(!print)screen_update_2=true;
      }										
      if (b_2.retention&&print)
      {
        press_2=true;
      }				
      if (press_2)								
      {										
        valum+=1;					
        valum=constrain(valum,min,max);			
        delay(150);
        screen_update=true;
      }										
      if (b_2.click_up)
      {
        press_2=false;
      }															
      if (b_1.click_down)
      {										
        valum-=1;
        valum=constrain(valum,min,max);
        screen_update=true;
        if(!print)screen_update_2=true;
      }										
      if (b_1.retention&&print)
      {
        press_1=true;
      }					
      if(press_1)								
      {										
        valum-=1;					
        valum=constrain(valum,min,max);						
        delay(150);		
        screen_update=true;
      }										
      if (b_1.click_up)
      {
        press_1=false;
      }
      if (b_3.click_down)
      {
        screen_update=true;
        screen_update_2=true;
        enter_menu=true;
      }
      button_update();
    } 
 }
 if(print)
 {
   lcd.clear();
   lcd.setCursor(14,1);
   lcd.print("OK");
   delay(50);
 }
  return valum;
}											

Здесь используется класс "ТИТАНОВЫЙ ВЕЛОСИПЕД ДЛЯ ТАКТИЛЬНОЙ КНОПКИ" Клапауция, за что ему отдельное спасибо,(можно найти на форуме)

b_1, b_2, b_3 это кнопочки

функция button_update обновляет состояния кнопок и выглядит так:

void button_update()
{
  b_1.read();
  b_2.read();
  b_3.read();
}

Фишка в том, что при долгом нажатии на кнопку (длительность настраивается в велсипеде) переменная начинает перекручиваться сама (делайем настраиваем скорость перескакивания).

Из программы вызывается следующим образом:

min_r[x]=change_valum("SET MINUTE",min_r[x],0,59,1);

Последний флаг я использую, если ничего печатать не надо, на пример в меню (печатаем все перед обращением к change_valum)

lcd.clear();
lcd.print("OVER WRITE?");
lcd.setCursor(3,1);
lcd.print("NO  YES  ESC");
byte choise=change_valum("",0,0,1,0);

при нажатии на кнопку b_2 choise принимает значение 1 и сразу выдает ее, причем на экран мы не выводим ничего.

И еще, кнопка b_3 делает глобальный флаг enter_menu=true, до следующего обращения его нужно в основной программе сделать false. Я понимаю что это немного криво, но мне пока так удобно, на большего моих знаний не хватает.

Может кому-нибудь из "новичков" пригодится, а также жду от "старичков" критику. В последствии планирую оптимизировать, когда знаний набирусь....

 

 

nik182
Offline
Зарегистрирован: 04.05.2015

Мне нравиться micromenu. http://www.avrfreaks.net/projects/micromenu

или вторая реинкорнация https://github.com/abcminiuser/micromenu-v2

Всё просто. Чётко структуировано. Подпрограмма обработки пунктов меню одна. Задать направление переходов внутри меню можно как угодно. На двух строчном дисплее всегда видно родителя и текущий пункт. Очень легко вставлять - удалять пункты меню. 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

тема лсд не раскрыта