Arduino многоуровневое меню

Реализация многоуровнего меню.

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

Приступим!

Для начала надо подумать какое меню я хочу видеть в результате, ведь вариантов огромное множество и часть из них я не смогу реализовать из-за ограниченных возможностей дисплея.

Не долго думая появилась идея реализовать 2 уровневое меню, которое схематично можно представить так:

1)Общая информация

1.1)Диод1 характеристики

1.2)Диод2 характеристики

Такой тип меню мне кажется всем сразу приходит на ум, он легок в реализации и хорошо расширяем в дальнейшем.

Давайте более подробно продумаем как это меню будет выглядеть на 2 строчном 16 значном lcd дисплее и сколько кнопок нам понадобится для удобной навигации из 5 представленных на lcd shield .

Общая информация будет выглядеть так:

Led1 On/Off 0-255

Led2 On/Off 0-255

Таким образом сразу при взгляде на монитор мы поймем какой светодиод включен и на какую яркость. Теперь нужно реализовать способ выбора настроек, для этого логично использовать все 5 кнопок, вверх, вниз и влево, право, селект. Выбранный элемент будет указываться таким символом ->

Значит будущее меню будет иметь следующий вид:

->Led1 On/Off 0-255     или     Led1 On/Off 0-255

Led2 On/Off 0-255                      ->Led2 On/Off 0-255

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

->Led 1: On/Off       или        Led1: On/Off

Intensity: 0-255                     ->Intensity: 0-255

И уже на этом экране в зависимости от выбранного кнопкой селект параметра мы будем его изменять кнопками вверх и вниз.

Проектирование программы меню

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

Первым делом нам нужно знать какой элемент выбран 1 или 2, для этого мы будем использовать переменную Item типа int (в принципе использование типа int в данном случае избыточное, но мы остановимся на нем),то есть переменная item будет отвечать за выбранный элемент меню

Led1 On/Off 0-255 ltem = 0

Led2 On/Off 0-255 item = 1

Эта переменная будет использоваться на любом экране где в столбике у нас будет более 1 элемента.

Теперь нам нужна переменная, которая будет изменятся если мы перейдем на любой уровень меню отличный от начального, для этого мы будем использовать переменную menuLevel так же типа int.

menuLevel = 0

Led1 On/Off 0-255

Led2 On/Off 0-255

 

menuLevel = 1

->Led 1: On/Off

Intensity: 0-255

 

Так же нам понадобится 2 переменные для того что бы понять в настройках какого светодиода мы находимся для этого создадим 2 переменные типа int под названием led1 и led2. Они будут использоваться для того что бы конкретизировать выбранный светодиод на первом экране.

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

 

Логика работы меню

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

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

При запуске нашей схемы нам нужно увидеть 1 экран меню с первым выбранным элементом, для этого начальные значения переменных menuLevel и item должны быть равны 0.

При нажатии кнопки в низ выбранный элемент меню должен изменится, для этого переменная item должна стать равным 1 (при нажатии кнопки вверх она опять должна стать равной 0).

При нажатии кнопки в право (выборе нужного элемента) переменная menuLevel должна стать равной 1 что скажет нашей программе о том, что нужно показать 2 уровень меню. Но показанное меню должно так же зависеть от переменной item, показать настройки первого или второго светодиода и в зависимости от этого изменить соответствующую переменную led1 или led2 с нуля на 1.

В принципе это и вся логика, теперь пришло время написать код и проверить все ли будет работать так как мы с вами задумали.

Пишем код

Первым делом нам нужно инициализировать дисплей и создать функцию для работы с кнопками, с этим вы должны уже справится сами так как это мы рассматривали в прошлой статье arduino lcd shield по этому я приведу готовый отрезок кода.

Следующим этапом нам нужно инициализировать нужные нам переменные и присвоить им стартовые значения, подготовить дисплей к работе и нарисовать стартовое меню с выбранным первым элементом меню. Переменные должны получить начальные значения только при старте Arduino по этой причине объявим их сразу после секции setup() .

