Arduino menu LCD

Masz problem z Arduino? Tutaj możesz szukać pomocy.
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 309
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Arduino menu LCD

Post autor: wojtekizk » 18 lut 2014, 08:02

Coż... sprawdziłem to, co jest napisane dla kuby..i działa dokładnie tak jak chciał, tzn po UP w menu Odczyt program wraca do root-a (korzenia) czyli do opcji "Kontrola szklarni:", tak jak chciał autor.
W Twoim przypadku nie widzę funkcji MenuChangeEvent, więc trudno zgadnąć co w niej robisz... u kuby wygląda to tak:

Kod: Zaznacz cały

void menuChangeEvent(MenuChangeEvent changed)
{
      Serial.print("jestes w opcji:  ");
      // poniżej sprytne przejscie do powitania :-)
      if(changed.to.getName()=="MenuRoot")Serial.println("Kontrola szklarni:");
      else Serial.println(changed.to.getName());
      
}
Prosiłem o cały kod Twojego programu... tak tracimy tylko czas...
Pozdrawiam

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


ojdas
Młodszy majsterkowicz
Posty: 5
Rejestracja: 17 lut 2014, 18:20

Re: Arduino menu LCD

Post autor: ojdas » 18 lut 2014, 11:14

Tutaj kod, jednakże nie jest to tak jak wczoraj pisałem kod Kuby tylko kod z Twojego dużego przykładowego menu. Za pomyłkę przepraszam.

Kod: Zaznacz cały

