Arduino Uno und Menü für LCD Keypad Shield

aber wenn du magst, können wir das hier schritt für schritt machen - du machst den anfang, wir korrigieren falls nötig. So hast du dann auch noch etwas gelernt... :slight_smile:

Hallo, danke für die Antworten.

Mit Schritt für Schritt wäre schön, doch leider habe ich noch keinen Plan, wie ich so ein Menü überhaupt erstelle bzw. bei der Erstellung vorgehen muss. :frowning:

Mir fehlen immer noch die Basics: hast du das Shield schon ausprobiert, funktionieren die Tasten bzw. das Display und hast schonmal irgentetwas probehalber damit programmiert?

Hier hat schon jemand was gemacht: http://arduino.cc/forum/index.php/topic,73816.0.html

Das shield funktioniert und die Tasten gehen auch, habe ich alles anhand von testprogrammen probiert. Momentan läuft auch eine Uhr darauf, doch leider muss ich zum stellen dieser immer das arduino an den PC hängen und dann anhand von dem Programm die Uhrzeit stellen. Da die Uhr aber in Zukunft mobil sein soll und ich nicht immer den Laptop mitnehmen will, möchte ich die Uhrzeit über ein Menü stellen können.

Danke für den Tip, von dem welcher sich schon mal daran versucht hat. Ich weis nur nicht, was ich mit den einzelnen Programmteilen anfangen soll? Muss ich sie alle hintereinander kopieren oder was muss ich damit tun?

Musikhai:
Momentan läuft auch eine Uhr darauf, doch leider muss ich zum stellen dieser immer das arduino an den PC hängen und dann anhand von dem Programm die Uhrzeit stellen.

Was verwendest Du für die Uhr, die "Time"-Library?

Musikhai:
Da die Uhr aber in Zukunft mobil sein soll und ich nicht immer den Laptop mitnehmen will, möchte ich die Uhrzeit über ein Menü stellen können.

Mal als Info: Wenn Du in der Anzeige (oder einem Teil der Anzeige) nur eine Uhr laufen haben möchtest und die Tasten des Shield (das hat ja reichlich davon) nur zum Stellen der Uhr verwendet werden sollen, dann brauchst Du überhaupt kein Menü, dann reicht folgende simple Logik im Programm-Sketch:

  • immer wenn der Links-Button gedrückt wird: Stelle die Minute um 1 zurück
  • immer wenn der Rechts-Button gedrückt wird: Stelle die Minute um 1 vor
  • immer wenn der Oben-Button gedrückt wird: Stelle die Stunde um 1 vor
  • immer wenn der Unten-Button gedrückt wird: Stelle die Stunde um 1 zurück

Würde Dir sowas schon ausreichen?

Die nächste Stufe, wenn Du die Tasten auch noch für andere Funktionen haben möchtest, wäre den "Select-Button" hinzuzunehmen. Dann könntest Du mit "Select" zwischen "Normalbetrieb" und "Zeiteinstellung" (und ggf. noch anderen Funktionen umschalten), und die anderen Tasten würden die Uhr nur dann verstellen, wenn Du vorher mit "Select" auf "Zeiteinstellung" umgeschaltet hast.

Komplette full-featured Menüs mit allem Klimbim und Einstell- und freien Editiermöglichkeiten sind viel schwieriger zu realisieren als das.

ja ich verwende für die Uhr die Time-Library.

Das mit dem Menü wäre schön, wenn ich es über den Select-Button steuern würde. So wie du beschrieben hast, "select" drücken und dann in einen Menü-Punkt zur Uhrzeiteinstellung springen.
Möchte den Arduino nämlich zu Temperaturerfassung verwenden und die Daten dann auf SD-Karte spreichern um sie später per Excel auszuwerten.

Musikhai:
Möchte den Arduino nämlich zu Temperaturerfassung verwenden und die Daten dann auf SD-Karte spreichern um sie später per Excel auszuwerten.

Eine Zeiteinstellfunktion ist dazu natürlich nicht falsch.

Aber damit der Arduino nach dem Einschalten schon "eine ziemlich genaue Zeit" bekommt, macht man es normalerweise so, daß wie bei einem PC eine kleine Echtzeituhrenplatine mit Pufferbatterie angeschlossen wird. Beim Starten holt sich der Arduino dann die aktuelle Uhrzeit aus dem Uhrenmodul.

