Pages: [1] 2 3 ... 10   Go Down
Author Topic: Arduino Uno und Menü für LCD Keypad Shield  (Read 12700 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 71
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo an Alle,

ich bräuchte mal fachkundige Hilfe.

Ich habe ein Arduino Uno R3 und ein LCD Keypad Shield.Nun möchte ich, wenn ich anschalte, ein Menü haben, in welchem ich die aktuelle Uhrzeit einstellen kann und ich diese dann auf dem LCD Displays des Shields ausgeben kann. Zur Bediehnung des Menüs möchte ich die 6 Taster auf dem Shiel benutzen.

Wer kann mir bitte ein fertiges Programm dafür zur Verfügung stellen?

Ich wäre sehr dankbar dafür und würde mich riesig darüber freuen.

Thomas
Logged

Germany
Offline Offline
Edison Member
*
Karma: 47
Posts: 2322
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Eine ganz wichtige Frage blieb ungeklärt: Wieviel zahlst du? smiley-wink

Nee, mal im Ernst. Hier helfen alle gern und opfern ihre Freizeit, um anderen zu helfen. Aber Auftragsarbeiten erledigen ist eigentlich nicht das, was hier angefragt werden sollte.

Wie weit bist du denn schon gekommen, woran hängts denn?
Logged

Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

Offline Offline
God Member
*****
Karma: 10
Posts: 721
42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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... smiley
Logged


Offline Offline
Jr. Member
**
Karma: 1
Posts: 71
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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. :-(
Logged

Offline Offline
God Member
*****
Karma: 10
Posts: 721
42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?


Logged


Cloppenburg
Offline Offline
Edison Member
*
Karma: 30
Posts: 1284
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Nicht Mensch, nicht Tier: Programmierer halt...

Offline Offline
Jr. Member
**
Karma: 1
Posts: 71
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 146
Posts: 3041
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?

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.

Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 71
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 146
Posts: 3041
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

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> 

// 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?
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 71
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 146
Posts: 3041
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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> 

// 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.
Logged

Offline Offline
God Member
*****
Karma: 10
Posts: 721
42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged


Germany S-H
Offline Offline
Faraday Member
**
Karma: 146
Posts: 3041
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

eine komplexe Lösung für ein simples Problem

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.
Logged

Wien
Offline Offline
Edison Member
*
Karma: 28
Posts: 1895
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1] 2 3 ... 10   Go Up
Jump to: