ардуино меню лсд , arduino menu lcd
- Войдите на сайт для отправки комментариев
Эта тема как просто сделать меню на лсд, в тех проектах где используются простые не дорогие экранчики, появляется необходимость сделать меню для изменения переменных участвующих в работе, начинающим очень сложно даже представить с чего начать.
Первое что необходимо создать топологию, какие переменные необходимы для изменения.
В любой программе нужно начертить то что будет из себя предстовлять меню.
Как видно в меню я использую 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;
}
}
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 (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;}P.S. Если кому-то покажется что можно было использовать какую ни буть библиотеку, то лично я для своих хотелок ничего нужного не нашол. Надеюсь что это кому-нибуть поможет, что не за зря я тут целый час распинался расписывая данную тему.
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; // }Я пользуюсь этим: http://forum.amperka.ru/threads/%D0%91%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA%D0%B0-%D0%B4%D0%BB%D1%8F-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D0%9C%D0%B5%D0%BD%D1%8E-%D0%BD%D0%B0-%D0%B4%D0%B8%D1%81%D0%BF%D0%BB%D0%B5%D1%8F%D1%85.1815/ ... Вполне устраивает всем:-)
безкорыстная работа это есть хорошо.
но раз делали для новичков неплохо было бы нормально блок-схему нарисовать да и код ваш нечитабельный - форматнули бы перед тем как выложить
http://geektimes.ru/post/255020/
для изменения значений переменных я использую функцию (собственнонаписанную, на написание которой у меня ушли все мои скудные (пока) познания в программировании):
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. Я понимаю что это немного криво, но мне пока так удобно, на большего моих знаний не хватает.
Может кому-нибудь из "новичков" пригодится, а также жду от "старичков" критику. В последствии планирую оптимизировать, когда знаний набирусь....
Мне нравиться micromenu. http://www.avrfreaks.net/projects/micromenu
или вторая реинкорнация https://github.com/abcminiuser/micromenu-v2
Всё просто. Чётко структуировано. Подпрограмма обработки пунктов меню одна. Задать направление переходов внутри меню можно как угодно. На двух строчном дисплее всегда видно родителя и текущий пункт. Очень легко вставлять - удалять пункты меню.
тема лсд не раскрыта