Проблема с меню настроек

trikom
Offline
Зарегистрирован: 15.08.2022

Новичок, первая неделя. Проект по просьбе друга. Инкубатор для рептилий.

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

Помогите с определением проблемы и возможно советами по оптимизации. Целевая платформа Nano.



#include "U8glib.h"
#include <EEPROM.h>

U8GLIB_ST7920_128X64_4X u8g(10);

#define KEY_NONE 0
#define KEY_PREV 1
#define KEY_NEXT 2
#define KEY_SELECT 3

uint8_t uiKeyPrev = 8;
uint8_t uiKeyNext = 9;
uint8_t uiKeySelect = 12;

uint8_t uiKeyCodeFirst = KEY_NONE;
uint8_t uiKeyCodeSecond = KEY_NONE;
uint8_t uiKeyCode = KEY_NONE;

int dInk = 0;
int egg = 0;
int alarmTemp = 0;
int fanTemp = 0;

boolean needSave;
boolean menu;

void uiSetup(void) {
  // configure input keys

  pinMode(uiKeyPrev, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyNext, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeySelect, INPUT_PULLUP);           // set pin to input with pullup
}

void uiStep(void) {
  uiKeyCodeSecond = uiKeyCodeFirst;
  if ( digitalRead(uiKeyPrev) == LOW )
    uiKeyCodeFirst = KEY_PREV;
  else if ( digitalRead(uiKeyNext) == LOW )
    uiKeyCodeFirst = KEY_NEXT;
  else if ( digitalRead(uiKeySelect) == LOW )
    uiKeyCodeFirst = KEY_SELECT;
  else
    uiKeyCodeFirst = KEY_NONE;

  if ( uiKeyCodeSecond == uiKeyCodeFirst )
    uiKeyCode = uiKeyCodeFirst;
  else
    uiKeyCode = KEY_NONE;
}


#define MENU_ITEMS 5
const char *menu_strings[MENU_ITEMS] = {"SETTINGS", "DAY INK", "EGG SETUP", "ALARM D.TEMP", "FAN D.TEMP" };
const int menu_ee[MENU_ITEMS] = {0, 100, 110, 106, 108 };
int menu_value[MENU_ITEMS];

uint8_t menu_current = 0;
uint8_t menu_redraw_required = 0;
uint8_t last_key_code = KEY_NONE;


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

  u8g.setFont(u8g_font_6x13);
  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);
      u8g.setDefaultBackgroundColor();
    }
    u8g.drawStr(5, i * h, menu_strings[i]);
    u8g.setPrintPos(105, i * h);
    u8g.print(menu_value[i]);
  }
}

void updateMenu(void) {
  if ( uiKeyCode != KEY_NONE && last_key_code == uiKeyCode ) {
    return;
  }
  last_key_code = uiKeyCode;

  switch ( uiKeyCode ) {
    case KEY_SELECT:
       menu_current++;
      
      if ( menu_current >= MENU_ITEMS ) {
        menu_redraw_required = 0;
        menu_current = 0;
        menu = 0;
        break;
      }
      if ( needSave == 1 ) {
        //Serial.println(menu_ee[menu_current - 1]);
        //Serial.println(menu_value[menu_current - 1]);
        EEPROM_int_write(menu_ee[menu_current - 1], menu_value[menu_current - 1]);
        needSave = 0;
      }
      menu = 1;
      menu_redraw_required = 1;
      break;
    case KEY_NEXT:
      //if ( menu_current == 0 )
      //  menu_current = MENU_ITEMS;
      menu_value[menu_current]++;
      menu_redraw_required = 1;
      needSave = 1;
      break;
    case KEY_PREV:
      //if ( menu_current == 0 )
      //  menu_current = MENU_ITEMS;
      menu_value[menu_current]--;
      menu_redraw_required = 1;
      needSave = 1;
      break;
  }
  Serial.print("menu_current=");
  Serial.println(menu_current);
}

void readSet() {
  menu_value[1]     = EEPROM_int_read(100);
  menu_value[2]     = EEPROM_int_read(110);
  menu_value[3]     = EEPROM_int_read(106);
  menu_value[4]     = EEPROM_int_read(108);

  //if (dInk > 36 || dInk < 0) {
  //  dInk = 0; //
}

void draw(void) {
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 07, 18, "Incubator 0.1");
  u8g.drawStr( 07, 58, "with Arduino");
}

void setup() {

  Serial.begin(115200);
  readSet();

  menu = 0;

  //u8g.firstPage();
 // do {
  //  draw();
 // } while ( u8g.nextPage() );

  //menu_value[MENU_ITEMS] = { dInk, egg, alarmTemp, fanTemp };
  uiSetup();
  // setup key detection and debounce algorithm
  menu_redraw_required = 0;     // force initial redraw
}

void loop() {
  Serial.println("loop");
  uiStep();                                     // check for key press

  //u8g.firstPage();
  //do {
  //  draw();
  //} while ( u8g.nextPage() );

  if (  menu == 0 ) {
    u8g.firstPage();
    do  {
      draw();
      Serial.println("draw");
    } while ( u8g.nextPage() );
    //menu_redraw_required = 0;
  }
  else {
    u8g.firstPage();
    do  {
      drawMenu();
    } while ( u8g.nextPage() );
    menu_redraw_required = 1;
  }
  Serial.print("menu=");
  Serial.println(menu);
  Serial.print("menu_redraw_required=");
  Serial.println(menu_redraw_required);

  updateMenu();                            // update menu bar
  delay(100);
}

int EEPROM_int_read(int addr) {
  byte raw[2];
  for (byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr + i);
  int &num = (int&)raw;
  return num;
}

void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for (byte i = 0; i < 2; i++) EEPROM.write(addr + i, raw[i]);
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Строка #108 всегда обращает menu в 1, обесценивая действие в #99.

trikom
Offline
Зарегистрирован: 15.08.2022

Нет, проблема не в этом, после Menu 0 происходит прерывание цикла.

trikom
Offline
Зарегистрирован: 15.08.2022

Переделал цикл, но проблема почему то не решается и не вижу почему



#include "U8glib.h"
#include <EEPROM.h>

U8GLIB_ST7920_128X64_4X u8g(10);

#define KEY_NONE 0
#define KEY_PREV 1
#define KEY_NEXT 2
#define KEY_SELECT 3

uint8_t uiKeyPrev = 8;
uint8_t uiKeyNext = 9;
uint8_t uiKeySelect = 12;

uint8_t uiKeyCodeFirst = KEY_NONE;
uint8_t uiKeyCodeSecond = KEY_NONE;
uint8_t uiKeyCode = KEY_NONE;

int dInk = 0;
int egg = 0;
int alarmTemp = 0;
int fanTemp = 0;

boolean needSave;
//boolean menu;

void uiSetup(void) {
  // configure input keys

  pinMode(uiKeyPrev, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyNext, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeySelect, INPUT_PULLUP);           // set pin to input with pullup
}

void uiStep(void) {
  uiKeyCodeSecond = uiKeyCodeFirst;
  if ( digitalRead(uiKeyPrev) == LOW )
    uiKeyCodeFirst = KEY_PREV;
  else if ( digitalRead(uiKeyNext) == LOW )
    uiKeyCodeFirst = KEY_NEXT;
  else if ( digitalRead(uiKeySelect) == LOW )
    uiKeyCodeFirst = KEY_SELECT;
  else
    uiKeyCodeFirst = KEY_NONE;

  if ( uiKeyCodeSecond == uiKeyCodeFirst )
    uiKeyCode = uiKeyCodeFirst;
  else
    uiKeyCode = KEY_NONE;
}


#define MENU_ITEMS 5
const char *menu_strings[MENU_ITEMS] = {"SETTINGS", "DAY INK", "EGG SETUP", "ALARM D.TEMP", "FAN D.TEMP" };
const int menu_ee[MENU_ITEMS] = {0, 100, 110, 106, 108 };
int menuValue[MENU_ITEMS];