/******************************************************************
 * Clock and clock adjust demo by "jurs" for German Arduino Forum *
 * Hardware required: keypad shield
 * Additional library required: Time library must be installed 
 ******************************************************************/

#include <LiquidCrystal.h>
#include <Time.h>  

// Select the pins used on the LCD panel:
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Define some values used by the LCD panel and buttons:
enum keypadButtons {btnNONE, btnSELECT, btnLEFT, btnRIGHT, btnDOWN, btnUP };

int readPadButtons()
// read the buttons from analog interface:
// returns the key currently pressed
// do not call this function directly from the sketch!
{
  int adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE;
  if (adc_key_in < 50)   return btnRIGHT; 
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...
}


#define DEBOUNCETIME 10

int buttonPressed()
// this function returns true only once per single button pressed
// use this function in your program sketch
{
  static boolean buttonFired;
  static long buttonDownSince;
  int State=readPadButtons();
  if (State==btnNONE)  
  { // this button is not pressed at this time
    buttonFired=false;
    buttonDownSince=0;
  }
  else if (buttonDownSince==0)
  { // button is pressed but DEBOUNCETIME did not yet started counting
    buttonFired=false;
    buttonDownSince=millis();
  }
  if (millis()-buttonDownSince>=DEBOUNCETIME && buttonFired==false)
  { // button is pressed and DEBOUNCETIME passed, so fire the button
    buttonFired=true;
    return(State); // return button 
  }  
  return(btnNONE); // no button fired this time
}




void setup()  
{
  Serial.begin(9600);           // set serial interface to 9600 baud
  lcd.begin(16, 2);             // starts the LCD display (2 lines by 16 chars)
  setTime(1357002000);          // set some initial time
}


boolean inMenu; // global variable to hold the menu status

void  updateDisplay()
// this function updates the display (time and menu status)
{
  char time[10];
  sprintf(time,"%02d:%02d:%02d",hour(),minute(),second());
  lcd.setCursor(0,0);
  lcd.print(time);
  lcd.setCursor(0,1);
  if (inMenu)
    lcd.print(F("Zeit einstellen"));
  else  
    lcd.print(F("Normalbetrieb  "));
}


void checkForNewSecond()
// function will update the display once per second
{
  static long lastsecond;
  if (lastsecond!=now())
  {
    updateDisplay();
    lastsecond=now();
  }  
}


void handleMenuButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(now()+3600);
      break;
    }
    case btnLEFT:
    {
      setTime(now()-3600);
      break;
    }
    case btnUP:
    {
      setTime(now()+60);
      break;
    }
    case btnDOWN:
    {
      setTime(now()-60);
      break;
    }
  }
}

void handleNormalButton(int button)
{
  // nothing yet
}


void handleButtons()
// Abfrage ob eine Taste gedrückt wurde
// Umschaltung des Menüstatus
// Falls im Zeiteinstellmenü, Funktion zur Behandlung der Tasten im Einstellmenü aufrufen
// Falls im Normalbetrieb, Funktion zur Behandlung der Tasten im Normalbetrieb aufrufen
{
  int curButton;
  curButton=buttonPressed();
  if (curButton==btnNONE) return; // nothing to do if no button is pressed
  else if (curButton==btnSELECT) inMenu=!inMenu;  // switch menu status
  else if (inMenu) handleMenuButton(curButton); // gedrückte Tasten im Einstellmenü behandeln
  else handleNormalButton(curButton); // gedrückte Tasten sonst behandeln
  updateDisplay();  
}


void loop()
{
  checkForNewSecond();      // einmal pro Sekunde das Display updaten
  handleButtons();
}

Per "Select" Button wird zwischen Zeiteinstellung und Normalbetrieb umgeschaltet.

Reicht es Dir, nur die Zeit einstellen zu können und das Datum ist egal und kann irgendwann sein? Oder brauchst Du auch noch erweiterte Möglichkeiten, um nicht nur Stunden und Minuten, sondern auch noch Tag, Monat und Jahr einstellen zu können?

Danke schon mal an dich!

Nur die Zeit reicht mir leider nicht. Ich möchte die Zeit (Stunden, Minuten, Sekunden) und das Datum (Tag, Monat, Jahr) einstellen können, damit wie ich schon beschrieben habe, das komplett auf der SD karte gespeichert werden kann wegen der Auswertung im Nachhinein.

