Проблема с созданием меню на дисплее.

Armata
Offline
Зарегистрирован: 04.03.2018

Здравствуйте друзья! И снова я к вам за подсказкой:
Прикупил себе дисплейчик ST7920 128x64 и решил сделать менюшку для управления шаговиком пока он в пути.Воспользовался библиотекой U8glib и её примером создания меню,немного пределав его под себя.А застрял на многоуговневости. Нужно создать в меню "Setings" подменю с пунктами "Zero point" и "Calibration",но почему - то не удается это осуществить.При входе в меню  "Setings" ничего нету,пустой экран.

#include "U8glib.h"
U8GLIB_ST7920_128X64_4X u8g(52, 51, 53);
#include <Keypad.h>

const byte ROWS = 4; //Количество строк клавиатуры
const byte COLS = 4; //Количество колонок клавиатуры
//Определяем символы соответствия клавиатуры
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','^'},
  {'4','5','6','V'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {38, 24, 26, 30}; //Подключам строки клавиатуры на пинах 8 1 2 4
byte colPins[COLS] = {28, 32, 34, 36}; //Подключам колонки клавиатуры на пинах 3 5 6 7
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
char customKey = customKeypad.getKey();

int KEY;
int Length = 0;
int data=0;

#define MENU_ITEMS 3
const char *menu_strings[MENU_ITEMS]  = { "MANUAL", "AUTO", "SETINGS",};
#define MENU_SEC_ITEMS 3
const char *menu2_strings[MENU_SEC_ITEMS] = {"ZERO POINT", "CALIBRATION"};

uint8_t menu_current = 0;
uint8_t menu_redraw_required = 0;
uint8_t menu_sec_current = 0;
uint8_t menu_sec_redraw_required = 0;



void drawMenu(void) {
  uint8_t i, h;
  u8g_uint_t w, d;

  u8g.setFont(u8g_font_timB18);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();
  
  h = u8g.getFontAscent()-u8g.getFontDescent();
  w = u8g.getWidth();
  for( i = 0; i < MENU_ITEMS; i++ ) {
    d = (w-u8g.getStrWidth(menu_strings[i]))/2;
    u8g.setDefaultForegroundColor();
    if ( i == menu_current ) {
      u8g.drawBox(0, i*h-1, w, h-1);
      u8g.setDefaultBackgroundColor();
    }
    u8g.drawStr(d, i*h, menu_strings[i]);
  }
}

void DrawMenu(void){
uint8_t i, h;
  u8g_uint_t w, d;

  u8g.setFont(u8g_font_timB18);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();
  
  h = u8g.getFontAscent()-u8g.getFontDescent();
  w = u8g.getWidth();
  for( i = 3; i < MENU_SEC_ITEMS; i++ ) {
    d = (w-u8g.getStrWidth(menu2_strings[i]))/2;
    u8g.setDefaultForegroundColor();
    if ( i == menu_sec_current ) {
      u8g.drawBox(0, i*h-1, w, h-1);
      u8g.setDefaultBackgroundColor();
    }
    u8g.drawStr(d, i*h, menu_strings[i]);
  }
}

void setup() {
  menu_redraw_required = 1;     // force initial redraw

  Serial.begin(115200);
}


void loop() {  

 char customKey = customKeypad.getKey();
       if (customKey){
       if(customKey >= '0' && customKey <= '9'){  //если нажата кнопка от 0-9        
          data = data*10+customKey-48;            //передвигаем каретку в право и присваеваем data это значение
          }
     if(customKey == 'D' || customKey == 'C'){
     Length = data;    
 }
    Serial.print("Input = ");
    Serial.println(data);
    Serial.print("OUT = ");
    Serial.println(Length); 
}


  if (customKey == '^'){
    if ( menu_current == 0 )
        menu_current = MENU_ITEMS;
      menu_current--;
      menu_redraw_required = 1;} 
      
  if (customKey == 'V'){
        menu_current++;
      if ( menu_current >= MENU_ITEMS )
        menu_current = 0;
      menu_redraw_required = 1;}
////////////////////////////////////////////

      
// Пункт меню Manual
  if(menu_current == 0){
  if (customKey == 'C' || customKey == 'D' ){
    u8g.firstPage();
    do  {
      u8g.setFont(u8g_font_helvB10);
     u8g.setPrintPos( 13, 12);
     u8g.print("MANUAL SIZE");
     u8g.drawLine(0, 13, 127, 13);
     u8g.setFont(u8g_font_fub30);
     u8g.setPrintPos( 18, 55);
     u8g.print(data);  }
     while( u8g.nextPage() );
    }
  }
  
// Пункт меню Auto
  if(menu_current == 1){
  if (customKey == 'C' || customKey == 'D' ){
    u8g.firstPage();
    do  {
      u8g.setFont(u8g_font_8x13);
     u8g.setPrintPos( 3, 10);
     u8g.print("No.SIZE No.SIZE");
     u8g.drawLine(63, 0, 63, 63);
     u8g.drawLine(0, 12, 127, 12);
     u8g.setFont(u8g_font_timB14);
//Первая колонка
     u8g.setPrintPos( 2, 29);
     u8g.print("99.3000");
     u8g.setPrintPos( 2, 45);
     u8g.print("99.3000");
     u8g.setPrintPos( 2, 61);
     u8g.print("99.3000");
//Вторая колонка
     u8g.setPrintPos( 66, 29);
     u8g.print("99.3000");
     u8g.setPrintPos( 66, 45);
     u8g.print("99.3000");
     u8g.setPrintPos( 66, 61);
     u8g.print("99.3000");}
     
     while( u8g.nextPage() );
    }
  }
// Пункт меню Setings  
  if(menu_current == 2){
  if (customKey == 'C' || customKey == 'D' ){
    menu_sec_redraw_required = 1;
    u8g.firstPage();
    do  {
    DrawMenu(); 
      }
     while( u8g.nextPage() );
    }
  }
    


  if (  menu_redraw_required != 0 ) {
    u8g.firstPage();
    do  {
      drawMenu();
    } while( u8g.nextPage() );
    menu_redraw_required = 0;
  }
   if (  menu_sec_redraw_required != 0 ) {
    u8g.firstPage();
    do  {
      DrawMenu();
    } while( u8g.nextPage() );
    menu_sec_redraw_required = 0;
  }
}

И ещё одна проблемма,в пункте "Manual" я ввожу данные,но они начинают отображатся только тогда когда нажму на "C" либо "D" а нужно чтобы при вводе они одновременно отображались на экран и после нажатия на "C" либо "D" через 5 секунд обнулились.
Я не гуру,пока учусь.Пожалуйста подскажите что сделал не так.

Armata
Offline
Зарегистрирован: 04.03.2018

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

fogary
Offline
Зарегистрирован: 05.03.2016
void drawMenu(void){
...
}

void DrawMenu(void){
...
}

Давать такие малоразличимые имена, плохая практика.

И void, в скобках, писать не нужно.

Armata
Offline
Зарегистрирован: 04.03.2018

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

u8g.drawStr(d, i*h, menu2_strings[i]);

было
 

u8g.drawStr(d, i*h, menu_strings[i]);

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

#include "U8glib.h"
U8GLIB_ST7920_128X64_4X u8g(52, 51, 53);
#include <Keypad.h>

const byte ROWS = 4; //Количество строк клавиатуры
const byte COLS = 4; //Количество колонок клавиатуры
//Определяем символы соответствия клавиатуры
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','^'},
  {'4','5','6','V'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {38, 24, 26, 30}; //Подключам строки клавиатуры на пинах 8 1 2 4
byte colPins[COLS] = {28, 32, 34, 36}; //Подключам колонки клавиатуры на пинах 3 5 6 7
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
char customKey = customKeypad.getKey();

int KEY;
int Length = 0;
int data=0;

#define MENU_ITEMS 3
const char *menu_strings[MENU_ITEMS]  = { "MANUAL", "AUTO", "SETINGS",};
#define MENU_SEC_ITEMS 2
const char *menu2_strings[MENU_SEC_ITEMS] = {"ZERO POINT", "CALIBRATION"};

uint8_t menu_current = 0;
uint8_t menu_redraw_required = 0;
uint8_t menu_sec_current = 0;
uint8_t menu_sec_redraw_required = 0;



void drawMenu(void) {
  uint8_t i, h;
  u8g_uint_t w, d;

  u8g.setFont(u8g_font_timB18);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();
  
  h = u8g.getFontAscent()-u8g.getFontDescent();
  w = u8g.getWidth();
  for( i = 0; i < MENU_ITEMS; i++ ) {
    d = (w-u8g.getStrWidth(menu_strings[i]))/2;
    u8g.setDefaultForegroundColor();
    if ( i == menu_current ) {
      u8g.drawBox(0, i*h-1, w, h-1);
      u8g.setDefaultBackgroundColor();
    }
    u8g.drawStr(d, i*h, menu_strings[i]);
  }
}

void Second_Menu(void){
uint8_t i, h;
  u8g_uint_t w, d;

  u8g.setFont(u8g_font_ncenB10);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();
  
  h = u8g.getFontAscent()-u8g.getFontDescent();
  w = u8g.getWidth();
  for( i = 0; i < MENU_SEC_ITEMS; i++ ) {
    d = (w-u8g.getStrWidth(menu2_strings[i]))/2;
    u8g.setDefaultForegroundColor();
    if ( i == menu_sec_current ) {
      u8g.drawBox(0, i*h-1, w, h);
      u8g.setDefaultBackgroundColor();
    }
    u8g.drawStr(d, i*h, menu2_strings[i]);
  }
}

void setup() {
  menu_redraw_required = 1;     // force initial redraw
  u8g.setRot180();
  Serial.begin(115200);
}


void loop() {  

 char customKey = customKeypad.getKey();
       if (customKey){
       if(customKey >= '0' && customKey <= '9'){  //если нажата кнопка от 0-9        
          data = data*10+customKey-48;            //передвигаем каретку в право и присваеваем data это значение
          }
     if(customKey == 'D' || customKey == 'C'){
     Length = data;    
 }
    Serial.print("Input = ");
    Serial.println(data);
    Serial.print("OUT = ");
    Serial.println(Length); 
}

//Кнопка вверх
  if (customKey == '^'){
    if ( menu_current == 0 )
        menu_current = MENU_ITEMS;
      menu_current--;
      menu_redraw_required = 1;} 
//Кнопка вниз     
  if (customKey == 'V'){
        menu_current++;
      if ( menu_current >= MENU_ITEMS )
        menu_current = 0;
      menu_redraw_required = 1;}
//Кнопка возврат "*"
  if (customKey == '*'){
        menu_current = 0;
      menu_redraw_required = 1;}
////////////////////////////////////////////
  
      
// Пункт меню Manual
  if(menu_current == 0){
  if (customKey == 'C' || customKey == 'D' ){
    u8g.firstPage();
    do  {
      u8g.setFont(u8g_font_helvB10);
     u8g.setPrintPos( 13, 12);
     u8g.print("MANUAL SIZE");
     u8g.drawLine(0, 13, 127, 13);
     u8g.setFont(u8g_font_fub30);
     u8g.setPrintPos( 18, 55);
     u8g.print(Length);
     if(customKey == 'D' || customKey == 'C'){
     Length = data;
     data = 0;
          }
     }
     while( u8g.nextPage() );
    }
  }
  
// Пункт меню Auto
  if(menu_current == 1){
  if (customKey == 'C' || customKey == 'D' ){
    u8g.firstPage();
    do  {
      u8g.setFont(u8g_font_8x13);
     u8g.setPrintPos( 3, 10);
     u8g.print("No.SIZE No.SIZE");
     u8g.drawLine(63, 0, 63, 63);
     u8g.drawLine(0, 12, 127, 12);
     u8g.setFont(u8g_font_timB14);
//Первая колонка
     u8g.setPrintPos( 2, 29);
     u8g.print("99.3000");
     u8g.setPrintPos( 2, 45);
     u8g.print("99.3000");
     u8g.setPrintPos( 2, 61);
     u8g.print("99.3000");
//Вторая колонка
     u8g.setPrintPos( 66, 29);
     u8g.print("99.3000");
     u8g.setPrintPos( 66, 45);
     u8g.print("99.3000");
     u8g.setPrintPos( 66, 61);
     u8g.print("99.3000");}
     
     while( u8g.nextPage() );
    }
  }
// Пункт меню Setings  
  if(menu_current == 2){
  if (customKey == 'C' || customKey == 'D' ){
    menu_sec_redraw_required = 1;
    u8g.firstPage();
    do  {
    Second_Menu(); 
      }
     while( u8g.nextPage() );
    }
  }

  if (  menu_redraw_required != 0 ) {
    u8g.firstPage();
    do  {
      drawMenu();
    } while( u8g.nextPage() );
    menu_redraw_required = 0;
  }
   if (  menu_sec_redraw_required != 0 ) {
    u8g.firstPage();
    do  {
      Second_Menu();
    } while( u8g.nextPage() );
    menu_sec_redraw_required = 0;
  }
}

Ну и пока не разобрался с отображение данных во время ввода в пункте  MANUAL.

fogary
Offline
Зарегистрирован: 05.03.2016

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

Вот тут:

// Пункт меню Manual
  if(menu_current == 0){
  if (customKey == 'C' || customKey == 'D' ){
    u8g.firstPage();
    do  {
     ...
     if(customKey == 'D' || customKey == 'C'){
     Length = data;
     data = 0;
          }
     }
     while( u8g.nextPage() );
    }
  }

Зачем второй раз проверять, что код клавиши 'D' или 'C'? Если проверка выше как раз обеспечивает это условие. И в самом начале loop() уже выполнялось присвоение "Length = data;", второй-то раз зачем?

Не думали перейти на использование конструкции switch-case?

Armata
Offline
Зарегистрирован: 04.03.2018

Спасобо за подсказку,убрал лишнюю проверку.
Не совсем понял что вs имели введу
"Странно, что Вы проверяете состояние customKey только при вводе чисел." .

Про switch-case пока не думал,да и облегчит ли это задачу?

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Armata пишет:
Про switch-case пока не думал,да и облегчит ли это задачу?
Ну это от Вас зависит. Я бы предложил еще на автомате организовать меню, но для Вас это за гранью понимания.

Armata
Offline
Зарегистрирован: 04.03.2018

Пока Вы правы,это за гранью моего понимания.
Но если у Вас есть настолько большие знания то може поможете в решении проблеммы?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

fogary пишет:

И void, в скобках, писать не нужно.

Что, Клапа успел и это запретить?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Armata пишет:

Пока Вы правы,это за гранью моего понимания.
Но если у Вас есть настолько большие знания то може поможете в решении проблеммы?

Нет базовых знаний. А без них это долго и бесполезно. #44  

Armata
Offline
Зарегистрирован: 04.03.2018

Понял,я по сути и сразу написал что не знаток,по этому и прошу помощи чтобы понять и разобраться.Спасибо и на этом.