меню для дисплея ардуино
Про Ардуино и не только
четверг, 4 января 2018 г.
Текстовое меню на Ардуино
Меню верхнего уровня в данном скетче содержит 2 элемента: первый для решения квадратных уравнений, второй просто как пример построения многоуровнего меню. Параметр ReturnFromMenu установлен в 0 и при выборе пунктов меню вызываются соответствующие обработчики. Так осуществляется задание коэффициентов квадратного уравнения и нахождение его корней (функции InputA, InputB, InputC, Solve). В обработчиках следует помнить об управлении подсветкой дисплея, для этого регулярно вызывается функция LCDBacklight. Функция loop содержит единственный вызов DrawMenu. Вся дальнейшая работа будет заключаться в отрисовке меню и выполнении функций-обработчиков.
Вот в общем-то и всё, остальное должно быть понятно из примера. Ну и в заключение дочитавшим до конца предлагаю видео работы этого меню:
90 комментариев:
Здравствуйте тёзка. Я «полный новичок» в ардуино, самостоятельно накидать менюшку с управлением энкодером, для меня, как-то сложновато. Поиск дал кучу вариантов.
Но Ваша работа наиболее качественная, и фишки в виде бегущего текста, вообще супер.
Но, сходу использовать скетч, не прокатило.
На версии IDE 1.6.7 (Uno R3) заругалась на строку «eMenuKey DrawMenu(eMenuKey Key)» словами «does not name a type». Подскажите, что можно сделать? И ой, чувствую, вопросов будет куча.
Попробовал оба варианта путей к скетчу, и с «C:\Новая папка\Arduino_KY040_Menu» и просто из корневухи С:\Arduino_KY040_Menu. Не выходит. Выдает целый список «недовольств»:
Arduino: 1.6.7 (Windows 7), Плата:»Arduino/Genuino Uno»
Arduino_KY040_Menu:192: error: ‘eMenuKey’ does not name a type
eMenuKey DrawMenu(eMenuKey Key) < // Отрисовка указанного уровня меню и навигация по нему
^
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
>;
^
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
Arduino_KY040_Menu:172: error: invalid conversion from ‘void* (*)()’ to ‘void (*)()’ [-fpermissive]
C:\Users\foto\AppData\Local\Temp\arduino_0e105e996471fbde0dc2a2dfa2384703\Arduino_KY040_Menu.ino: In function ‘void LCDBacklight(byte)’:
Arduino_KY040_Menu:175: error: default argument given for parameter 1 of ‘void LCDBacklight(byte)’ [-fpermissive]
^
Arduino_KY040_Menu:30: error: after previous specification in ‘void LCDBacklight(byte)’ [-fpermissive]
void LCDBacklight(byte v = 2);
^
exit status 1
‘eMenuKey’ does not name a type
Я использую версию 1.6.12. Она таких ошибок не выдавала, как и web редактор create.arduino.cc.
Скачал 1.6.7, немного изменил скетч, скомпилировалось без ошибок. Пробуйте.
Но это всё так, навскидку.
Разумеется, заголовок прокручиваться не будет, это надо учитывать. Добавить прокрутку можно, но, мне кажется, это перегрузит меню.
Arduino.ru
Первое что необходимо создать топологию, какие переменные необходимы для изменения.
В любой программе нужно начертить то что будет из себя предстовлять меню.
Как видно в меню я использую 20 блоков пароль, начальное меню и две эдинтичные ветки по девять блоков.
P.S. Если кому-то покажется что можно было использовать какую ни буть библиотеку, то лично я для своих хотелок ничего нужного не нашол. Надеюсь что это кому-нибуть поможет, что не за зря я тут целый час распинался расписывая данную тему.
vov4ik, очень интересная тема, я тоже долго искал пример меню но ничего не нашел. На текстовом дисплее у менятеперь своя методика. Мне нравится 4 кнопки для управления. Столкнулся с проблемой создания меню на 5110. У вас есть наработки меню для 5110?
Р.S. клавиатура у меня подключена к 1 пину её опрос это отдельная продцедура:
безкорыстная работа это есть хорошо.
для изменения значений переменных я использую функцию (собственнонаписанную, на написание которой у меня ушли все мои скудные (пока) познания в программировании):
Здесь используется класс «ТИТАНОВЫЙ ВЕЛОСИПЕД ДЛЯ ТАКТИЛЬНОЙ КНОПКИ» Клапауция, за что ему отдельное спасибо,(можно найти на форуме)
b_1, b_2, b_3 это кнопочки
функция button_update обновляет состояния кнопок и выглядит так:
Фишка в том, что при долгом нажатии на кнопку (длительность настраивается в велсипеде) переменная начинает перекручиваться сама (делайем настраиваем скорость перескакивания).
Из программы вызывается следующим образом:
Последний флаг я использую, если ничего печатать не надо, на пример в меню (печатаем все перед обращением к change_valum)
при нажатии на кнопку b_2 choise принимает значение 1 и сразу выдает ее, причем на экран мы не выводим ничего.
И еще, кнопка b_3 делает глобальный флаг enter_menu=true, до следующего обращения его нужно в основной программе сделать false. Я понимаю что это немного криво, но мне пока так удобно, на большего моих знаний не хватает.
Может кому-нибудь из «новичков» пригодится, а также жду от «старичков» критику. В последствии планирую оптимизировать, когда знаний набирусь.
Опубликовано: 09.10.2017 22:39
Всем доброго. В этой статье мы познакомимся с созданием одноуровневого меню. В основу создания меню заложен скетч, используя который мы постепенно наращивали функционал меню представленного в статье. Предпосылкой реализации меню для LCD дисплея послужили несколько статей, а именно:
Передвигаться по пунктам меню можно с помощью кнопок 2(вверх) и 8(вниз), кнопка ENT служит для подтверждения/входа, кнопка ESC служит для отмены/выхода.
Как работает этот скетч? Это можно увидеть из нижеследующего видео.
Конечно же автор проекта на этом не остановился, когда создана основа, можно только наращивать функционал и потенциал. Дальнейшие действия были направлены на то чтобы реализовать функционал для пунктов уже имеющегося одноуровневого меню, так сказать создать для каждого пункта свой подпункт. Следующим шагом стало добавление функционала к пунктам меню Set Date и Set Time, соответственно при помощи пункты открывают доступ к настройкам/установкам времени/даты. В одном из экранов установки опций было решено реализовать движение курсора не только вверх/вниз при выборе нужных подпунктов но и вправо/влево, эта функция была прописана и дополнена к кнопкам 4(влево) и 5(вправо).Простое меню для Arduino
И так, пока ждем посылки из Китая со всеми компонентами. Сделаем простенькое меню для Arduino и LCD Keyboard шилда.
Как выглядит готовый результат:
Программировать я больше привык в Visual Studio (сейчас у меня версия communit 2015) + Arduino для Visual Studio
Меню у меня просто плоское, без вложенных подменю, мне кажется так проще и понятнее, у каждого наименования параметра есть код, который поможет описать его в инструкции или документации. Для начала у меня только параметры настройки даты и времени, которые будут сохраняться в модуль реального времени, при нажатии “save & exit”. Код получился простой и я надеюсь понятный.
Итак, готовая прошивка для простого меню с комментариями:
Надеюсь, этот код кому-то сэкономит время, прошу не стесняться комментировать =)
20 thoughts on “ Простое меню для Arduino ”
Пытаюсь использовать ваш код но выдает что переменнные не задекларированы
MenuSaveRam’ was not declared in this scope
Это проблема компилятора, я когда-то сталкивался с такой, надо объявление функций и структур вынести в заголовочный файл (.h)
подскажите для чайников как это сделать или где про это почитать. Спасибо!
Мне даже сложно указать на источник, это нюансы самого компилятора и языка си. Я думаю лучше начать с изучения синтаксиса языка http://cppstudio.com/cat/274/. Потом просто учиться по примеру других программ, благо для ардуино много примеров и уроков, тут пользуясь гуглом думаю не промажешь =)
Мне не помогло. Печально
Приветствую, хорошее меню. А можно ли его реализовать на дисплее LCD 1602 I2C и подключеным отдельно на макете кнопкам, если да то что поменять?
Конечно можно, нужно поменять обработку клавиш в этом месте на вашу, читая значение пинов к которым присвоены кнопки в этом месте
if (ButtonPress == 0) < // Если кнопки не были нажаты ранее
int ButtonPinValue = analogRead(0); // Проверяем значение, не нажата ли кнопка
if (ButtonPinValue
А приведёте пример изменения такой записи на 4-5 кнопок, сравнительно с вашим подключением кнопок на шилд (какие команды будут это заменять )? Буду очень благодарен! ^_^
Не совсем понятно как с int ButtonPinValue = analogRead(0) сделать приём с 4-5 выходов Ардуинки.
Ну если это не аналоговый вход а цифровые, тогда надо пользоваться digitalRead()
Ну как-то так:
if (ButtonPress == 0) < // Если кнопки не были нажаты ранее
if (digitalRead(pinButton1)) ButtonPress = 4; // Нажата [+]
else if (digitalRead(pinButton2)) ButtonPress = 2; // Нажата [Prev]
else if (digitalRead(pinButton3)) ButtonPress = 3; // Нажата [Next]
else if (digitalRead(pinButton4)) ButtonPress = 5; // Нажата [-]
else if (digitalRead(pinButton5)) ButtonPress = 1; // Нажата [Menu]
> else …
где pinButton соответственно пин к которому подключена конкретная кнопка
1) У функции void MenuSaveRam(int Concat) < …>потерялась закрывающая фигурная скобка
2)Для того чтобы sprintf(str_format, …) могла отображать результат во всю ширину экранчика, длина массива str_format должна быть 17 (на 1 длиннее ширины экранчика – для хранения нуля, завершающего строку)
Не совсем так =)
1) Скобочка закрывающая есть, одна после if… а вторая после процедуры
2) Длинна и так в 17, так как размерность у массив начинается с 0. От 0 до 16 – 17 символов.
Не получается запустить Ваш скетч. Пишет кучу ошибок:
menu:46: error: ‘MenuSaveRam’ was not declared in this scope
menu:47: error: ‘SettingDateDay’ was not declared in this scope
menu:48: error: ‘SettingDateMonth’ was not declared in this scope
menu:49: error: ‘SettingDateYear’ was not declared in this scope
menu:50: error: ‘SettingTimeHour’ was not declared in this scope
menu:51: error: ‘SettingTimeMin’ was not declared in this scope
C:\Users\Р?ван\Documents\Arduino\menu\menu.ino: In function ‘void loop()’:
menu:80: error: ‘pinButton11’ was not declared in this scope
menu:81: error: ‘pinButton8’ was not declared in this scope
C:\Users\Р?ван\Documents\Arduino\menu\menu.ino: In function ‘void MenuSaveRam(int)’:
menu:127: error: a function-definition is not allowed here before ‘<‘ token
menu:131: error: a function-definition is not allowed here before ‘<‘ token
menu:135: error: a function-definition is not allowed here before ‘<‘ token
menu:139: error: a function-definition is not allowed here before ‘<‘ token
menu:143: error: a function-definition is not allowed here before ‘<‘ token
menu:145: error: expected ‘>’ at end of input
Помогите запустить.
мм круто, но лучше бы вы показали, и не потому что лень разбираться самим….
действительно одна фигурная скобка лишняя:
void MenuSaveRam(int Concat) < // SAVE & EXIT
if (Concat == 1) < //TODO Сохранение параметров в RAM >;
MenuEnter = false; // Выход из меню
>
А если всё, после “// Функции вызываемые для изменения значений переменных” перенести по тексту выше, до “// Главный цикл” то всё заработает.
точнее перенести выше “// Тип структуры данных описывающих пункт меню”, до описания пунктов меню
Спасибо! Скобка реально потерялась ))
Здравствуйте! Подскажите пожалуйста – после того как Вы скомпилировали код в VS, как и чем(как я понимаю что не через ардуино ИДЕ) его загружаете в контроллер? (Писать код в VS действительно удобней).
Текстовое меню на Arduino для дисплея 20х4
В данной статье я бы хотел поделиться опытом создания простого универсального текстового меню для ардуино. Его можно использовать в совершенно различных проектах, меню легко масштабируется под различное количество пунктов, основные его возможности такие:
Итак, для начала немного теории, разберемся с основными принципам построения структуры меню. Для упрощения задачи я отказался от многоуровневой реализации пунктов меню, в основе лежит классический принцип: несколько экранов, на каждом экране несколько строк (пунктов меню), все как в ресторане. Соответственно, общее количество пунктов меню равно произведению количества экранов на количество строк в каждом экране.
Но меню подразумевает не только отображение названий своих пунктов, но так же и возможность назначить на каждый пункт какую-то определенную функцию, а также реализовывать обратную связь с пользователем, например, отображая в конкретном пункте меню значение изменяемой переменной (или вообще любой другой переменной).
Логично для этих целей также использовать двумерные массивы такого же размера, как и основной массив с названиями пунктов меню. Тогда переменные, отвечающие за номер экрана и строки на экране, могут быть использованы также для однозначного указания на внешнюю функцию, прикрепляемую к пункту меню, и для выбора переменной, значение которой необходимо отобразить на экране.
Изначальный размер массива задается в начале прошивки исходя из необходимого максимального числа экранов и максимального числа строк на экране. Однако использовать можно и меньшее количество строк, что будет описано при разборе скетча. Также не являются обязательными прикрепленные функции и переменные для отображения, они могут быть заданы произвольно для любого пункта или не заданы вообще.
Теперь пройдемся по скетчу, разберем основные моменты. В самом начале подключаются необходимые библиотеки для работы с экраном, энкодером и шиной I 2 C:
И в основном подключается библиотека энкодера и собственно файл с кодом меню:
Далее назначаются пины энкодера и опционально алгоритм его работы.
После можно указать требуемое количество экранов и строк на каждом экране:
Если не указать, то по умолчанию будет четыре экрана по пять строк.
После задания названий пунктов меню нужно поставить в соответствие или, проще говоря, прикрепить какие-либо внешние функции. Для каждого пункта меню предусмотрено максимально две функции, они независимы друг от друга, для их назначения используются функции void SetFunc1(uint8_t s, uint8_t l, void *p) и void SetFunc1(uint8_t s, uint8_t l, void *p) соответственно. Синтаксис вызова функций похож на функцию присвоения названий пунктам меню, с той лишь разницей, что кроме координат (номера экрана и номера строки) в функцию передается указатель на прикрепляемую внешнюю функцию. Пример использования:
Здесь мы задали для второй строки первого экрана две функции: включения и выключения светодиода (не забываем, что нумерация элементов массивов начинается с нуля ).
Событие для переключения к предыдущему экрану (menu_one.MakeMenu( 2, 0)) у меня не задано, т.к. количество экранов небольшое и они просто циклично переключаются по кругу, но при необходимости его не трудно добавить.
На этом, пожалуй, все, если что-то непонятно, задавайте вопросы в комментариях. В целом я старался довольно подробно комментировать скетч, так что, думаю, в нем будет несложно разобраться, если это потребуется. Всем спасибо за внимание!