Wątek przeniesiony 2021-02-15 20:35 z C/C++ przez furious programming.

Nieudane tworzenie menu dla Arduino

0

Napisalem kod ktory wyswietlać mial menu i submenu jednak po odpaleniu go w arduino na moim wyswietlaczu lcd pojawia sie tylko "opcja1opcja1opcja1..." i nie odpowiada na przyciski . Czy wie ktos co tu zle zrobilem i jak to naprawic? Kod wyglada tak :

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
//piny guzikow
#define DownB 10
#define UpB 9
#define SelectB 8
#define BackB 7

void setup() {
  lcd.begin();
  lcd.clear();
  pinMode( UpB,INPUT);
  pinMode( DownB,INPUT);
  pinMode( SelectB,INPUT);
  pinMode( BackB,INPUT);
}

//zmienne 
int pressBack;//sluza do okreslenia w jakim stanie jest pin
int pressUp;
int pressDown;
int pressSelect;
int readkey;

int menuState = 1;//sluza do okreslenia stanu menu
int subMenuState = 1;
int poziom = 1;


  void loop() {
     pressBack = digitalRead(BackB);
     pressUp  = digitalRead(UpB);
     pressDown  = digitalRead(DownB);
     pressSelect = digitalRead(SelectB);
    switch (menuState){
      case 1:
      option_1();
      break;
      case 2:
      option_2();
      break;
    }
      delay(300);
}
void option_1()
{
  if (poziom == 1)//menu głowne 
  {
    lcd.print("opcja1");
    if(pressUp==HIGH)
    {
    menuState =2;
    pressUp = LOW;
    }
    else if (pressSelect == HIGH)
    {
      poziom = 2;
      subMenuState = 1;
      pressSelect = LOW;
    }
  }
  else if(poziom == 2)
  {
    switch (subMenuState){
     case 1:
      lcd.clear();
      lcd.print("opcja 1.1");
      if(pressUp == HIGH)
      {
        subMenuState = 2;
        pressUp = LOW ;
      }
      else if(pressBack==HIGH )
      {
        poziom = 1;
        pressBack=LOW;
      }
      break;
     case 2:
     lcd.clear();
     lcd.print("opcja 1.2");
     if (pressUp == HIGH)
     {
      subMenuState = 3;
      pressUp = LOW;
     }
     else if (pressDown == HIGH)
     {
      subMenuState = 1;
      pressDown = LOW;
     }
     else if(pressBack == HIGH)
     {
      poziom = 1 ;
      pressBack = LOW;
     }
     break;
       case 3:
     lcd.clear();
     lcd.print("opcja 1.3");
     if (pressDown == HIGH)
     {
      subMenuState = 2;
      pressDown = LOW;
     }
     else if(pressBack == HIGH)
     {
      poziom = 1 ;
      pressBack = LOW;
     }
     break;
    }
  }
}
void option_2() 
{
  lcd.clear();
  lcd.print("opcja 2");
  if (pressDown == HIGH && poziom == 1){
  menuState = 1 ;
  pressDown = LOW;}
}
4

te zmienne **poziom ** i menustate to jakaś takie zagubione w tym kodzie są.
Generalnie masz nieprzemyślany ten kod.
Brakuje w nim widocznej logiki co zmienia stan menu a co odpowiada za poruszanie się po nim. Ciężko to przenanalizować.
Napisz to wszystko od początku z jakąś klarowną koncepcją.
Teraz masz 3 opcje i się gubisz... Co będzie przy 20 i kilku poziomach zagłębień.
Oddziel zmienną stanu menu od samego wyświetlania.

Spójrz na ten fragment kodu ... Z niego nic nie wynika a to Twoja główna pętla programu.
Nie wiadomo co ma na co wpływ. Poczytaj sobie o czymś takim jak maszyna stanów (https://ep.com.pl/files/1436.pdf). Zobaczysz, że wtedy nie będziesz potrzebował osobnych zmiennych na menu i subMenu bo wystarczy jedna zmienna a istotą jest zapisanie z jakiego stanu, w który może przechodzić.
Potem osobna funkcja co rysuje odpowiednie menu na podstawie wartości tej zmiennej i gotowe...

  void loop() {
     pressBack = digitalRead(BackB);
     pressUp  = digitalRead(UpB);
     pressDown  = digitalRead(DownB);
     pressSelect = digitalRead(SelectB);
    switch (menuState){
      case 1:
      option_1();
      break;
      case 2:
      option_2();
      break;
    }
      delay(300);
}

Poza tym dodałbym w kodzie eliminację powtórnych kliknięć przycisków i drgań styków.

A na LCD wypisuje w koło opcja 1 bo masz w kodzie wywoływane z pętli:

  if (poziom == 1)//menu głowne 
  {
    lcd.print("opcja1");

1 użytkowników online, w tym zalogowanych: 0, gości: 1