Создание меню Arduino Uno, дисплей: OLED 128*64

alekseev2016
Offline
Зарегистрирован: 04.01.2017

Приветствую! Уже очень долго мучаюсь и не могу понять азы создания меню на ардуино. Получилось создать меню в котором два значения и два подменю. С помощью него включал/выключал светодиоды и управлял их яркостью. Моете написать скетч меню, где больше значений (от 3) и больше трёх подменю. Буду очень вам за это благодарен. Управляю я меню с помощью самодельного Key Pad шилда, который подключён к аналоговому пину ардуино. Заранее спасибо)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ну, если азы, могу привести описание класса меню, ориентированного на 2-строчный дисплей. В верхней строке всегда название текущего пункта меню, в нижней - название или номер подпункта. Подпункт может либо быть числом в диапазоне от 0 до 127, либо иметь собственное имя. Максимальное количество пунктов меню 128, не считая подпункты-числа (т.е. 128 именованных пункта). В рамках этих ограничений количество подпунктов, а также глубина вложенности меню не ограничена. Подпункты меню могут быть либо только именнованными, либо только числами, совмещение не допускается. 

Да, в строках 28-29: 4 - это максимальная глубина меню. Нужно изменить эти значения в соответствии с собственными пристрастиями.

struct MenuItem {
  int8_t  next;      //(indx) если >0 - индекс в массиве следующего элемента одного уровня, если <= 0 - индекс родительского элемента со знаком "-"
  int8_t  first;     //(indx) если >0 - индекс в массиве первого дочернего элемента, если <= 0 - индекс родительского элемента со знаком "-"
  uint8_t numChild;  // 0-128 - количество дочерних листьев, элементов нет. 129-255 - количество элементов num-128, листьев нет, т.к. дочерние возможны только одного типа.
  uint8_t str;       // индекс строки, связанной с элементом, в массиве строк
};

class tMenu {
public :
  tMenu();    
  int8_t createItem(int8_t parent, uint8_t numLeafs, uint8_t str); // создание пункта, возвращает номер свежесозданного, отриц. - если неудачно, type=0 - пункт, type=1 - лист
  bool includeItem(int8_t parent, int8_t child); // включение одного пункта в другой
  bool enterItem(); // вход в пункт меню (сделать текущий currChild активным, снять активность со старого)
  void leaveItem(); // покинуть текущий, сделать активным тот, что был активным до него
  int8_t getLast(uint8_t parent); // нахождение последнего дочернего элемента
  int8_t getChildByN(uint8_t parent, uint8_t n); // нахождение дочернего элемента по его порядковому номеру (по показаниям валкодера)
  void changeChild(int8_t n); // изменить currChild на указанную величину
  int16_t getCurrChildStr(); // выдача строки, соответствующей текущему дочернему объекту
  int16_t getCurrActiveStr(); // выдача строки, соответствующей текущему активному объекту
  void printMenu(); // последовательно выводит массив элементов
  void sendCommand(); // посылает команды листьев
private :
  MenuItem MI[MaxMenu];
  uint8_t numMenu; // количество реально созданных пунктов меню
  int8_t currActive; //(indx) текущий активный пункт меню
  int8_t currLevel; // текущий уровень вложенности
  int8_t currChild; //(nmb) текущий дочерний элемент (номер по порядку, а не индекс в массиве) текущего активного - вычисляется по валкодеру.
  int8_t levelActive[4]; //(indx) активные пункты меню на каждом из уровней вложенности: 
  int8_t levelChild[4];  //(nmb) текущие номера дочерних пунктов на каждом из уровней вложенности: 
  uint8_t currNumChild; // количество детей (вне зависимости от типа) у текущего элемента
};

 

alekseev2016
Offline
Зарегистрирован: 04.01.2017

Можно по проще что то?