Arduino LCD Menü mit rotary switch

Arduino LCD Menü mit rotary switch

Beitragvon Rocktagon » So 23. Dez 2012, 09:38

Ein Menü welches über ein Drehencoder mit Druckknopf gesteuert wird.
Ausgabe an einem LCD.
Benutzt habe ich dafür ein Arduino Mini Pro mit LCD 20x4 aber auch andere Arduinos und Displays sind möglich.
10K Pulldowns von Digital 2+3 sowie switch nach GND nicht vergessen.
Code: Alles auswählen
#include <LiquidCrystal.h>


// select the pins used on the LCD panel:
/*
2=D7
 3=D6
 4=D5
 5=D4
 11=E (Enabled)
 12=RS
 10 KOhm Poti:
 1 = +
 2 = Vo
 3 = -
 R/W auf GND
 */

/*
 Rotary switch:
 1 auf +
 2 auf digital 2 (interrupt)
 3 auf digital 3 (interrupt)
 
 */
LiquidCrystal lcd(9, 8, 10, 11, 12, 13); //Pro Mini Handheld 20x4
//LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //LCD Shield BB Robot 16x2
char LCDChar[2]="";
byte lastp=0; //Letzer Zustand des select buttons
byte aktp=0; //Aktueller Zustand des select Buttons
byte mainMenue=255; //Aktuelles Hauptmenü
int Msize; //Anzahl Menüeintrage

#define MCHAR 16   //Char count für eine Zeile
#define MMAX  2  //Max anzahl Hauptmenüpunkte
#define MROW  4    //Max anzahl Menü mit submenüs

//Das Menü
char menuArray[MMAX][MROW][MCHAR]=

  { 
    "Kaffee", "Benutzer","Reset"      }
  ,
  { 
    "Main menue 2", "Submenu 2-1", "Submenu 2-2", "Submenu 2-3"      } 
};


volatile boolean fired = false;
volatile long rotaryCount = 0;

// Interrupt Service Routine
void isr ()
{

  static boolean ready;
  static unsigned long lastFiredTime;
  static byte pinA, pinB; 

  // wait for main program to process it
  if (fired)
    return;

  byte newPinA = digitalRead (2);
  byte newPinB = digitalRead (3);

  // Forward is: LH/HH or HL/LL
  // Reverse is: HL/HH or LH/LL

  // so we only record a turn on both the same (HH or LL)

  if (newPinA == newPinB)
  {
    if (ready)
    {
      long increment = 1;

      // if they turn the encoder faster, make the count go up more
      // (use for humans, not for measuring ticks on a machine)
      unsigned long now = millis ();
      unsigned long interval = now - lastFiredTime;
      lastFiredTime = now;

      if (interval < 10)
        increment = 5;
      else if (interval < 20)
        increment = 3;
      else if (interval < 50)
        increment = 2;

      if (newPinA == HIGH)  // must be HH now
      {
        if (pinA == LOW)
          rotaryCount += increment;
        else
          rotaryCount -= increment;
      }
      else
      {                  // must be LL now
        if (pinA == LOW) 
          rotaryCount -= increment;
        else
          rotaryCount += increment;       
      }
      fired = true;
      ready = false;
    }  // end of being ready
  }  // end of completed click
  else
    ready = true;

  pinA = newPinA;
  pinB = newPinB;
}  // end of isr



void setup()
{
  analogWrite(A0,250); //Hintergrundbeleuchtung des LCD einschalten
  lcd.begin(20, 4);              // 20x4 LCD panel
  lcd.setCursor(0,0);
  lcd.print("Setter V1.0");

  digitalWrite (2, HIGH);   // activate pull-up resistors
  digitalWrite (3, HIGH);

  attachInterrupt (0, isr, CHANGE);   //Interrupt für rotary encode an digital 2 (interrupt 0=digital 2)
  attachInterrupt (1, isr, CHANGE);   //Interrupt für rotary encode an digital 3 (interrupt 1=digital 3)


}

void loop()
{
  if (fired)
  {
    lcd.clear();

    lcd.setCursor(0,0);
    if (mainMenue==255) //Noch kein Hauptmenü ausgewählt
    {
      if (rotaryCount<0) { //Wenn unter Null Menü wieder von hinten anfangen
        rotaryCount=MMAX-1;
      }
      if (rotaryCount>MMAX-1) {//Auf anzahl Menüs beschränken
        rotaryCount=0;
      }
      lcd.print(menuArray[rotaryCount][0]);
    }
    else
    {
      Msize = sizeof(menuArray[mainMenue]) / MCHAR; //Anzahl der Menüeinträge
      if (rotaryCount<1) {
        rotaryCount=Msize-1;
      } //1 da 0 das Mainmenu ist
      if (rotaryCount>Msize-1) {
        rotaryCount=1;
      }
      lcd.print(menuArray[mainMenue][rotaryCount]);
    }
    lcd.setCursor(0,1);
    lcd.print ("Count = "); 
    lcd.print (rotaryCount);
    lcd.print("   ");
    fired = false;
  }  // end if fired


  aktp=digitalRead(4); //Select Knopf
  lcd.setCursor(0,1);
  if (aktp!=lastp) //Wenn sich der Zustand geändert hat
  {
    lastp=aktp; //Letzten Zustand setzen
    if (aktp) //Wenn also neu gedrückt
    {
      if (mainMenue==255) //Wenn noch kein Hauptmenü ausgewählt wurde diese jetzt setzen
      {
        mainMenue=rotaryCount; 
        rotaryCount=1;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(menuArray[mainMenue][rotaryCount]); //Submenü anzeigen
      }
      else
      {
        if (mainMenue  ==0) //Erstes Hauptmenü
        {
          if (rotaryCount==1) //Erstes Submenü wurde ausgewählt
          {
            lcd.print("ausgewählt"); //Aktion zu dem Submenü
          }
        }
      }
    }

  }

}
Non mihi non tibi sed nobis
nightlight ÄT gmx PUNKT de
Benutzeravatar
Rocktagon
Administrator
 
Beiträge: 143
Registriert: So 28. Okt 2012, 10:15
Wohnort: NRW

Zurück zu Arduino

Wer ist online?

Mitglieder in diesem Forum: NewBot und 0 Gäste

Fatal: Not able to open ./cache/data_global.php