Musikhai:
Danke schon mal an dich!

Nur die Zeit reicht mir leider nicht. Ich möchte die Zeit (Stunden, Minuten, Sekunden) und das Datum (Tag, Monat, Jahr) einstellen können, damit wie ich schon beschrieben habe, das komplett auf der SD karte gespeichert werden kann wegen der Auswertung im Nachhinein.

Dann hier eine erweiterte Version, mit der Du nacheinander mit dem SELECT Button umschalten kannst zwischen:

  • Normalbetrieb
  • Zeit einstellen (rechts/links Stunde, up/down Minute)
  • Datum einstellen (rechts/links Monat, up/down Tag)
  • Jahr einstellen
/******************************************************************
 * Clock and clock adjust demo by "jurs" for German Arduino Forum *
 * Hardware required: keypad shield
 * Additional library required: Time library must be installed 
 ******************************************************************/

#include <LiquidCrystal.h>
#include <Time.h>  

// Select the pins used on the LCD panel:
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Define some values used by the LCD panel and buttons:
enum keypadButtons {btnNONE, btnSELECT, btnLEFT, btnRIGHT, btnDOWN, btnUP };
enum menuStates {menuNONE, menuTIME, menuDATE, menuYEAR};

int readPadButtons()
// read the buttons from analog interface:
// returns the key currently pressed
// do not call this function directly from the sketch!
{
  int adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE;
  if (adc_key_in < 50)   return btnRIGHT; 
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...
}


#define DEBOUNCETIME 10

int buttonPressed()
// this function returns true only once per single button pressed
// use this function in your program sketch
{
  static boolean buttonFired;
  static long buttonDownSince;
  int State=readPadButtons();
  if (State==btnNONE)  
  { // this button is not pressed at this time
    buttonFired=false;
    buttonDownSince=0;
  }
  else if (buttonDownSince==0)
  { // button is pressed but DEBOUNCETIME did not yet started counting
    buttonFired=false;
    buttonDownSince=millis();
  }
  if (millis()-buttonDownSince>=DEBOUNCETIME && buttonFired==false)
  { // button is pressed and DEBOUNCETIME passed, so fire the button
    buttonFired=true;
    return(State); // return button 
  }  
  return(btnNONE); // no button fired this time
}




void setup()  
{
  Serial.begin(9600);           // set serial interface to 9600 baud
  lcd.begin(16, 2);             // starts the LCD display (2 lines by 16 chars)
  setTime(1357002000);          // set some initial time
}


int menuState; // global variable to hold the menu status

void  updateDisplay()
// this function updates the display (time and menu status)
{
  char lcdline[17];
  sprintf(lcdline,"%02d:%02d:%02d",hour(),minute(),second());
  lcd.setCursor(0,0);
  lcd.print(lcdline);
  lcd.setCursor(0,1);
  if (menuState==menuTIME)
    lcd.print(F("Zeit einstellen "));
  else if (menuState==menuDATE)
  {
    lcd.print(F("Datum: "));
    sprintf(lcdline,"%02d.%02d.   ",day(),month());
    lcd.print(lcdline);
  }  
  else if (menuState==menuYEAR)
  {
    lcd.print(F("Jahr: "));
    sprintf(lcdline,"%04d      ",year());
    lcd.print(lcdline);
  }  
  else  
    lcd.print(F("Normalbetrieb   "));
}


void checkForNewSecond()
// function will update the display once per second
{
  static long lastsecond;
  if (lastsecond!=now())
  {
    updateDisplay();
    lastsecond=now();
  }  
}


void handleMenuTimeButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(now()+3600);
      break;
    }
    case btnLEFT:
    {
      setTime(now()-3600);
      break;
    }
    case btnUP:
    {
      setTime(now()+60);
      break;
    }
    case btnDOWN:
    {
      setTime(now()-60);
      break;
    }
  }
}

void handleMenuDateButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    {
      setTime(hour(),minute(),second(),day(),month()+1,year());
      break;
    }
    case btnLEFT:
    {
      setTime(hour(),minute(),second(),day(),month()-1,year());
      break;
    }
    case btnUP:
    {
      setTime(hour(),minute(),second(),day()+1,month(),year());
      break;
    }
    case btnDOWN:
    {
      setTime(hour(),minute(),second(),day()-1,month(),year());
      break;
    }
  }
}

void handleMenuYearButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
  switch (button)
  {
    case btnRIGHT:
    case btnUP:
    {
      if (year()<2038)
        setTime(hour(),minute(),second(),day(),month(),year()+1);
      break;
    }
    case btnLEFT:
    case btnDOWN:
    {
      if (year()>2000)
        setTime(hour(),minute(),second(),day(),month(),year()-1);
      break;
    }
  }
}



void handleNormalButton(int button)
{
  // nothing yet
}


void handleButtons()
// Abfrage ob eine Taste gedrückt wurde
// Umschaltung des Menüstatus
// Falls im Zeiteinstellmenü, Funktion zur Behandlung der Tasten im Einstellmenü aufrufen
// Falls im Normalbetrieb, Funktion zur Behandlung der Tasten im Normalbetrieb aufrufen
{
  int curButton;
  curButton=buttonPressed();
  if (curButton==btnNONE) return; // nothing to do if no button is pressed
  else if (curButton==btnSELECT) // switch menu status
  {
    if (menuState==menuNONE) menuState=menuTIME;  
    else if (menuState==menuTIME) menuState=menuDATE;  
    else if (menuState==menuDATE) menuState=menuYEAR;
    else menuState=menuNONE;
  }
  else if (curButton!=btnNONE) // falls eine Taste gedrückt wurde
  {
    if (menuState==menuTIME) handleMenuTimeButton(curButton);  // Zeit einstellen
    else if (menuState==menuDATE) handleMenuDateButton(curButton);  // Datum einstellen
    else if (menuState==menuYEAR) handleMenuYearButton(curButton);  // Jahr einstellen
    else handleNormalButton(curButton); // gedrückte Tasten sonst behandeln
  }
  updateDisplay();  
}


void loop()
{
  checkForNewSecond();      // einmal pro Sekunde das Display updaten
  handleButtons();
}

Vielleicht nützt es Dir auch was, falls Du zum Zwischenpuffern der Zeit bei ausgeschaltetem Arduino doch noch ein Uhrenmodul installierst und die Einstellmöglichkeit dann nur zum Nachstellen der Zeit benötigst.

Und er tut es schon wieder... eine komplexe Lösung für ein simples Problem - super sauber ausgeführt und dokumentiert, allerdings mit Null Eigenleistung des Threadstarters

Simples Problem?

Dann gibt's vielleicht auch eine simplere Lösung als das, was ich gepostet habe?

Immer her mit den simplen Lösungen für "simple" Probleme, ich lerne selbst gerne noch was!

Ich finde, die Shield-Anbieter lassen Programmieranfänger ganz schön im Regen stehen, indem sie für ihre von der Hardware her eigentlich recht leistungsfähigen Shields teilweise nur dümmlichste und kaum für irgendwas brauchbare Demoprogramme anbieten. Zum Keypad-Shield wird nicht mal eine Funktion wie die oben von mir gepostete "buttonPressed()" Funktion gezeigt, die bei laufender Abfrage immer genau zu einem Tastendruck auch einmal einen Rückgabecode zurückliefert.

Das ist eine absolute Schande.

Meine Meinung: Wenn Anfänger überhaupt keine Ahnung haben, wie irgendein Problem angepackt werden kann und Hardwareanbieter zu ihren Shields keine brauchbaren Demoprogramme mitliefern, dann kann ein Anfänger aus dem funktionierendem Code eines erfahreneren Programmierers sicher mindestens genau so viel lernen als wenn er sich selbst völlig planlos irgendwas zusammenstümpert, das dann vielleicht oder vielleicht auch nicht funktioniert.

hi,

musikhai wollte eine fertige lösung, jurs hat's spaß gemacht, sie zu liefern.
wo ist das problem?
wir sind doch hier nicht die lehrer einer schule, die jemandem etwas beibringen müssen.

traurig an der sache find' ich viel mehr, daß jurs unbedingt englisch dokumentieren will.
"Clock and clock adjust demo by "jurs" for German Arduino Forum" ist doch jenseitig.

gruß stefan

Eisebaer:
traurig an der sache find' ich viel mehr, daß jurs unbedingt englisch dokumentieren will.
"Clock and clock adjust demo by "jurs" for German Arduino Forum" ist doch jenseitig.

