ARDUINO Помогите с реализацией меню на экран, с библиотекой u8glib с энкодером

Andrey_uf

✩✩✩✩✩✩✩
27 Ноя 2022
3
0
Запутался с кодами, нашёл много примеров, по изучав так и не вышло как должно быть то ошибки по скетчу, то вообще ничего не выводит, энкодер хотелось ещё поставить чтоб кнопок не было, но это потом, пока хочется вывести меню на экран, psi подключение, экран 128х64 st7920. Меню с одним подуровнем и с изменением одной переменной и вкл/выкл, сам самоучка, смотрел уроки. Но ведать что то я непонял
 

viktor1703

★★★✩✩✩✩
9 Дек 2021
611
145
Так, тебе нужно, что бы кто-то написал и выложил готовый код? Тогда в раздел "Ищу разработчика". Если нужна помощь с твоим кодом, тогда выложи его здесь.
 

Andrey_uf

✩✩✩✩✩✩✩
27 Ноя 2022
3
0
Хочу сам научится, но надо чтоб кто то направлял

C++:
#include <U8glib.h>

//указание пинов для использования дисплея, не обязательно брать пины аппаратного SPI
U8GLIB_ST7920_128X64_1X u8g(13, 11, 12);

//Переменные отвечающие за меню
//Массив с названиями меню
char* MenuNames [50];

//Тип элемента меню
//0-родительское меню
//1-целое число
//2-временной интервал (h:m:s, целое число но отображается как время) ? заменим на изменение переменой
//3-Вкл/Выкл (целое число, но отображается как On/Off)
//4-Расстояние (cm, целое число, но отображается как 0.хх метров)  ? этого у нас не будет
int MenuTypeCode[50];

//Значение элемента меню
int MenuValue[50];

//Текущая позиция в меню, вложенность не важна т.к. меню представляет из себя список с ссылками на родительские
//и дочерние пункты
int MenuNowPos=0;

//Режим редактирования (0-нет, просто выделен определенный параметр или пункт меню, 1-редактируем значение параметра)
int MenuEdit=0;

//номер элемента меню который является для данного родительским
//0-нет родительского элемента
int MenuParent[50];

//номер элемента меню который является для данного дочерним
//0-нет дочернего элемента
int MenuChild[50];

//Номер элемента дочернего меню который является первым
int MenuChildFirst[50];

//номер элемента дочернего меню который является последним
int MenuChildEnd[50];

//позиция меню в которой находится выделенный пункт на экране (например на экране отображается 3 пункта при этом выделен второй)
int MenuDrawPos=0;

//максимальное количество отображаемых на экране пунктов
int MenuDrawCount=5;

//переменные для таймера перерисовки
//время последней перерисовки
long DrawTime1=0;
//текущее время
long DrawTime2=0;
//интервал для перерисовки экрана
long DrawTimeInterval=200000;

void MenuSetup()
{
//Настройка меню
//задаем начальное положение в меню
MenuNowPos=1;
//Массив с названиями меню, индексами родительских элементов меню, начальными и конечными индексами дочерних элементов меню
//также задаем начальные значения параметров элементов и их тип
MenuNames[0]="menu";
MenuTypeCode[0]=0;
MenuValue[0]=0;
MenuParent[0]=0;
MenuChildFirst[0]=1;
MenuChildEnd[0]=3;

MenuNames[1]="temp";
MenuTypeCode[1]=1;
MenuValue[1]=0;
MenuParent[1]=0;
MenuChildFirst[1]=0;
MenuChildEnd[1]=0;// тут мы еще подумаем какое значение ставить!

MenuNames[2]="heat";
MenuTypeCode[2]=1;
MenuValue[2]=0;
MenuParent[2]=0;
MenuChildFirst[2]=0;
MenuChildEnd[2]=0;

MenuNames[3]="motor";
MenuTypeCode[3]=1;
MenuValue[3]=0;
MenuParent[3]=0;
MenuChildFirst[3]=0;
MenuChildEnd[3]=0;  // тут мы еще подумаем какое значение ставить!

MenuNames[4]; // значение переменой стврт/ стоп
MenuTypeCode[4]=2;
MenuValue[4]=0;
MenuParent[4]=0;
MenuChildFirst[4]=0;
MenuChildEnd[4]=0;

MenuNames[5]="T=";
MenuTypeCode[5]="t=",1;
MenuValue[5]=0;
MenuParent[5]=1;
MenuChildFirst[5]=0;
MenuChildEnd[5]=0;

MenuNames[6]="V=";
MenuTypeCode[6]=1;
MenuValue[6]=0;
MenuParent[6]=2;
MenuChildFirst[6]=0;
MenuChildEnd[6]=0;
}

void DrawMenu()
{
u8g.setFont(u8g_font_fixed_v0); 
//вывод названия родительского меню вверху экрана
u8g.setPrintPos(5, 9);
u8g.print(MenuNames[MenuParent[MenuNowPos-MenuDrawPos]]);
u8g.drawLine( 0, 10, 123,10);
//переменная для вывода пунктов меню на экран
int DrawI=0;
//цикл для вывода пунктов меню на экран
for(DrawI=0; DrawI<MenuDrawCount;DrawI++) 
  {
    u8g.setPrintPos(5, 21+10*DrawI);
    if ((MenuChildFirst[MenuParent[MenuNowPos]]<=(MenuNowPos-MenuDrawPos+DrawI)) and
      (MenuChildEnd[MenuParent[MenuNowPos]]>=(MenuNowPos-MenuDrawPos+DrawI)))
      {
        u8g.print(MenuNames[MenuNowPos-MenuDrawPos+DrawI]);

         u8g.setPrintPos(80, 21+10*DrawI);
        //Если целое число
        if (MenuTypeCode[MenuNowPos-MenuDrawPos+DrawI]==1)
          {
            
            u8g.print(MenuValue[MenuNowPos-MenuDrawPos+DrawI]); 
          }

          //Если пункт меню бинарный
        if (MenuTypeCode[MenuNowPos-MenuDrawPos+DrawI]==2)
          {
            if (MenuValue[MenuNowPos-MenuDrawPos+DrawI]==0)
            {u8g.print("Off");}
              else {u8g.print("On");} 
          }
      }
  }
   //если параметр сейчас не редактируется то отображение рамки вокруг выделенного пункта меню
  if (MenuEdit==0)
    {
    u8g.drawLine( 3, 12+10*MenuDrawPos, 70, 12+10*MenuDrawPos);
    u8g.drawLine(70, 12+10*MenuDrawPos, 70,22+10*MenuDrawPos);
    u8g.drawLine( 3,22+10*MenuDrawPos, 70,22+10*MenuDrawPos);
    u8g.drawLine( 3,  22+10*MenuDrawPos, 3,12+10*MenuDrawPos);
    }
    //если параметр сейчас редактируется то отображение рамки вокруг значения параметра
  if (MenuEdit==1)
    {
      u8g.drawLine( 75, 12+10*MenuDrawPos, 122, 12+10*MenuDrawPos);
      u8g.drawLine(122, 12+10*MenuDrawPos, 122,22+10*MenuDrawPos);
      u8g.drawLine( 75,22+10*MenuDrawPos, 122,22+10*MenuDrawPos);
      u8g.drawLine( 75,  22+10*MenuDrawPos, 75,12+10*MenuDrawPos);
    }
}


/*void Draw(){
  u8g.firstPage();   
  do
    {
      //прорисовка статуса калибровки
      DrawMenu();
    } while( u8g.nextPage() );
}*/

void setup() {
  //настройка порта для клавиатуры
  //pinMode(KeyButton1Pin, INPUT);
 
  //настройка дисплея
  u8g.setHardwareBackup(u8g_backup_avr_spi);
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);       
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);       
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }

//формирование меню
MenuSetup();




//при завершении редактирования пункта меню происходит обновление настроек
/*void UpdateSettings()
{
  //здесь происходит обновление настроек
  //допустим мы имеем программу которая мигает лампочкой с частотой speed
  //допустим этот параметр speed задается в элементе с индексом 4 тогда нам надо написать такой код:
  /*if (MenuNowPos==4) {
      Speed=MenuValue[MenuNowPos]
      }
  */
}
          
void loop() {
 
  u8g.firstPage();   
  do
    {
      //прорисовка статуса калибровки
      DrawMenu();
    } while( u8g.nextPage() );

}

   //проверка таймера для обработки графики, аналогично с обработкой клавиатуры
  //обновление графики происходит не чаще заданного интервала DrawTimeInterval
  /*DrawTime2=micros();
  if ((DrawTime2-DrawTime1)>DrawTimeInterval)
    {
      DrawTime1=DrawTime2;
    
    }*/
@Andrey_uf,собственно вот, не могу правильно собрать, хочу чтоб получилось, имя напротив имени значение или переменная и кнопка старт/стоп менялась, но ведать не дано пока. подтолкните пожалуйста, объясните что щас и куда
 
Изменено:

n0tamused

✩✩✩✩✩✩✩
31 Окт 2022
5
1
Пока не понимаю какая у меню структура.
Но если подуровень всего один - можно сделать на свичах. Будет топорно, но работать будет. Сам подобное сейчас ваяю.

А по-хорошему - нужно раскурить MicroMenu.
 
  • Лойс +1
Реакции: Andrey_uf

Andrey_uf

✩✩✩✩✩✩✩
27 Ноя 2022
3
0
@Andrey_uf,ещё думал если я буду значение менять. То как его в переменной записать. Полностью имя массива?

@n0tamused,со switch можно попробовать, может так даже лучше будет, я тут посидел подумал, мне всего то надо крутить 2 переменные видить температуру действующую и ту которую выставлю, и скорость мотора, ну и сам старт/стоп. По идее даже подменю не надо.