Jump to content

Кушать подано!

ARV

465 views

Поскольку кормят нас повара и санитары, решил повысить уровень обслуживания, сделав меню.

То есть, вдохновившись всем известным MicroMenu, сделал свой вариант "библиотечки" дл создания меню в проектах на микроконтроллерах AVR. На видео показаны основные фишки моего варианта:

  1. Скроллинг меню, если на дисплее оно целиком не вмещается. Выделение активного пункта в данном случае сделано "прочеркиванием" двумя линиями, но, естественно, можно сделать, как угодно.
  2. Выполнение команд меню без завершения самого меню (с завершением тоже можно).
  3. Наличие в меню пунктов со значениями параметров. Выделенный параметр сразу может редактироваться в заданных пределах.
  4. Возможность вложенных меню.

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

// главное меню
//	 id	name			parent	prev	next	func|subm	property
MENU_CMD( mm_1,	"BEEP",			NONE,	NONE,	mm_2,	beep);
MENU_PROP(mm_2,	"TEST",			NONE,	mm_1,	mm_3,	NULL,		PROP_U8(u8, NOSTORE, 0, 12));
MENU_PROP(mm_3,	"MOTOR",		NONE,	mm_2,	mm_4,	motor,		PROP_BOOL(motor_state, NOSTORE, sf("STOP"), sf("RUN")));
MENU_SUB( mm_4,	"SUBMENU",		NONE,	mm_3,	mm_5,	sm_1);
MENU_PROP(mm_5,	"TEMPERATURE",		NONE,	mm_4,	mm_6,	NULL,		PROP_I16(vfr, NOSTORE, -20, 20));
MENU_CMD( mm_6,	"LOAD",			NONE,	mm_5,	mm_7,	load);
MENU_CMD( mm_7,	"SAVE & EXIT",		NONE,	mm_6,	NONE,	save);

// субменю
MENU_CMD( sm_1, "STOP DEMO 1",		mm_4,	NONE,	sm_2,	done);
MENU_CMD( sm_2, "STOP DEMO 2",		mm_4,	sm_1,	sm_3,	done);
MENU_SUB( sm_3, "STOP SUB",		mm_4,	sm_2,	NONE,	ssm_1);

// субменю 2
MENU_CMD(ssm_1, "SUB STOP DEMO 1",	sm_3,	NONE,	ssm_2,	done);
MENU_CMD(ssm_2, "SUB STOP DEMO 2",	sm_3,	ssm_1,	ssm_3,	done);
MENU_CMD(ssm_3, "SUB STOP DEMO 3",	sm_3,	ssm_2,	NONE,	done);

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

Реализована поддержка следующих свойств:

  • целое число (со знаком и без оного, 8 и 16 бит), причем число можно выводить в десятичной или шестнадцатеричной форме;
  • булево значение (т.е. логическое) - оно отображаетс парой соответствующих строк текста;
  • выбор одного варианта из нескольких - каждый вариант так же представляется соответствующим текстом.

Относительно просто добавить поддержку и 32-битных чисел... Но надо ли? Вводить их значение при помощи кнопок "навигации" - это удовольствие не из приятных... При желании это можно реализовать по-старинке - написав свою функцию и назначив её нужному пункту меню...

Таким образом, моя система меню сразу позволяет решить следующие задачи, практически всегда присутствующие в проектах на МК с ЖКИ:

  • организовать процесс "настройки" всех параметров при помощи интуитивного меню;
  • сохранять автоматически в EEPROM все свойства, используемые в меню, и загружать их оттуда.

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

Думаю, многие знают, что не всегда просто решить, напрмер, интерактивную регулировку яркости подсветки дисплея. Часто делают так: в меню выбирают пункт, по активации которого выводится редактор яркости (то ли шкала, то ли число), а потом, когда ввод нового значения яркости завершен, работа с меню завершается, и задается новое значение яркости. Так вот, в моей системе яркость может меняться одновременно с изменением соответствующего свойства! На видео вы могли видеть, как включается и выключается "моторчик" - точно так же можно выполнять какую-то функцию при каждом изменении числа. То есть реализован полностью интерактивный способ изменения всех свойств! И прощайте странные цифры, обозначающие включение или отключение каких-то режимов - здравствуйте понятные слова!

Надеюсь, моё меню сможет удоветворить самый изысканный вкус любого гурмана...

  • Like 1


7 Comments


Recommended Comments

MicroMenu неплохой проект. Но вы не поняли его сути. Сразу скажу, для своих нужд я ничего лучшего не нашёл. Плюсы этого проекта. Сведение большой части данных по меню в одно место. Навигация, сами пункты, текст, вспомогательные функции. Минусы. Ожидаемой универсальности, что вы приписываете, нет. Иначе, придётся вводить дополнительные поля, что приводит к расходу flash памяти. И по большому счету ненужный балласт.

Поверьте, я достаточно хорошо разбирался с этим проектом. Притом, в моей реализации из статьи easyelectronics.ru взяты имена. Parent, Child и так далее. Но за основу взят оригинальный проект с AVRFreaks.

Что могу сказать, для разных типов дисплеев все равно придётся делать разные реализации. Символьные, графические, семисегментные. Это разные реализации. Количество кнопок управления соответственно навигация по меню тоже вносит свои коррективы.

Что в итоге остается: MicroMenu это всего лишь завернутый в красивые фантики (макросы) доступ к структурам. И ничего более. Всё остальное, что вы так красиво расписали, все равно придётся делать ручками.

Edited by demiurg1978

Share this comment


Link to comment
4 часа назад, demiurg1978 сказал:

MicroMenu это всего лишь завернутый в красивые фантики (макросы) доступ к структурам

Вот именно. То есть оно не решает никакой практической задачи. А ведь из проекта в проект надо решать именно задачи: изменить значение настроечных переменных, отобразить их значение, считать-сохранить... Так вот: мое "меню", кроме того, что оно предоставляет фантики для доступа к структурам, еще и эти задачи решает. Т.е. сохраняя достоинства MicroMenu, добавляет новые.

4 часа назад, demiurg1978 сказал:

для разных типов дисплеев все равно придётся делать разные реализации

Как и в MicroMenu, у меня "рисование пунктов" - это внешняя функция, реализуемая полльзователем. Хотите - применяйте ЖКИ, хотите - семисегментники, выводите в терминал, да хоть на штифты Брайля - это никак не влияет на заложенные функции.

4 часа назад, demiurg1978 сказал:

Всё остальное, что вы так красиво расписали, все равно придётся делать ручками.

В том и фишка, что не придется. Если, конечно, вы согласны применять готовые решения.

Я немного поясню, что именно привносит моё решение в жизнь программиста.

Вот у вас есть параметр, отвечающий за яркость подсветки дисплея. Вы заводите переменную uint8_t bright - так ведь? Так же вы должны выделить место в EEPROM для сохранения ее значения между сеансами работы EEMEM uint8_t ebright - так? Когда вы соберетесь предоставить пользователю возможность её изменить, вы должны применить функцию редактирования числа uint8_t, функцию отображения числа uint8_t, при редактировании вы обязаны контролировать пределы изменения значения, т.е. у вас должны быть и константы bright_min и bright_max - ну так ведь? Т.е. от этого вы все равно не избавитесь никак.

Так вот, моё решение просто объединяет все вышеперечисленное (переменную, ячейку EEPROM, функцию редактирования с контролем границ, сами эти границы и функцию вывода числа) в одну структуру PROP_U8, которую вы просто укажете в нужном пункте меню MENU_PROP - и всё!

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

/**  \ingroup MACRO
 * Определение свойства: число 8 бит без знака \n
 * \b _var имя переменной \n
 * \b _eadr адрес переменной в \b EEPROM для сохранения значения свойства \n
 * \b _min минимально допустимое значение \n
 * \b _max максимально допустимое значение
 */
#define PROP_U8(_var, _eadr, _min, _max) 

Смотрите выше на описание макроса - что из его "параметров" у вас не применяется и так? Все это вы так или иначе создаете и используете в своем коде, я не требую ничего сверх необходимого, кроме 7 байт flash под эту структуру.

Накладных расходов, конечно, чуть больше, но все они во flash, расходы ОЗУ минимальны. Зато комфорт в применении, заплатить за него несколькими байтами памяти - не такая уж великая цена, не находите? ;) 

Share this comment


Link to comment

Я вам уже писал. Кроссплатформенность. Если вы дадите решение, которое будет работать на всех компиляторах с минимальными переделками, ещё лучше, проект сделанный в разных компиляторах, как делают некоторые авторы статей, честь вам и хвала. Если же будет решение для единственного компилятора, тогда практический смысл имеет только для вас.

Лично мне пришлось помучиться, чтобы перевести проект micromenu с easyelectronics.ru на IAR. Тем более что на тот момент у меня были сложности с указателями в си. 

Edited by demiurg1978

Share this comment


Link to comment

@demiurg1978 я тоже вам писал: я не намерен скачивать, устанавливать и тестировать все возможные версии компиляторов, чтобы убедиться в кроссплатформенности или обеспечить её. Хотите - проверяйте сами, возможно, вместе нам удастся эту кроссплатформенность обеспечить. Мне кажется, что мой код вполне кроссплатформенный, но это не точно :)

Кстати, пока суть да дело, сделал я еще одно видео:

 

Здесь показано, как FlexMenu работает с терминальной программой putty. Пришлось переписать единственную функцию paint_menu и поменять пару макросов в файле конфигурации, чтобы сделать строки шире 16 символов. Черное окно - это как раз окно putty, остальное, как и прошлый раз, протеус делает.

Share this comment


Link to comment

Засуньте сейчас свою исключительность ммм... куда-нибудь. Вы сами писали, а как же начинающие. И представляете, они не всегда пишут свои проекты в вашем компиляторе. IAR, AVR-Studio Toolchain, WinAVR. Этого достаточно. Не согласны? Варитесь сами в своем компиляторе. Я знаю что грубо. Написал статью, держи свою гранату. А теперь отключим эмоции, включим осознанность. Я на свои работы получил карт бланш. У Татарчевского, у редакции. Ты получил карт бланш на статью в easyelectronics? Замахнулся, соответствуй... Все по взрослому.

Edited by demiurg1978

Share this comment


Link to comment

Сделал документацию к своему проекту: FlexMenu.chm 

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

Share this comment


Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Add a comment...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...