Hi Eisebaer,

das finde ich nicht. Wer sich auch nur halbwegs ernsthaft mit Arduino und programmieren beschäftigt, kommt früher oder später um ein bissl Englisch nicht drumrum. Und so kann jurs ggf. auch im englischen Forum weiterhelfen, ohne den Code neu kommentieren zu müssen.
Ich finde das legitim und mache es selbst auch so.

Beste Grüße

Helmuth

Wer sich auch nur halbwegs ernsthaft mit Arduino und programmieren beschäftigt kommt früher oder später um ein bissl Englisch nicht drumrum.

Seh ich genauso. Ich habe durch das Programmieren mit Xcode etwas English gelernt. Natürlich gehts auch ohne English, nur sehr mühsam.

Hallo an Alle.

Vielen dank an dich Jurs. Ich bin zwar heute noch nicht zum ausprobieren gekommen, doch das werde ich morgen sofort nachholen.
Ich stimme dir voll zu, dass man von den Shiel-Anbietern total im Regen stehen gelassen wird. So toll wie die Shields sind, bleibt man als Neuling im Regen stehen.
Es wäre schön, wenn ich zu gegebner Zeit noch einmal deine Hilfe in Anspruch nehmen könnte, denn das nächste Problem wird sicherlich die Speicherung der Daten auf SD Karte werden. Doch eins nach dem anderen. wie gesagt werde morgen dein Programm testen.

Also vielen Dank noch mal und bis Morgen dann

Hallo Jurs,

habe gerade dein Script ausprobiert und funktioniert gut. Nun habe ich es etwas verändert. Z.B. das dort wo du "normalbetrieb" stehen hast , ich jetzt das Datum stehen habe. Desweiteren habe ich dein Script so verändert, dass 2 Dallas Themperatursensoren DS18B20 ausgelesen werden und gleichzeitig mit der Uhrzeit und dem Datum angezeigt werden.

Wie bekomme ich jetzt das Script hier reinkopiert, so dass du es auch sehen kannst?

Könntest du das Script dann so verändern, dass beim einschalten des Arduino ich in ein Menü komme, wo ich zwischen Anzeige ( Anzeige von Zeit, Datum, Werte der Temperturfühler) (sollte so aussehen wie es jetzt läuft) und Setup (Einstellen der Uhr und des Datums) wählen kann. Wäre ganz toll, wenn du mir bei der Programierung wieder behilflich sein könntest.

Danke schon mal im voraus.

Musikhai

Musikhai:
Wie bekomme ich jetzt das Script hier reinkopiert, so dass du es auch sehen kannst?

Code kannst Du hier im Forum zwischen zwei Code-Tags einkopieren. Schema:

(code)
Hier Dein Code
(/code)

Nur mußt Du dafür die ECKIGEN Klammern [] anstelle der runden Klammern verwenden.

Musikhai:
Könntest du das Script dann so verändern, dass beim einschalten des Arduino ich in ein Menü komme, wo ich zwischen Anzeige ( Anzeige von Zeit, Datum, Werte der Temperturfühler) (sollte so aussehen wie es jetzt läuft) und Setup (Einstellen der Uhr und des Datums) wählen kann. Wäre ganz toll, wenn du mir bei der Programierung wieder behilflich sein könntest.

Na ja, ich gebe ja gerne Schwimmhilfe, aber irgendwann müßtest Du auch selbst den Freischwimmer machen. Oder wenigstens das Seepferdchen.

In das Einstellmenü kommst Du nicht nur beim Programmstart, sondern JEDERZEIT durch Drücken des SELECT Buttons auf dem Shield. Falls Du eine Merkhilfe benötigst, dass nach dem Start die Zeit noch nicht gestellt wurde, kannst Du dafür eine globale Variable deklarieren, z.B.:
boolean timeIsSet=false;

Diese Variable könntest Du nutzen, um z.B. eine modifizierte Normalanzeige zu machen, aus der man erkennt, dass die Zeit noch nicht gesetzt wurde. Z.B.
if (!timeIsSet) ==> Code zum Ausgeben der Zeit als ##:##:## statt 11:23:47