uint8_t menuCurrent = 0;
//uint8_t menu_redraw_required = 0;
uint8_t last_key_code = KEY_NONE;


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

  u8g.setFont(u8g_font_6x13);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();

  h = u8g.getFontAscent() - u8g.getFontDescent();
  w = u8g.getWidth();
  for ( i = 0; i < MENU_ITEMS; i++ ) {
    u8g.setDefaultForegroundColor();
    if ( i == menuCurrent ) {
      u8g.drawBox(0, i * h + 1, w, h);
      u8g.setDefaultBackgroundColor();
    }
    u8g.drawStr(5, i * h, menu_strings[i]);
    u8g.setPrintPos(105, i * h);
    u8g.print(menuValue[i]);
  }
}

void updateMenu(void) {
  if ( uiKeyCode != KEY_NONE && last_key_code == uiKeyCode ) {
    return;
  }
  last_key_code = uiKeyCode;

  switch ( uiKeyCode ) {
    case KEY_SELECT:
       menuCurrent++;
      
      if ( menuCurrent >= MENU_ITEMS ) {
        menuCurrent = 0;
        break;
      }
      if ( needSave == 1 ) {
        EEPROM_int_write(menu_ee[menuCurrent - 1], menuValue[menuCurrent - 1]);
        needSave = 0;
      }
      break;
    case KEY_NEXT:
      menuValue[menuCurrent]++;
      needSave = 1;
      break;
    case KEY_PREV:
      menuValue[menuCurrent]--;
      needSave = 1;
      break;
  }
  Serial.print("menuCurrent=");
  Serial.println(menuCurrent);
}

void readSet() {
  menuValue[1]     = EEPROM_int_read(100);
  menuValue[2]     = EEPROM_int_read(110);
  menuValue[3]     = EEPROM_int_read(106);
  menuValue[4]     = EEPROM_int_read(108);
}

void draw(void) {
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 07, 18, "Incubator 0.1");
  u8g.drawStr( 07, 58, "with Arduino");
}

void setup() {

  Serial.begin(115200);
  readSet();
  uiSetup();
  
}

void loop() {
  Serial.println("loop");
  uiStep();                                     // check for key press

  if (  menuCurrent == 0 ) {
    u8g.firstPage();
    do  {
      draw();
      Serial.println("draw");
    } while ( u8g.nextPage() );
  }
  else {
    u8g.firstPage();
    do  {
      drawMenu();
    } while ( u8g.nextPage() );
  }

  updateMenu();                            // update menu bar
  delay(100);
}

int EEPROM_int_read(int addr) {
  byte raw[2];
  for (byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr + i);
  int &num = (int&)raw;
  return num;
}

void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for (byte i = 0; i < 2; i++) EEPROM.write(addr + i, raw[i]);
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

trikom пишет:

но после прохождения цикла пунктов меню не возвращается к начальному экрану 

...

trikom пишет:

Нет, проблема не в этом, после Menu 0 происходит прерывание цикла.

Противоречивые утверждения, не кажется?

trikom
Offline
Зарегистрирован: 15.08.2022
if (  menuCurrent == 0 ) {
    u8g.firstPage();
    do  {
      draw();
      Serial.println("draw");
    } while ( u8g.nextPage() );
  }

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

/sites/default/files/u67798/snimok_ekrana_2022-08-15_v_09.16.25.png

sadman41
Offline
Зарегистрирован: 19.10.2016

Может u8g_font_unifont кривой или строки выводятся не туда.

#152  в #145 откопируйте - проверите появится вообще хоть что-то на экране или нет.

trikom
Offline
Зарегистрирован: 15.08.2022

https://wokwi.com/projects/340049691659993683. Сделал в эмуляторе для проверки.

sadman41
Offline
Зарегистрирован: 19.10.2016
void draw(void) {
  u8g.setColorIndex(1); // <<<< крутить здесь

  u8g.setFont(u8g_font_6x13);
  u8g.drawStr( 07, 18, "Incubator 0.1");
  u8g.drawStr( 07, 58, "with Arduino");
}

void loop() {
  Serial.print("getColorIndex=");Serial.println(u8g.getColorIndex());
...
}

 

 

trikom
Offline
Зарегистрирован: 15.08.2022

Спасибо большое, долго бы до меня доходило, что картинка есть, но  с установкой цвета проблема.