Как мы раньше решили переменная отвечающая за выбранный элемент называется item а переменная отвечающая за уровень меню menuLevel, отсюда следует что нам надо проверить что бы переменная menuLevel была равна нулю в обеих случаях и в зависимости от значения item был выбран 1 или второй элемент.

Наш код будет иметь следующий вид:

Теперь давайте нарисуем второй экран (меню) для каждого возможного элемента, выбранного в первом меню, для этого нам нужно проверить что переменная menuLevel = 1 а так же узнать какой элемент был выбран, это можно сделать проверив чему равна переменная led1 или led2. Наш код будет иметь следующий вид:

Наше меню почти готово, нам осталось его оживить, для этого нужно менять значение переменных в зависимости от того какая кнопка была нажата. Для этого мы будем использовать оператор switch как и в прошлой статье по lcd шильду.

Наш код получит следующий вид:

 

Теперь давайте прошьем Arduino Uno этой прошивкой и проверим как работает навигация.

И как не странно все работает но не так как мы изначально планировали. Мы допустили одну ошибку, которая заключается в том что после перехода на 2 экран значение переменной item остается неизменным. Это приводит к тому что при переходи на любой экран со второго элемента меню курсор так и остается на 2 элементе меню. Давайте исправим это!

Еще 1 проблема
Также не все символы помещаются на экране, но эта проблема уйдет сама, когда мы откажемся от абстрактных On/Off и 0-255 что произойдет чуточку позднее.

Для этого нам нужно при переходе от 1 уровня меню к другому обнулять значение переменной item, для этого нужно изменить функцию switch и привести ее к следующему виду:

Теперь у нас есть полностью рабочее меню которое ни как не взаимодействует со светодиодами и не представляет ни какой информации о том в каком режиме сейчас они находятся. Давайте исправим это! Для этого нам придется опять написать кучу кода и немного изменить уже написанный приступим!

Логика управления светодиодами!

Первым делом нам нужно добавить переменных, которые будут отвечать за состояние (On, Off) каждого светодиода и за их яркость. Переменные мы назовем led1On, led2On (будут отвечать за то включен или нет светодиод) и led1Intens, led2Intens( отвечать за яркость светодиода) и select (которая будет отвечать за вход и выход из режима редактирования), объявим их так же после void setup() {} .

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

Код будет иметь следующий вид:

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

 

Теперь значения на экране меняются и все почти работает, не работают только светодиоды, это легко исправить если схема собрана точно так же как я рассказывал в прошлой статье Arduino управление яркостью светодиодов. Для этого просто в самый конец кода нужно добавить несколько строк. А именно:

В конечном результате полный код нашей программы имеет следующий вид:

И все! Наша прошивка для Arduino работает, включая и выключая светодиоды и регулируя их яркость! Но внимательные заметили, что отзывчивость на нажатие клавиш не всегда моментальная. Это вызвано особенностью нашей программы, а именно использованием оператора delay который мы поставили что бы ограничить скорость обновления картинки на нашем дисплее.

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

Вообще этот код является далеко не самым оптимальным, он был написан для того что бы понять, что такое программирование, и как мы видим это чистая логика (а в школе говорят математика =)), весь код пестрит операторами if и его разновидностями. Так что всегда продумывайте свои прошивки что бы не получить на каком-либо этапе логическую ошибку так как ее сложнее всего найти. В нашем коде всего 200 строк (которые без проблем можно прилично уменьшить, ухудшив читаемость) но даже мне через пару дней будет сложно разобраться какая строка за что отвечает, так что всегда комментируйте свой код! Комментарии вас выручать, поверьте. Если требуются дополнительные комментарии по коду то вы сообщите а я их добавлю.

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

А на сегодня все! Всем удачи в ваших начинаниях.

 

Метки: , , , . Закладка Постоянная ссылка.

Добавить комментарий