Und sobald die Zeiteinstellroutine verlassen wird, setzt Du timeIsSet für den Rest des Programmablaufs auf true.
Dann kannst Du bei einem Datenlogger auch vermeiden, dass schon Datenzeilen geloggt werden, während die Zeit noch gar nicht gestellt worden ist. Also den Datenlogger erst ab dem Zeitpunkt loggen lassen, ab dem eine eingestellte Zeit vorliegt:
if (timeIsSet) ==> Code zum Loggen von Daten

Die genaue Programmlogik richtet sich nach dem, was der Sketch können soll.

Und wie gesagt: Normalerweise bekommt ein autonomes Gerät ein kleines Uhrenmodul mit Knopfzelle, so dass die Zeit auch bei ausgeschaltetem Gerät weiterläuft. beim Programmstart wird die Zeit aus dem Uhrenmodul gelesen, und eine Einstellroutine wird nur benötigt, wenn Gangabweichungen der Uhr ausgeglichen werden sollen (bei DS1307 durchaus bis zu 2 Minuten pro Monat). Oder wenn man keine vernünftige Sommer-/Winterzeitumstellung programmiert bekommt, beim Umstellen von Winter- auf Sommerzeit und umgekehrt.

Wie genau Arduino-Boards mit ihrem 16 MHz Takt laufen, das hängt von der Bauweise des Boards ab und ob ein Schwingquarz oder nur ein Resonator verbaut ist, sowie von den Temperaturbedingungen beim Betrieb. Mit dem 16 MHz Systemtakt und der Time-Library kann es ohne Nachstellen der Uhr durchaus zu deutlich höheren Gangabweichungen kommen als mit einem DS1307 Uhrenmodul.

Hier mein Sketch vom Menü. Da kann man zwar auch Zeit/Datum einstellen, habs aber nicht fertig bekommen. http://pastebin.com/34trMagQ

Hier mal mein Script. Bitte Jurs schau mal drüber und vielleicht macht es ja keine große Mühe das umprogramieren:

(code)
/******************************************************************

  • Clock and clock adjust demo by "jurs" for German Arduino Forum *
  • Hardware required: keypad shield
  • Additional library required: Time library must be installed
    ******************************************************************/

#include <LiquidCrystal.h>
#include <Time.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2

// Select the pins used on the LCD panel:
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Define some values used by the LCD panel and buttons:
enum keypadButtons {btnNONE, btnSELECT, btnLEFT, btnRIGHT, btnDOWN, btnUP };
enum menuStates {menuNONE, menuTIME, menuDATE, menuYEAR};

int readPadButtons()
// read the buttons from analog interface:
// returns the key currently pressed
// do not call this function directly from the sketch!
{
int adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
return btnNONE; // when all others fail, return this...
}

#define DEBOUNCETIME 10

int buttonPressed()
// this function returns true only once per single button pressed
// use this function in your program sketch
{
static boolean buttonFired;
static long buttonDownSince;
int State=readPadButtons();
if (State==btnNONE)
{ // this button is not pressed at this time
buttonFired=false;
buttonDownSince=0;
}
else if (buttonDownSince==0)
{ // button is pressed but DEBOUNCETIME did not yet started counting
buttonFired=false;
buttonDownSince=millis();
}
if (millis()-buttonDownSince>=DEBOUNCETIME && buttonFired==false)
{ // button is pressed and DEBOUNCETIME passed, so fire the button
buttonFired=true;
return(State); // return button
}
return(btnNONE); // no button fired this time
}

void setup()
{
Serial.begin(9600); // set serial interface to 9600 baud
lcd.begin(16, 2); // starts the LCD display (2 lines by 16 chars)
setTime(1357002000); // set some initial time
}

int menuState; // global variable to hold the menu status

void updateDisplay()
// this function updates the display (time and menu status)
{
char lcdline[17];
sprintf(lcdline,"%02d:%02d:%02d",hour(),minute(),second());
lcd.setCursor(0,0);
lcd.print(lcdline);
lcd.setCursor(0,1);
if (menuState==menuTIME)
lcd.print(F("Zeit einstellen "));
else if (menuState==menuDATE)
{
lcd.print(F("Datum: "));
sprintf(lcdline,"%02d.%02d. ",day(),month());
lcd.print(lcdline);
}
else if (menuState==menuYEAR)
{
lcd.print(F("Jahr: "));
sprintf(lcdline,"%04d ",year());
lcd.print(lcdline);
}
else
// lcd.print(F("Normalbetrieb "));
printZiffernGenulltOhnePunkt(day());
lcd.print(".");
printZiffernGenulltOhnePunkt(month());
lcd.print(".");

}