void menuChangeEvent(MenuChangeEvent changed)  // funkcja klasy MenuBackend 
{
  /* tak naprawdę to tylko tutaj przydaje się ów shortkey i służy przede wszystkim do wzbogacenia menu
   o symbole strzałek w zależności co wybrano. Wszystko co tutaj się wyprawia jest pokazywane na LCD. 
   */

  int c=changed.to.getShortkey();                         // pobieramy shortkey (1,2,3, lub4)
  lcd.clear();                                            // bez komentarza 
  lcd.setCursor(0,0); 
  if(c==1)                                                // jeśli to menu głowne (shortkey=1) to:
  {
    lcd.write(3);                                         // strzałka w lewo
    strcpy(linia1,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(19,0);
    lcd.write(4);                     // strzałka w prawo
    lcd.setCursor(0,1);
    lcd.write(5);                      // strzałka w dół
    lcd.setCursor(19,1);
    lcd.write(5);                     // strzałka w dół
  }
  if(c==2)                                              // jeśli to podmenu dla dziecka - (shortkey=2) to:
  {
    lcd.print("*");                                       // rysujemy gwiazdkę
    strcpy(linia2,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(19,0);
    lcd.print("*");                   // gwiazdka 
    lcd.setCursor(0,1);
    lcd.write(6);                      // druga linia i strzałka powrotu (arrowBack)
    lcd.print(changed.to.getName());                      // wyświetlamy nazwe "dziecka"
    lcd.setCursor(19,1);
    lcd.write(7);                     // strzałka góra-dół
  }
  if(c==3)                                              // jeśli dziecko  ma dziecko - (shortkey =3) to:
  {
    lcd.print("*");                                       // gwiazdka
    strcpy(linia2,changed.to.getName());                  // kopiujemy akt. nazwe opcji menu do zmiennej linia2
    lcd.print(linia1);                                    // i wyświetlamy pierwszą linię
    lcd.setCursor(19,0);
    lcd.print("*");                   // gwiazdka
    lcd.setCursor(0,1);
    lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka w drugiej linii
    lcd.setCursor(19,1);
    lcd.write(4);                     // strzałka w prawo bo są wnuki
  }

  if(c==4)                                              // jeśli to wnuk  (shortkey =4) to:
  {
    lcd.print("*");                                       // gwaizdka
    lcd.print(linia2);                                    // w pierwszej linii wyświetlamy dziecko ( czyli rodzica wnuka) 
    lcd.setCursor(19,0);
    lcd.print("*");                   // gwaizdka
    lcd.setCursor(0,1);
    lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka
    lcd.setCursor(19,1);
    lcd.write(7);                     // strzałka góra-dół 
  }

}
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 309
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Arduino menu LCD

Post autor: wojtekizk » 18 lut 2014, 14:03

Witam ponownie...
Hmmm... mój drogi kolego, swój własny kod zamieszczony w tutorialu znam :-)
Mnie chodziło o cały Twój kod, bo przecież prosisz o pomoc w swojej sprawie prawda, czy się mylę?
Zamieść tu CAŁY swój program... od #include po koniec loopa :-) Tylko wtedy mogę mieć jakieś pojęcie :-)
Wyrwane z kontekstu fragmenty kodu nie pomogą za wiele.
Pozdrawiam
ojdas
Młodszy majsterkowicz
Posty: 5
Rejestracja: 17 lut 2014, 18:20

Re: Arduino menu LCD

Post autor: ojdas » 18 lut 2014, 15:14

Poniżej cały kod:

Kod: Zaznacz cały

// ============= MenuBackend tutorial ===============================================
#include <MenuBackend.h>                 // dołączenie biblioteki
//#include <LiquidCrystal.h>               // obsługa wyświetlacza LCD

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

int led = 13;

LiquidCrystal_I2C lcd(0x27,20,4);


// --- definiujemy dla LCD własne znaki strzałek: dół, lewo, prawo, gora-dół i powrót ---
uint8_t arrowUpDown[8] = {
  0x4,0xe,0x15,0x4,0x15,0xe,0x4};
uint8_t arrowDown[8]  = {
  0x4,0x4,0x4,04,0x15,0xe,0x4};
uint8_t arrowRight[8] = {
  0x0,0x4,0x2,0x1f,0x2,0x4,0x0};
uint8_t arrowLeft[8] = {
  0x0,0x4,0x8,0x1f,0x8,0x4,0x0};
uint8_t arrowBack[8] = {
  0x1,0x1,0x5,0x9,0x1f,0x8,0x4};

//LiquidCrystal lcd(8,9,4,5,6,7);    // definicja pinów dla LCD (sprawdź piny w swoim LCD)
volatile int zm =-1;               // to dla kontroli zmiany stanu klawiatury
volatile int x=-1;                 // zmienna pomocnicza
volatile int stan_Analog;          // wartość na wejściu Analogowym dla klawiaturki analogowej
char *linia1;                      // pierwsza linia wyświetlanego tekstu na LCD
char *linia2;                      // druga linia wyświetlanego tekstu na LCD

// --- tworzymy wszystkie opcje Menu: ---------------------------------------
// de facto tworzymy obiekty klasy MenuItem, które dziedziczą po klasie MenuBackend
MenuBackend menu = MenuBackend(menuUseEvent,menuChangeEvent); // konstruktor 
//                        ("                ")

MenuItem P1 = MenuItem("TestAAA",1);
MenuItem P11 = MenuItem("ON",2);
MenuItem P12 = MenuItem("OFF",2);

MenuItem P2 = MenuItem("TestBBB",1);
MenuItem P21 = MenuItem("Test1",2);
MenuItem P22 = MenuItem("Test2",2);

/* --- Teraz pozycjonujemy  menu ( zgodnie z ustawieniem podanym powyżej) ------------
 add - dodaje w pionie, addRight - dodaje w poziomie z prawej , addLeft dodaje z lewej
 */
void menuSetup()                       // funkcja klasy MenuBackend 
{
  menu.getRoot().add(P1);          // ustawiamy korzeń Menu, czyli pierwszą opcję
  P1.add(P11);
  P11.add(P12);
  P11.addLeft(P1);
  P12.addLeft(P1);
  P12.add(P11);
  P1.addRight(P2);
  P2.addLeft(P1);

  P2.add(P21);
  P21.add(P22);
  P21.addLeft(P2);
  P22.addLeft(P2);
  P22.add(P21);
  P2.addRight(P1);


}
// ----------- uff... nareszcie :-) -----------------------------------------------------------------------
void menuUseEvent(MenuUseEvent used)      // funkcja klasy MenuBackend - reakcja na wciśnięcie OK
// tutaj właśnie oddajemy menu na rzecz akcji obsługi klawisza OK
{
  //Serial.print("wybrano: "); 
  //Serial.println(used.item.getName()); // do testów, potem niepotrzebne
  // --- ponizej kilka przykładów obsługi  opcji -----------
  // przykładowa reakcja na wcisnięcie klawisza OK w opcji Otworz :
  if (used.item.getName() == "ON")   // Uwaga - dokładnie taki sam ciąg "    Otworz" jak w menu !!!
    // bo przecież getName() pobiera nazwę
  {
    lcd.setCursor(1,0);
    lcd.print("  Turn it ON!  "); // info 
    digitalWrite(led,HIGH);
    delay(1000);
    //digitalWrite(led,LOW); // na 2 sekundy pin 0 otrzymał stan wysoki
    // czyli np. otworzyły się drzwi
    //delay(1000);
    lcd.setCursor(1,0);
    lcd.setCursor(1,0);
    lcd.print(linia1); //poprzedni stan LCD
  }

  if (used.item.getName() == "OFF")   // Uwaga - dokładnie taki sam ciąg "    Otworz" jak w menu !!!
    // bo przecież getName() pobiera nazwę
  {
    lcd.setCursor(1,0);
    lcd.print("  Turn it OFF!  "); // info  
    //digitalWrite(led,HIGH);
    //delay(1000);
    digitalWrite(led,LOW); // na 2 sekundy pin 0 otrzymał stan wysoki
    // czyli np. otworzyły się drzwi
    delay(1000);
    lcd.setCursor(1,0);
    lcd.print("              ");
    lcd.setCursor(1,0);
    lcd.print(linia1); //poprzedni stan LCD
  }

  // A teraz coś ambitniejszego :-), bo przekazujemy sterowanie klawiaturką do innej procedury,
  // w tym przykładzie programik czeka aż ustawisz jakąś temperaturę i po wciśnięciu OK wraca do pętli głównej
  if (used.item.getName() == " Temperatura")   // dokładnie taki sam ciąg " Temperatura"
  {
    int temp=21;                         // przykładowo 21 st. C
    lcd.setCursor(0,0);
    lcd.write(7);     // wyswietlamy nasz symbol strzałki góra-dół
    lcd.print("              ");
    lcd.setCursor(1,0);
    lcd.print("Ust.temp. = "); // tekst dla użytkownika
    lcd.setCursor(13,0);
    lcd.print(temp); // wyświetlamy akt. temperaturę
    int  akcja=-1;
    delay(1000);         // zmienna pomocnicza, sterująca dla petli while
    // jesli nie puścisz klawisza OK w ciągu 1 sek. to powrót do menu    
    while(akcja!=4)                   // ta pętla trwa tak długo aż wciśniesz klawisz OK  
    {
      zm=-1; 
      akcja=czytaj_1(0);//delay(300);   // odczyt stanu klawiatury - funkcja czytaj_1 lub czytaj_2 lub czytaj_3
      // opis poniżej przy 3 różnych definicjach funkcji czytaj
      if(zm!=akcja)                    // ruszamy do pracy tylko wtedy gdy zmienił sie stan klawiatury
      {
        if (akcja==1) {
          temp++;
          if(temp>99)temp=99;
          lcd.setCursor(13,0);
          lcd.print(temp);
          delay(300);
        }
        // jesli akcja=1 (czyli wciśnieto klawisz w górę to zwiększono temperaturę
        // ustawiono max próg i wyświetlono obecną temperaturę
        if(akcja==2)  {
          temp--;
          if(temp<10)temp=10;
          lcd.setCursor(13,0);
          lcd.print(temp);
          delay(300);
        }
        // jesli akcja=2 (czyli wciśnieto klawisz w dół to mniejszono temperaturę
        // ustawiono min próg i wyświetlono obecną temperaturę
        if(akcja==4) // jeśli wciśnieto OK 
        {
          lcd.setCursor(0,0);
          lcd.print("*Temperatura OK");
          delay(2000); // pokazujemy OK przez 2 sek.
          lcd.setCursor(1,0);
          lcd.print("              "); // czyścimy linię
          lcd.setCursor(1,0);
          lcd.print(linia1);           // odtwarzamy poprzedni stan na LCD
        }
      } 
    } 
    zm=akcja;  // aktualizacja zmiennej zm, po to aby reagować tylko na zmiany stanu klawiatury
    // tu WAŻNY MOMENT - kończy się pętla while i zwracamy sterowanie do głównej pętli loop()
  }
  // a tutaj obsługa pozostałych opcji :-)  
  // ...
  // ...
}
// --- Reakcja na wciśnięcie klawisza -----------------------------------------------------------------
void menuChangeEvent(MenuChangeEvent changed)  // funkcja klasy MenuBackend 
{
  /* tak naprawdę to tylko tutaj przydaje się ów shortkey i służy przede wszystkim do wzbogacenia menu
   o symbole strzałek w zależności co wybrano. Wszystko co tutaj się wyprawia jest pokazywane na LCD. 
   */

  int c=changed.to.getShortkey();                         // pobieramy shortkey (1,2,3, lub4)
  lcd.clear();                                            // bez komentarza 
  lcd.setCursor(0,0); 
  if(c==1)                                                // jeśli to menu głowne (shortkey=1) to:
  {
    lcd.write(3);                                         // strzałka w lewo
    strcpy(linia1,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(19,0);
    lcd.write(4);                     // strzałka w prawo
    lcd.setCursor(0,1);
    lcd.write(5);                      // strzałka w dół
    lcd.setCursor(19,1);
    lcd.write(5);                     // strzałka w dół
  }
  if(c==2)                                              // jeśli to podmenu dla dziecka - (shortkey=2) to:
  {
    lcd.print("*");                                       // rysujemy gwiazdkę
    strcpy(linia2,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(19,0);
    lcd.print("*");                   // gwiazdka 
    lcd.setCursor(0,1);
    lcd.write(6);                      // druga linia i strzałka powrotu (arrowBack)
    lcd.print(changed.to.getName());                      // wyświetlamy nazwe "dziecka"
    lcd.setCursor(19,1);
    lcd.write(7);                     // strzałka góra-dół
  }
  if(c==3)                                              // jeśli dziecko  ma dziecko - (shortkey =3) to:
  {
    lcd.print("*");                                       // gwiazdka
    strcpy(linia2,changed.to.getName());                  // kopiujemy akt. nazwe opcji menu do zmiennej linia2
    lcd.print(linia1);                                    // i wyświetlamy pierwszą linię
    lcd.setCursor(19,0);
    lcd.print("*");                   // gwiazdka
    lcd.setCursor(0,1);
    lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka w drugiej linii
    lcd.setCursor(19,1);
    lcd.write(4);                     // strzałka w prawo bo są wnuki
  }

  if(c==4)                                              // jeśli to wnuk  (shortkey =4) to:
  {
    lcd.print("*");                                       // gwaizdka
    lcd.print(linia2);                                    // w pierwszej linii wyświetlamy dziecko ( czyli rodzica wnuka) 
    lcd.setCursor(19,0);
    lcd.print("*");                   // gwaizdka
    lcd.setCursor(0,1);
    lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka
    lcd.setCursor(19,1);
    lcd.write(7);                     // strzałka góra-dół 
  }

}
/* --- ponżej funkcja odczytująca stan klawiatury -------------------------------------------
 przygotowałem 3 różne wersje:
 1) dla klawiaturki analogowej z shielda LCDanalogKey firmy DFRobot
 2) dla joysticka ( 2 wejscia Analogowe i 1 pin cyfrowy )
 Uwaga dla tej wersji opcji musisz dopisać w funkcji setup konfigurację dla pin, np. tak:
 pinMode(1,INPUT);digitalWrite(1,HIGH);
 3) dla 5-ciu pojedynczych przycisków ( potrzeba 5 pinów cyfrowych)
 Uwaga dla tej wersji opcji musisz dopisać w funkcji setup konfigurację dla pinów, np. tak:
 pinMode(1,INPUT);digitalWrite(1,HIGH);
 pinMode(2,INPUT);digitalWrite(2,HIGH);
 pinMode(3,INPUT);digitalWrite(3,HIGH); 
 pinMode(11,INPUT);digitalWrite(11,HIGH); 
 pinMode(12,INPUT);digitalWrite(12,HIGH); 
 */
// --- wersja dla klawiatury 5-cio przyciskowej DFRobot --------------------------------------
volatile int czytaj_1(int analog)
{
  int stan_Analog = analogRead(analog);
  delay(30);//Serial.println(stan_Analog); 
  if (stan_Analog > 1000) return -1; // dla wartosci poza zakresem
  if (stan_Analog < 50)   return 0;  // w prawo  
  if (stan_Analog < 150)  return 1;  // do gĂłry 
  if (stan_Analog < 333)  return 2;  // w dół 
  if (stan_Analog < 510)  return 3;  // w lewo  
  if (stan_Analog < 745)  return 4;  // OK 
  return -1;                         // nic nie wcisnieto
}
// --- wersja dla joysticka (2 wejscia analogowe + pin cyfrowy -------------------------------
int czytaj_2(int poziom, int pion, int pinD)
{
  // poziom - nr wejścia analogowego do którego podłączona jest manetka joysticka dla ruchu lewo-prawo
  // pion   - nr wejścia analogowego do którego podłączona jest manetka joysticka dla ruchu góra-dół
  // pinD   - nr pinu cyfrowego do którego podłączony jest przycisk OK w joysticku
  int stan1= analogRead(pion); 
  {
    delay(60);
    if(stan1>0)stan1=(stan1+50)/1024+1;
  }  
  int stan2= analogRead(poziom); 
  {
    delay(60);
    if(stan2>0)stan2=(stan2+50)/1024+1;
  } 
  int stanD=digitalRead(pinD);
  if(stanD==LOW) return 4;           // OK 
  if(stan1==0) return 2;             // w dół
  if(stan1==2) return 1;             // do gĂłry
  if(stan2==0) return 3;             // w lewo
  if(stan2==2) return 0;             // w prawo
  return -1;                         // nic nie wcisnieto
}
// --- wersja dla 5-ciu przycisków cyfrowych --------------------------------------------------
// dla przykładu jeśli wykorzystujesz piny: 1,2,3,11 i 12 to wołasz : czytaj_2(1,2,3,11,12)
int czytaj_3(int gora, int lewo, int ok, int prawo,int dol)
// gora   - nr pinu cyfrowego do którego podłączony jest przyciski góra
// lewo   - nr pinu cyfrowego do którego podłączony jest przyciski lewo
// ok     - nr pinu cyfrowego do którego podłączony jest przyciski OK
// prawo  - nr pinu cyfrowego do którego podłączony jest przyciski prawo
// dol    - nr pinu cyfrowego do którego podłączony jest przyciski dół
{
  if(digitalRead(gora)==LOW) return 1;
  if(digitalRead(lewo)==LOW) return 3;
  if(digitalRead(ok)==LOW) return 4;
  if(digitalRead(prawo)==LOW) return 0;
  if(digitalRead(dol)==LOW) return 2;
  return -1;
}
// ============================================================================================
// 
void setup()
{
  linia1=new char[20]; 
  linia2=new char[20];
  
  Serial.begin(9600);
  //lcd.begin(16, 2);     // inicjacja LCD

  lcd.init();
  lcd.backlight();

  lcd.createChar(3,arrowLeft);
  lcd.createChar(4,arrowRight);
  lcd.createChar(5,arrowDown);
  lcd.createChar(6,arrowBack);
  lcd.createChar(7,arrowUpDown);
  
  /* tu przykładowe piny cyfrowe dla 3 wersji funkcji czytaj_3(1,2,3,11,12)
   pinMode(1,INPUT);digitalWrite(1,HIGH);
   pinMode(2,INPUT);digitalWrite(2,HIGH);
   pinMode(3,INPUT);digitalWrite(3,HIGH); 
   pinMode(11,INPUT);digitalWrite(11,HIGH); 
   pinMode(12,INPUT);digitalWrite(12,HIGH); 
   */
  pinMode(0,OUTPUT);
  //digitalWrite(0,LOW); // do testów 

  menuSetup();          // funkcja klasy MenuBackend - tu tak naprawdę tworzymy nasze menu 
  menu.moveDown();      // idziemy do pierwszej opcji - PLIK, moveDown bo pierwotnie byliśmy w root

  pinMode(led, OUTPUT); // moje do testów led na pin 13

}
// --- I nadszedł czas na neverending story :-) -------------------------------------------- 
void loop()    
{
  x=czytaj_1(0);
  delay(30);             // odczytujemy stan klawiatury:
  /*
  Ja używam funkcji czytaj_1() bo mam akurat klawiaturkę podpiętą pod A0
   Jeśli masz inna klawiaturkę to użyj funkcji czytaj_2 lub czytaj_3 - patrz opis
   Ponadto musisz pamietać że w funkcji obsługo klawisza OK - menuUseEvent(MenuUseEvent used)
   także musisz użyć odpowiedniej wersji funkcji czytaj !!!
   */
  if(zm!=x)                               // jesli była zmiana stanu to :
  {
    switch(x)                           // sprawdzamy co nacisnieto 
    {
    case 0: 
      menu.moveRight();
      break;     // jesli naciśnięto klawisz w Prawo to przesuń menu w prawo
    case 1: 
      menu.moveUp();
      break;        // menu do góry
    case 2: 
      menu.moveDown();
      break;      // menu w dół
    case 3: 
      menu.moveLeft();
      break;      // menu w lewo
    case 4: 
      menu.use();
      break;           // wciśnięto OK więc skok do funkcji menuUseEvent(MenuUseEvend used)
      // to w tej funkcji właśnie obsługujemy nasze Menu, tu sprawdzamy
      // jaką opcję wybrano i tutaj tworzymy kod do obslugi zdarzenia.
    }
  } 
  zm=x;                               // przypisanie zmiennej zm wartości x po to, aby dluższe wciskanie tego
  // samego klawisza nie powodowało ponownej generacji zdarzenia. 
  // program reaguje na zmianę stanu klawiatury.
}
// === KONIEC ===========================================================
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 309
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Arduino menu LCD

Post autor: wojtekizk » 19 lut 2014, 08:59

Witam... sorry że dopiero teraz odpisuje...
W skrypcie napisanym dla kuby w funkcji menuChangeEvent(...) na końcu masz taką linię:

Kod: Zaznacz cały

if(changed.to.getName()=="MenuRoot")Serial.println("Kontrola szklarni:");
... co w wolnym tłumaczeniu oznacza:
jeśli w menu skoczyłeś do korzenia - MenuRoot to wykonaj jakąś akcję. W przypadku kuby program wyświetla po prostu komunikat powitalny, bo tak chciał kuba.
W Twoim przypadku program powinien wyświetlić to samo co wyświetla opcja "TestAAA" bo przecież ustaliłeś że:
menu.getRoot().add(P1); - czyli korzeniem jest opcja :TestAAA
Zatem powinieneś na końcu, w funkcji menuChangeEvent ( przed nawiasem zamykającym funkcję) dodać:

Kod: Zaznacz cały

if(changed.to.getName()=="MenuRoot")
  {
    lcd.clear();                                            // bez komentarza 
    lcd.setCursor(0,0); 
    lcd.write(3);                                         // strzałka w lewo
    strcpy(linia1,"TestAAA");                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(19,0);
    lcd.write(4);                     // strzałka w prawo
    lcd.setCursor(0,1);
    lcd.write(5);                      // strzałka w dół
    lcd.setCursor(19,1);
    lcd.write(5);                     // strzałka w dół
  }
Pozdrawiam
ojdas
Młodszy majsterkowicz
Posty: 5
Rejestracja: 17 lut 2014, 18:20

Re: Arduino menu LCD

Post autor: ojdas » 19 lut 2014, 14:23

Dzieki za info i pomoc.
Cały czas ucze się Twojego skryptu dostosowując go do własnych potrzeb.

Mam pytanie jeszcze z natury znaków specialnych. Chciałem dodać dodatkowe nazwijmy to ikonki.
Dziwna sprawa bo jak deklaruje je w

Kod: Zaznacz cały

void setup()
i mam coś takiego:

Kod: Zaznacz cały

  lcd.createChar(3,arrowLeft);
  lcd.createChar(4,arrowRight);
  lcd.createChar(5,arrowDown);
  lcd.createChar(6,arrowBack);
  lcd.createChar(7,arrowUpDown);
  lcd.createChar(8,battFull);
  lcd.createChar(9,arrowLeftB);
  lcd.createChar(10,arrowRightB);
  lcd.createChar(11,arrowLeftBE);
  lcd.createChar(12,arrowRightBE);
  lcd.createChar(13,robot);
to ta deklaracja

Kod: Zaznacz cały

lcd.createChar(13,robot);
nie wiem czemu zostaje automatycznie zastąpiona tą

Kod: Zaznacz cały

lcd.createChar(5,arrowDown);
I wszystko zostaje podmienione na ekranie.
Masz może pomysł czemu tak może się dziać?
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 309
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Arduino menu LCD

Post autor: wojtekizk » 19 lut 2014, 17:57

Cześć ...definiowanie własnych znaków jest realizowane w pamięci samego wyświetlacza i niestety większość z nich może zapamiętać max. 8 znaków. Musisz poczytać notę katalogową takiego LCD. Zresztą jak wpiszesz w Googlle 16x2 LCD i własne znaki to w mig się zorientujesz :-)
Pozdrawiam
Bartek
Młodszy majsterkowicz
Posty: 2
Rejestracja: 22 cze 2014, 12:08

Re: Arduino menu LCD

Post autor: Bartek » 30 cze 2014, 20:02

Witam,
Jestem nowy na forum. Właśnie rozpoczynam swoją przygodę z Arduino - i prosze o pomoc w tworzeniu menu na LCD. Coś mi nie działa za dobrze to menu. Zamysł jest taki aby z menu zmieniać nastawy dla 5 parametrów - 3 nastawy PWM, Licznik i skala. Na chwilę obecną potrzebuję sprawdzić jaki błąd jest w kodzie, że nie działa to prawidłowo oraz prosze o pomoc jak wstawić zmienne które mogę ustawiać + lub - z pozycji menu i dalej wpisac je jako wartości dla wyjść PWM. Kod MENU:

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include <MenuBackend.h> //MenuBackend library
//this library is included in the Arduino IDE

const int buttonPinLeft = 0; // pin for the Up button
const int buttonPinRight = 1; // pin for the Down button
const int buttonPinEsc = 2; // pin for the Esc button
const int buttonPinEnter = 3; // pin for the Enter button
const int buttonPinUp = 4; // pin for the UP button
int lastButtonPushed = 0;

int lastButtonEnterState = LOW; // the previous reading from the Enter input pin
int lastButtonEscState = LOW; // the previous reading from the Esc input pin
int lastButtonLeftState = LOW; // the previous reading from the Left input pin
int lastButtonRightState = LOW; // the previous reading from the Right input pin
int lastButtonUpState = LOW;

long lastEnterDebounceTime = 0; // the last time the output pin was toggled
long lastEscDebounceTime = 0; // the last time the output pin was toggled
long lastLeftDebounceTime = 0; // the last time the output pin was toggled
long lastRightDebounceTime = 0; // the last time the output pin was toggled
long lastUpDebounceTime = 0;
long debounceDelay = 500; // the debounce time

LiquidCrystal_I2C lcd(0x27,16,2);

//Menu variables
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menu items
MenuItem menu1Item1 = MenuItem("PWM1");
MenuItem menuItem1SubItem1 = MenuItem("Ustaw PWM1");
MenuItem menu1Item2 = MenuItem("PWM2");
MenuItem menuItem2SubItem1 = MenuItem("Ustaw PWM2");
MenuItem menu1Item3 = MenuItem("PWM3");
MenuItem menuItem3SubItem1 = MenuItem("Ustaw PWM3");
MenuItem menu1Item4 = MenuItem("Odlicz wstecz");
MenuItem menuItem4SubItem1 = MenuItem("Ile mam odliczyc?");
MenuItem menu1Item5 = MenuItem("Skalowanie");
MenuItem menuItem5SubItem1 = MenuItem("Podaj skale");

void setup()
{
pinMode(buttonPinLeft, INPUT_PULLUP);
pinMode(buttonPinRight, INPUT_PULLUP);
pinMode(buttonPinEnter, INPUT_PULLUP);
pinMode(buttonPinEsc, INPUT_PULLUP);
pinMode(buttonPinUp, INPUT_PULLUP);

lcd.init(); // initialize the lcd


lcd.backlight();
lcd.begin(16, 2);

//configure menu
menu.getRoot().add(menu1Item1);
menu1Item1.addRight(menu1Item2).addRight(menu1Item3).addRight(menu1Item4).addRight(menu1Item5);
menu1Item1.add(menuItem1SubItem1);
menu1Item2.add(menuItem2SubItem1);
menu1Item3.add(menuItem3SubItem1);
menu1Item4.add(menuItem4SubItem1);
menu1Item5.add(menuItem5SubItem1);
menu.getRoot();
lcd.setCursor(0,0);
lcd.print("Menu");

} // setup()...


void loop()
{

readButtons(); //I splitted button reading and navigation in two procedures because
navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings)

} //loop()...


void menuChanged(MenuChangeEvent changed){

MenuItem newMenuItem=changed.to; //get the destination menu

lcd.setCursor(0,1); //set the start position for lcd printing to the second row

if(newMenuItem.getName()==menu.getRoot()){
lcd.print("MENU GLOWNE ");
}else if(newMenuItem.getName()=="PWM1"){
lcd.print("PWM1 ");
}else if(newMenuItem.getName()=="Ustaw PWM1"){
lcd.print("Ustaw PWM1 ");
}else if(newMenuItem.getName()=="PWM2"){
lcd.print("PWM2 ");
}else if(newMenuItem.getName()=="Ustwaw PWM2"){
lcd.print("Ustaw PWM2 ");
}else if(newMenuItem.getName()=="PWM3"){
lcd.print("PWM3 ");
}else if(newMenuItem.getName()=="Ustaw PWM3"){
lcd.print("Ustaw PWM3 ");
}else if(newMenuItem.getName()=="Odlicz wstecz"){
lcd.print("Odlicz wstecz ");
}else if(newMenuItem.getName()=="Ile mam odliczyc?"){
lcd.print("Ile mam odliczyc? ");
}else if(newMenuItem.getName()=="Skalowanie"){
lcd.print("Skalowanie ");
}else if(newMenuItem.getName()=="Podaj skale"){
lcd.print("Podaj skale ");
}
}

void menuUsed(MenuUseEvent used){
lcd.setCursor(0,0);
lcd.print("Jestes w menu ");
lcd.setCursor(0,1);
lcd.print(used.item.getName());
delay(3000); //delay to allow message reading
lcd.setCursor(0,0);
lcd.print("TRANSPORTER ");
menu.getRoot(); //back to Main
}


void readButtons(){ //read buttons status

int reading;
int buttonEnterState=HIGH; // the current reading from the Enter input pin
int buttonEscState=HIGH; // the current reading from the input pin
int buttonLeftState=HIGH; // the current reading from the input pin
int buttonRightState=HIGH; // the current reading from the input pin

//Enter button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEnter);

// check to see if you just pressed the enter button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:

// If the switch changed, due to noise or pressing:
if (reading != lastButtonEnterState) {
// reset the debouncing timer
lastEnterDebounceTime = millis();
}

if ((millis() - lastEnterDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEnterState=reading;
lastEnterDebounceTime=millis();
}

// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEnterState = reading;


//Esc button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEsc);

// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:

// If the switch changed, due to noise or pressing:
if (reading != lastButtonEscState) {
// reset the debouncing timer
lastEscDebounceTime = millis();
}

if ((millis() - lastEscDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEscState = reading;
lastEscDebounceTime=millis();
}

// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEscState = reading;


//Down button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinRight);

// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:

// If the switch changed, due to noise or pressing:
if (reading != lastButtonRightState) {
// reset the debouncing timer
lastRightDebounceTime = millis();
}

if ((millis() - lastRightDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonRightState = reading;
lastRightDebounceTime =millis();
}

// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonRightState = reading;


//Up button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinLeft);

// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:

// If the switch changed, due to noise or pressing:
if (reading != lastButtonLeftState) {
// reset the debouncing timer
lastLeftDebounceTime = millis();
}

if ((millis() - lastLeftDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonLeftState = reading;
lastLeftDebounceTime=millis();;
}

// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonLeftState = reading;

//records which button has been pressed
if (buttonEnterState==HIGH){
lastButtonPushed=buttonPinEnter;

}else if(buttonEscState==HIGH){
lastButtonPushed=buttonPinEsc;

}else if(buttonRightState==HIGH){
lastButtonPushed=buttonPinRight;

}else if(buttonLeftState==HIGH){
lastButtonPushed=buttonPinLeft;

}else{
lastButtonPushed=0;
}
}

void navigateMenus() {
MenuItem currentMenu=menu.getCurrent();

switch (lastButtonPushed){
case buttonPinEnter:
if(!(currentMenu.moveDown())){ //if the current menu has a child and has been pressed enter then menu navigate to item below
menu.use();
}else{ //otherwise, if menu has no child and has been pressed enter the current menu is used
menu.moveDown();
}
break;
case buttonPinEsc:
menu.getRoot(); //back to main
break;
case buttonPinRight:
menu.moveRight();
break;
case buttonPinLeft:
menu.moveLeft();
break;
}

lastButtonPushed=0; //reset the lastButtonPushed variable
}



Sterowanie PWM które chciałbym scalić i ustawiać z pozycji menu:




int pwmMotorA=9;

int pwmMotorB=10;

int pwmMotorC=11;

void setup() {

//Wyjście PWM kanału A

pinMode(pwmMotorA, OUTPUT);

//Wyjście PWM kanału B

pinMode(pwmMotorB, OUTPUT);

//Wyjście PWM kanału C

pinMode(pwmMotorC, OUTPUT);
}
// Nieskonczona pętla

void loop() {

//Opóźnienie 2s

delay(2000);

//Kanał A

//(zakres PWM: 8bitów czyli 0-255)

analogWrite(pwmMotorA,190);

//Kanał B

//(zakres PWM: 8bitów czyli 0-255)
delay(2000);
analogWrite(pwmMotorB,190);

//Kanał C

//(zakres PWM: 8bitów czyli 0-255)
delay(2000);
analogWrite(pwmMotorC,190);

}

Dodatkowo do całości chce dołączyć czujnik i liczyć z niego impulsy. Na razie utknąłem przy menu i próbie scalenia programów. Może jest ktoś kto byłby w stanie mi pomóc. A może znalazł by się ktoś, kto chciałby się podjąć napisania kompleksowo programu - oczywiście odpłatnie. Jeżeli tak to proszę o kontakt. Sprawa jest dość pilna. Więcej szczegółów na priv.
ODPOWIEDZ

Strony partnerskie: