Variable in einem LCD HMI Inkrementieren oder Dekrementieren

Hey Leute,
Ich arbeite gerade an einem HMI, das 3 Dinge machen soll:

Menü 1) Anzeigen der Aktuellen Winkel
Menü 2) Anzeigen des Aktuellen Grenzwinkels
Menü 3) Einstellen des Grenzwinkels (Problem, denn da müssen nicht nur Werte angezeigt werden)

Mein Aufbau des HMI entnahm ich aus diesem Video:

Wenn ich jetzt mit dem Enter Taster in das Menü 3) betrete, will ich mit den Tastern die Variable Inkrementieren und Dekrementieren können.

Könnte mir Jemand dabei helfen wie ich das machen könnte?

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


LiquidCrystal_I2C lcd(0x3F, 16, 2);

int upButton = 10;
int downButton = 11;
int enterButton = 12;
int escapeButton = 13;
int inkButton = 9;
int dekButton = 8;
int inkState = 0;
int inkStateold = 0;
int dekState = 0;
int dekStateold = 0;
int menu = 1;

int Winkelx = 10;
int Winkely = 30;
int Grenzwinkel = 50;

unsigned long previousMillis = 0;
const long interval = 60000;
unsigned long currentMillis = millis();

/*void IRAM_ATTR escape() {  //ESP
menu = 1;
}
*/

void escape() {  //Arduino
menu = 1;
}

void setup() {
lcd.init();
lcd.backlight();
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
pinMode(enterButton, INPUT_PULLUP);
pinMode(escapeButton, INPUT_PULLUP);
updateMenu();
attachInterrupt(digitalPinToInterrupt(escapeButton), escape, FALLING);
}

void loop() {
if (!digitalRead(downButton)) {
  menu++;
  updateMenu();
  delay(100);
  while (!digitalRead(downButton));
}
if (!digitalRead(upButton)) {
  menu--;
  updateMenu();
  delay(100);
  while (!digitalRead(upButton));
}
if (!digitalRead(enterButton)) {
  executeAction();
  updateMenu();
  delay(100);
  while (!digitalRead(enterButton));
}
}

void updateMenu() {
switch (menu) {
  case 0:
    menu = 1;
    break;
  case 1:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(">Angle now");
    lcd.setCursor(0, 1);
    lcd.print(" Limit now");
    break;
  case 2:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(" Angle now");
    lcd.setCursor(0, 1);
    lcd.print(">Limit now");
    break;
  case 3:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(">Set Limit");
    break;
  case 4:
    menu = 3;
    break;
}
}

void executeAction() {
switch (menu) {
  case 1:
    action1(); //Aktueller Winkel ausgeben
    break;
  case 2:
    action2(); //Aktueller Grenzwinkel ausgeben
    break;
  case 3:
    action3(); //Grenzwinkel einstellen
    break;
}
}

void action1() {
lcd.clear();
lcd.print("Winkel X: ");
lcd.print(Winkelx);
lcd.print("\337");
lcd.setCursor(0, 1);
lcd.print("Winkel Y: ");
lcd.print(Winkely);
lcd.print("\337"); // \337 = °
delay(20000);
}
void action2() {
lcd.clear();
lcd.print("Grenzwinkel: ");
lcd.print(Grenzwinkel);
lcd.print("\337");
delay(20000);
}
void action3() {
lcd.clear(); //Grenzwinkel einstellen
lcd.print("Grenzwinkel: ");
lcd.print(Grenzwinkel);
lcd.print("\337");

inkState = digitalRead(inkButton);
if (inkState != inkStateold) {
  if (inkState == HIGH) {
    Grenzwinkel++;
    Serial.println(Grenzwinkel);
  }
  delay(100);
  inkStateold = inkState;
}

dekState = digitalRead(dekButton);
if (dekState != dekStateold) {
  if (dekState == HIGH) {
    Grenzwinkel--;
    Serial.println(Grenzwinkel);
  }
  delay(100);
  dekStateold = dekState;
}
}

Interface.ino (3.04 KB)

Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *). So ist er auch auf portablen Geräten lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Danke für die Info, sorry kenn mich hier noch nicht gut aus.

Was genau möchtest du mit dieser
while (!digitalRead(downButton));"Bremsschleife" erreichen ?

Und wenn dein Sketch richtig laufen soll, musst du dich von den delay() verabschieden.
Die blockieren dein gewünschtes Menü.

Und du solltest mehr Kommentare einbauen, damit auch außenstehende deinen Sketch verstehen.
Ich verstehe ihn noch nicht.

Du musst auch am Anfang des Loop die Tasten für inc und dec abrufen, sie aber nur zur Wirkung bringen, wenn 3 gewählt wurde.

Gruß Tommy

Der Sketch ist nicht original von mir, ich weiß nur dass man durch diesen Tasterdruck die Variable Menü ändert oder eben die Action ausführt.

Delay ist weg :P. Ich möchte halt mit Enter in das Menü hinein und mit Escape hinaus ohne Zeitabhängigkeit.

Könntest du das mithilfe von Code beschreiben also wirksamkeit wenn menu = 3?

danke für die Hilfe

Direkt im loop:

if (menu == 3) {
  // Tastenauswertung und Aktion für inc / dec
}

Gruß Tommy

danke ich werde das mal ausprobieren!
:slight_smile:

Ok ich habs jetzt so eingebaut wie du gesagt hast. Aber ich möchte wirklich sehen wie ich die Variable hochzähle oder verringere. Im Moment gehe ich mit enter in das menu rein und komme direkt wieder hinaus.

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


LiquidCrystal_I2C lcd(0x3F, 16, 2);

int upButton = 10;
int downButton = 11;
int enterButton = 12;
int escapeButton = 13;
int inkButton = 9;
int dekButton = 8;
int inkState = 0;
int inkStateold = 0;
int dekState = 0;
int dekStateold = 0;
int menu = 1;

int Winkelx = 10;
int Winkely = 30;
int Grenzwinkel = 50;

unsigned long previousMillis = 0;
const long interval = 60000;
unsigned long currentMillis = millis();

/*void IRAM_ATTR escape() {  //ESP
  menu = 1;
  }
*/

void escape() {  //Arduino
  menu = 1;
}

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(enterButton, INPUT_PULLUP);
  pinMode(escapeButton, INPUT_PULLUP);
  updateMenu();
  attachInterrupt(digitalPinToInterrupt(escapeButton), escape, FALLING);
}

void loop() {
  dekState = digitalRead(dekButton);
  inkState = digitalRead(inkButton);

  if (menu == 3) {
    if (inkState != inkStateold) {
      if (inkState == HIGH) {
        Grenzwinkel++;
        Serial.println(Grenzwinkel);
      }
      inkStateold = inkState;
    }

    if (dekState != dekStateold) {
      if (dekState == HIGH) {
        Grenzwinkel--;
        Serial.println(Grenzwinkel);
      }
      dekStateold = dekState;
    }
  }

  if (!digitalRead(downButton)) {
    menu++;
    updateMenu();
    while (!digitalRead(downButton));
  }
  if (!digitalRead(upButton)) {
    menu--;
    updateMenu();
    while (!digitalRead(upButton));
  }
  if (!digitalRead(enterButton)) {
    executeAction();
    updateMenu();
    while (!digitalRead(enterButton));
  }
}

void updateMenu() {
  switch (menu) {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(">Angle now");
      lcd.setCursor(0, 1);
      lcd.print(" Limit now");
      break;
    case 2:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" Angle now");
      lcd.setCursor(0, 1);
      lcd.print(">Limit now");
      break;
    case 3:
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(">Set Limit");
      break;
    case 4:
      menu = 3;
      break;
  }
}

void executeAction() {
  switch (menu) {
    case 1:
      action1(); //Aktueller Winkel ausgeben
      break;
    case 2:
      action2(); //Aktueller Grenzwinkel ausgeben
      break;
    case 3:
      action3(); //Grenzwinkel einstellen
      break;
  }
}

void action1() {
  lcd.clear();
  lcd.print("Winkel X: ");
  lcd.print(Winkelx);
  lcd.print("\337");
  lcd.setCursor(0, 1);
  lcd.print("Winkel Y: ");
  lcd.print(Winkely);
  lcd.print("\337"); // \337 = °
  delay(20000);
}
void action2() {
  lcd.clear();
  lcd.print("Grenzwinkel: ");
  lcd.print(Grenzwinkel);
  lcd.print("\337");
  delay(20000);
}
void action3() {
  lcd.clear(); //Grenzwinkel einstellen
  lcd.print("Grenzwinkel: ");
  lcd.print(Grenzwinkel);
  lcd.print("\337");
}

Dann baue Dir weitere Serial.print rein, um Dir Variablenwerte und den Weg Deines Programms anzeigen zu lassen.

Wenn Du mit INPUT_PULLUP arbeitest, dann müssen Deine Taster nach GND schalten und Du musst LOW auswerten.

Gruß Tommy

fabijrk:
Der Sketch ist nicht original von mir, ich weiß nur dass man durch diesen Tasterdruck die Variable Menü ändert oder eben die Action ausführt.
.....

Dann solltest du mal einen Link posten, wo du den kopiert hast.
Dann können wir evtl. vergleichen und einen Fehler erkennen.

Ich habe das Video verlinkt wo ich ihn her habe...

fabijrk:
Ich habe das Video verlinkt wo ich ihn her habe...

Du hast eine URL geschrieben. Einen Link kann man anklicken, was besonders für User mit mobilen Geräten sinnvoll ist.

Gruß Tommy

Kann ich mit irgendeiner Funktion in dem Menu 3 Action bleiben bis ich wieder Enter drücke?

fabijrk:
Ich habe das Video verlinkt wo ich ihn her habe...

Und da gibt es einen Download.....oder hast du abgetippt ?

Da hast du den LINK zu dem CODE
War übrigens in der Beschreibung :wink: