Помогите пожалуйста по меню.
- Войдите на сайт для отправки комментариев
Добрый день всем форумчанам.
Помогите пожалуйста, уже сил нет, хочется освоить но застрял и не знаю что делать.
Уже месяц не могу сделать меню, перепробовал сотню вариантов но не получается.
Раньше програмировал на PHP там все просто, а тут не выходит.
Логика программы следующая. Но как ее реализовть не приложу ума.
1) Главное меню работает кнопкави в низ в верх.
2) Дошли до нужного меню, нажали кнопку ОК и вошли в меню.
3) Работаем только в этом субменю, куда вошли
3.1) Выбрав необходимый раздел подменю, мы работаем в нем.
Например блок Настройки
Имеет следующиее опции.
Включить свет 1 или 0
Включить мотор 1 или 0
Выход Кнопка ОК, вышли в начало субменю
4) Выход осуществляется при выборе пункта ВЫХОД в подменю и нажатии кнопки ок.
Есть 5 кнопок, которые хотел использовать как
вверх, вниз
влево. вправо
пятая кнопка ok или для любого действия
каждая кнопка имеет номерацию
по сути можно использовать и три кнопки.
const byte NONE_MENU= 0; // не нажата ни одна кнопка выводим морду const byte LEFT_MENU=1;//В лево, либо выход const byte RIGHT_MENU = 2;//В право либо вход const byte UP_MENU=3; //ВНИЗ const byte DOWN_MENU=4;//ВВЕРХ const byte SELECT_MENU=5;//Функция выбора или окей
#define TotalMenu 4 //Количество меню в главном меню делаем на 1 больше, для 4х меню делаем значение 5 #define TotalSubMenu 6 //Количество меню в главном меню const byte keypadPin = A5; //Номер аналогового пина для кнопок меню. byte button_key = 0; //Начальное значение переменной байт
//Функция обработчик меню byte getKey() { int val_analog = 0; byte button_key = 0; val_analog = analogRead(keypadPin); //В данный блок можно добавлять сколько угодно меню. if ( val_analog <= 30) { button_key = SELECT_MENU; } // В ЛЕВО else if ( (val_analog >= 35) && (val_analog <=60) ) { button_key = DOWN_MENU;} // Вверх else if ( (val_analog >= 100) && (val_analog <= 150 ) ) { button_key = UP_MENU;}// Вниз else if ( (val_analog >= 200) && (val_analog <= 280) ) { button_key = RIGHT_MENU;}//В ПРАВО else if ( (val_analog >= 580) && (val_analog <650) ) { button_key = LEFT_MENU;}// ВЫБОР else if (val_analog >= 900) { button_key=NONE_MENU;} // По умолчанию если не нажали ни одной кнопки return button_key; }
Данный код который ниже работает При нажатии кнопки 1 он листает по кругу значения от 1 до 4. при нажатии кнопки 2 он листает в обратном направлении.
но не могу перейти в подменю, вернее вхожу но дальше не получается.
#include <SPI.h> #include <Adafruit_TFTLCD.h> #include <Adafruit_GFX.h> #include <TouchScreen.h> #include "DHT.h" #define DHTPIN 10 // what digital pin we're connected to #define DHTTYPE DHT21 // DHT 21 (AM2301) DHT dht(DHTPIN, DHTTYPE); #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define SEREBRO 0xCCCC #define GRAY 0x6d9285 #define GOLUB 0x3AAA #define COLORS GOLUB //Цвет рамки меню горизонтально #define COLORS2 CYAN //Цвет рамки меню горизонтально С права квадратик int posicion[6] = {0,15, 50, 95, 135,175}; // Выделяет координату в виде прямоугольника над надписью меню субменю шрифт размер 3 #define TotalMenu 4 //Количество меню в главном меню делаем на 1 больше, для 4х меню делаем значение 5 #define TotalSubMenu 6 //Количество меню в главном меню const byte NONE_MENU= 0; // не нажата ни одна кнопка выводим морду const byte LEFT_MENU=1;//В лево, либо выход const byte RIGHT_MENU = 2;//В право либо вход const byte UP_MENU=3; //ВНИЗ const byte DOWN_MENU=4;//ВВЕРХ const byte SELECT_MENU=5;//Функция выбора или окей const byte keypadPin = A5; //Номер аналогового пина для кнопок меню. byte button_key = 0; //Начальное значение переменной байт int outblock=1; int block=1; int flag=1; #define TS_MINX 16 #define TS_MINY 118 #define TS_MAXX 909 #define TS_MAXY 918 Adafruit_TFTLCD tft(A3, A2, A1, A0, A4); TouchScreen ts = TouchScreen(6, A1, A2, 7, 300); #define MINPRESSURE 10 //check for any touch 0 would mostly be too senitive. #define MAXPRESSURE 1000 int counter=0; void setup() { Serial.begin(9600); tft.reset(); tft.begin(0x7575); tft.setRotation(1); tft.fillScreen(BLACK); //Фон главного экрана pinMode(keypadPin, INPUT_PULLUP); // Пин аналоговый для кнопок меню. dht.begin(); tft.cp437(true); } //Данная функция во вложенном меню выделяет нужную строку void menu_line(int lines){ tft.fillRect(10, posicion[lines], 240, 40, BLUE); tft.fillRect(220, posicion[lines], 26, 40, BLUE); int ryad= posicion[lines]; tft.setCursor(160, 220); tft.setTextColor(YELLOW); tft.print(ryad); } void(* resetFunc) (void) = 0; void loop() { menu_block(); } //Главный блок меню void menu_block(){ button_key = getKey(); funcmenu(block,TotalMenu); //Функция передает значение block++; и количество меню 4 tft.setTextSize(3); tft.setTextColor(WHITE,BLACK); tft.setCursor(10, 10); if(block==1 && flag ==0) {tft.print("BLOCK A");} if(block==2 && flag ==0) {tft.print("BLOCK B"); if(button_key==3) { configuration(); } } if(block==3 && flag ==0) {tft.print("BLOCK C");} if(block==4 && flag ==0) {tft.print("BLOCK D");} } //Вложенное меню void configuration() { funcmenu(block,TotalSubMenu); //Функция передает значение block++; и количество меню tft.setTextSize(3); tft.setTextColor(WHITE,BLACK); tft.setCursor(10,120); tft.print("subblock\t"); tft.print(block); menu_line(outblock); //Передаем значение цикла tft.setTextSize(3);//Размер текста, настройки в верху tft.setTextColor(WHITE); tft.setCursor(16, 20); tft.print(utf8rus("Блок е")); tft.setCursor(16, 60); tft.print(utf8rus("блок а")); tft.setCursor(16, 100); tft.print(utf8rus("блок 3")); tft.setCursor(16, 140); tft.print(utf8rus("В верх")); tft.setCursor(16, 180); tft.print(utf8rus("Выход")); } //Функция обработчик меню byte getKey() { int val_analog = 0; byte button_key = 0; val_analog = analogRead(keypadPin); //В данный блок можно добавлять сколько угодно меню. if ( val_analog <= 30) { button_key = SELECT_MENU; } // В ЛЕВО else if ( (val_analog >= 35) && (val_analog <=60) ) { button_key = DOWN_MENU;} // Вверх else if ( (val_analog >= 100) && (val_analog <= 150 ) ) { button_key = UP_MENU;}// Вниз else if ( (val_analog >= 200) && (val_analog <= 280) ) { button_key = RIGHT_MENU;}//В ПРАВО else if ( (val_analog >= 580) && (val_analog <650) ) { button_key = LEFT_MENU;}// ВЫБОР else if (val_analog >= 900) { button_key=NONE_MENU;} // По умолчанию если не нажали ни одной кнопки return button_key; } // Функция нажатий кнопок перехода по меню, в цикле колесом. void funcmenu(int outblok, int CountMenu) { button_key = getKey(); // Получить номер от нажатой кнопки. от 1 до 4 if(button_key==1&&flag==0)//если нажата кнопка в низ то прибавить 1 { block++; flag=1; //это нужно для того что бы с каждым нажатием кнопки //происходило только одно действие // плюс защита от "дребезга" 100% if(block > CountMenu ){block=1; } } // Уменьшает значение на 1 еденицу if(button_key==2&&flag==0)//если кнопка нажата { block--; flag=1; if( 1 > block) {block=CountMenu;} } if(button_key==0&&flag==1) { flag=0; } //обнуляем переменную flag если кнопка НЕ нажата outblok = block; } void clearmessage() { tft.fillRect(0,0, 320, 240, BLACK);// } void TEST_display_3() { tft.setCursor(0, 0); tft.setTextColor(CYAN); tft.setTextSize(3); tft.println(utf8rus("АБВГДЕЖЗИЙКЛМНОП")); tft.println(utf8rus("РСТУФХЦЧШЩЪЫЬЭЮЯ")); tft.println(utf8rus("абвгдежзийклмноп")); tft.println(utf8rus("рстуфхцчшщъыьэюя")); tft.println(utf8rus("Ёё123ABCabc!@#\xBC\xBD")); tft.println(utf8rus("10\x83 10\x8A\x82 10\x81\x80 2\x85")); } /* Recode russian fonts from UTF-8 to Windows-1251 */ String utf8rus(String source) { int i,k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; }
Раньше програмировал на PHP там все просто, а тут не выходит.
Именно в этом проблема. Тяжелое наследие пыхи так даром не проходит никому. Почитайте форум, здесь каждый второй немощный раньше для веба писал. Потому и веб такой :( Хороший доход от плохого кода надолго меняет человека. Вижу два выхода или заработать достаточно денег и заказать проект в соответствующем разделе или много и долго пить, чтоб память отшибло, потом начинать изучение информатики с подхода и включения ПК.
Раньше програмировал на PHP там все просто, а тут не выходит.
Именно в этом проблема. Тяжелое наследие пыхи так даром не проходит никому. Почитайте форум, здесь каждый второй немощный раньше для веба писал. Потому и веб такой :( Хороший доход от плохого кода надолго меняет человека. Вижу два выхода или заработать достаточно денег и заказать проект в соответствующем разделе или много и долго пить, чтоб память отшибло, потом начинать изучение информатики с подхода и включения ПК.
Пк я изучил тет 15 назад, так как посточнно ремонтироват и переустанавливать систему было дорого.
Програмровал раньше как хобби, зарабатывал хватало на домены ихостинг. Сейчас интернет забросил, так как кризис ( доходов кот плакал аж 2- 3 к руб в месяц) надолго незнаю.
Можно конечно оставить ардуину и забросить, хотя охота научится чему то.
Книг я прочитал несколько штук по ардуино и прочим, только там задачи совсем не продходят.
Хочу для себя сделать блок для котла, так как тот что стоит шибко дубовый.
Мне бы саму суть понять.
Хотя бы пример простейшей функции
где есть меню пару разделов и в одном из них подменю, дальше пробовал бы сам лепить.
Просто я могу сделать каждыйц раздел меню в виде списка.
то есть например
2 кнопки в цикле прокручивают меню.
принцип следующий.
flag==1 Меню главное
flag==2 Котел выключить, включить
flag==3 Насос включить, выключить
flag==4 Возврат в главное меню.
Но это будет ерунда.
Разумеется У Ардуины нет даже среды разработки по типу borland c++, которые давали готовые компоненты в программу. Да и компонент нет . Их надо создавать самому. Связывать работу между готовыми компонентами надо самому. Опять же создавать и разрушать компоненты при переходе на новое окно не сильно получится .Нет у Ардуины так много памяти. Так что у Ардуины все жестко компонент поле экран, и компонент кнопки. Только переключать управление надо при переходе от экрана к экрану,от переменой к переменной, от режима показа к режиму программирования. Да и еще кнопок у Ардуины мало. И мышь не работает.
Да и еще вверх- вниз это переход с экрана на экран, влево -вправо это переход от одной переменной к другой, селект это переход в режим редактирования переменных.Которые редактируют опять же влево вправо. Ну разве что вверх вниз шаг +10/-10.
да кто только не делал меню. ищи в проектах
Да и еще кнопок у Ардуины мало. И мышь не работает.
Да и еще вверх- вниз это переход с экрана на экран, влево -вправо это переход от одной переменной к другой, селект это переход в режим редактирования переменных.Которые редактируют опять же влево вправо. Ну разве что вверх вниз шаг +10/-10.
Спасибо, буду вникать. На счет кнопок их много и не надо, хватит трех. Самое сложное логику реализовать.
Я делал на сеносрном экране меню, все работало но занимало 2 пина.
Потом делал на цифровых выходах но уже кнопками, тоже все работало.
А сейчас мозг закипает, застрял именню на менюшке.
У меня экран TFT и работаю с библиотекой Adafruit
Все меню в сети валяются сделаны на LiquidCrystal
Еще есть MICRO-MENU но там я вообще не понимаю нифига.
Так надо вникать в указатели, указатели на функцию,указатели на объекты, классы,структуры . И самое главное не использовать delay и другие тормоза, освоить millis(). Так что с разбегу не поймете даже если вы увидете рабочий код. Вот по этой причине так много вариантов меню и народ не очень хочет втягиваться в геморой - научить новичка писать меню.
А это так бонус от меня. Полный скетч здесь https://yadi.sk/d/QMBIxpjE3GZcLo
Головной выложу тут
Так надо вникать в указатели, указатели на функцию,указатели на объекты, классы,структуры . И самое главное не использовать delay и другие тормоза, освоить millis(). Так что с разбегу не поймете даже если вы увидете рабочий код. Вот по этой причине так много вариантов меню и народ не очень хочет втягиваться в геморой - научить новичка писать меню.
А это так бонус от меня. Полный скетч здесь https://yadi.sk/d/QMBIxpjE3GZcLo
Я согласен полностью, новичков учить дело сложное.
А вот вникать в указатели, указатели на функцию,указатели на объекты, классы,структуры
это как раз сложно, если нет толковой информации, функции и указатели как раз сложно освоить, хотя еще сложнее освоить ООП.
Тут важно внимать с малого.
Я купил ардукинку три месяца назад, месяц вообще смотрел на нее как на новые ворота.
Затем освоил библиотеку TFT adafruit. Начал рисовать кнопки на сенсорном экране, освоил работу сенсора,
ну и по нарастающей. Mills очень полезная штука, от delay я сразу отказался так как понял что он не нужен.
За бонус Спасибо огромное, буду по маленьку изучать.
Вы правы на счет готовых библиотек, гораздо легче освоить и написать свой код, чем изучать чужой.
Но я стараюсь подглядыват в чужой код, там бывает много интересных решений.
Поглядел я код. Для меня там где классы пока еще сложновато, хоят я в книге изучал классы.
Но я так понял это полностью рабочий код, и он должен работать при нажатии кнопок на клавиатуре.
У меня значения на клавиатуре другие я сменил их
Если вы скачали скетч и просто запустили, то все там будет работать. Нажатие на кнопку отправить сообщение на монитор. Но его надо открыть. Бывает такое. Вы клавиатуру повесили не на ту ногу, что в программе. И еще куча детских ляпов.
Вот мои кнопки. Но проблема в том что мои кнопки дают шум, тоесть у меня значение на кнопке 1 может быть от 30 до 60, на второй от 60 до 10. И так далее.
Видимо кнопки надо делать как то по другому.
У вас если я правильно понимаю условие будет срабатываеть если значения не будут превышать перменную a.
Ошибку нашел, пин у меня A5. Спасибо за бонус, теперь должно работать.
Щас проверил входные значения.
кнопки отключены полностью, значения скачут
http://zelectro.cc/Z-Keyboard_module.
Вывов функции идет когда был момент не нажато ничего и нажата опред кнопка.
похоже нужен разгрузочный резистор на Anlg_pin = A5;
и питание в место земли.
с резистором по умолчанию идут нолики
щас переделаю по этой схеме
А Вам точно не надо понимать что нажато две (или более) кнопок одновременно? По такой схеме - не получится.
В интернете много вариантов программ меню. Даже больше скажу, любой новичек пытается это написать самостоятельно. Вот и я написал очередную. Аналоговые кнопки 5 штук , и вывод в Serial. Раземеется можно поменять на другое подключение. Ну ладно полный скетч здесь. https://yadi.sk/d/P8lVDzcF3Gg4rq Головной файл выкладываю.
Не много не понял ваш вопрос.
Вы про чей вопрос? Мой?
похоже нужен разгрузочный резистор на Anlg_pin = A5;
и питание в место земли.
с резистором по умолчанию идут нолики
щас переделаю по этой схеме
схема норм но я бы применил еще и стабилитрон на 4.7в
схема норм но я бы применил еще и стабилитрон на 4.7в
Напомнили эпизод из фильма. Я дам вам парабеллум! - Двенадцать стульев https://www.youtube.com/watch?v=atZ6HRccqzU
ЕвгенийП Да, про ваш, немного не понял.
Подскажите пожалуйста, можно ли внутри функций делать
Просто у меня если кодключить while не работает код в loop.
не срабатывает код
Есть
ЕвгенийП Да, про ваш, немного не понял.
Ну, чего там не понимать. Впорос простой. Нужно ли Вам обрабатывать одновременное нажатие двух или боле кнопок?
ЕвгенийП Да, про ваш, немного не понял.
Ну, чего там не понимать. Впорос простой. Нужно ли Вам обрабатывать одновременное нажатие двух или боле кнопок?
Аа понял спасибо.
Думаю что не нужно.
У меня тут ошибка вылазит все время если использую в место print println
сейчас добавил скетч датчика температуры и снова ошибка
Arduino: 1.8.1 (Windows XP), Плата:"Arduino/Genuino Uno"
Тут у меня вот так компилит нормально без ошибки
Это частая ошибка на WinXP. Нужно либо пользоваться старой версией Arduino IDE (например 1.0.5), либо взять со старой версии файл ld.exe и скопировать его с заменой в новую версию IDE.
Пробовал, но что то не помогло. Надо попробовать еще разок скачать его.