void checkForNewSecond()
// function will update the display once per second
{
static long lastsecond;
if (lastsecond!=now())
{
updateDisplay();
lastsecond=now();
}
}

void handleMenuTimeButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
switch (button)
{
case btnRIGHT:
{
setTime(now()+3600);
break;
}
case btnLEFT:
{
setTime(now()-3600);
break;
}
case btnUP:
{
setTime(now()+60);
break;
}
case btnDOWN:
{
setTime(now()-60);
break;
}
}
}

void handleMenuDateButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
switch (button)
{
case btnRIGHT:
{
setTime(hour(),minute(),second(),day(),month()+1,year());
break;
}
case btnLEFT:
{
setTime(hour(),minute(),second(),day(),month()-1,year());
break;
}
case btnUP:
{
setTime(hour(),minute(),second(),day()+1,month(),year());
break;
}
case btnDOWN:
{
setTime(hour(),minute(),second(),day()-1,month(),year());
break;
}
}
}

void handleMenuYearButton(int button)
// we are in time setting menu and react on pressed button
// by changing the time
{
switch (button)
{
case btnRIGHT:
case btnUP:
{
if (year()<2038)
setTime(hour(),minute(),second(),day(),month(),year()+1);
break;
}
case btnLEFT:
case btnDOWN:
{
if (year()>2000)
setTime(hour(),minute(),second(),day(),month(),year()-1);
break;
}
}
}

void handleNormalButton(int button)
{
// nothing yet
}

void handleButtons()
// Abfrage ob eine Taste gedrückt wurde
// Umschaltung des Menüstatus
// Falls im Zeiteinstellmenü, Funktion zur Behandlung der Tasten im Einstellmenü aufrufen
// Falls im Normalbetrieb, Funktion zur Behandlung der Tasten im Normalbetrieb aufrufen
{
int curButton;
curButton=buttonPressed();
if (curButton==btnNONE) return; // nothing to do if no button is pressed
else if (curButton==btnSELECT) // switch menu status
{
if (menuState==menuNONE) menuState=menuTIME;
else if (menuState==menuTIME) menuState=menuDATE;
else if (menuState==menuDATE) menuState=menuYEAR;
else menuState=menuNONE;
}
else if (curButton!=btnNONE) // falls eine Taste gedrückt wurde
{
if (menuState==menuTIME) handleMenuTimeButton(curButton); // Zeit einstellen
else if (menuState==menuDATE) handleMenuDateButton(curButton); // Datum einstellen
else if (menuState==menuYEAR) handleMenuYearButton(curButton); // Jahr einstellen
else handleNormalButton(curButton); // gedrückte Tasten sonst behandeln
}
updateDisplay();
}

void printZiffernGenulltOhnePunkt(int zahl) // definieren Subroutine
{
// verschoenern Anzeige, indem wir ...
if(zahl < 10) // wenn kleiner als 10 ...
{
Serial.print("0"); // fuehrende 0 einfuegen
lcd.print("0"); // fuehrende 0 einfuegen
}
Serial.print(zahl); // Ausgabe auf serieller Konsole
lcd.print(zahl); // Ausgabe auf LCD
}

void printZiffernGenulltmitPunkt(int zahl) // definieren Subroutine
{
// verschoenern Anzeige, indem wir ...
Serial.print(":"); // trennende ":" einfuegen
lcd.print(":"); // trennende ":" einfuegen
if(zahl < 10) // wenn kleiner als 10 ...
{
Serial.print('0'); // fuehrende 0 einfuegen
lcd.print("0");
}
Serial.print(zahl); // Ausgabe auf serieller Konsole
lcd.print(zahl);
}

void loop()
{
sensors.requestTemperatures();
lcd.setCursor(11, 0);
//lcd.print("0: ");
lcd.print(sensors.getTempCByIndex(0));
// lcd.print("C");

lcd.setCursor(11, 1);
// lcd.print("1: ");
lcd.print(sensors.getTempCByIndex(1));
// lcd.print("C");

checkForNewSecond(); // einmal pro Sekunde das Display updaten
handleButtons();
}

(/Code)

Danke dir schon mal.

Musikhai