Problem mit Drucktasten im Techniker-Modus

Hallo,

ich habe ein Problem mit den Drucktasten im Techniker-Modus.
Wenn ich auf Techniker-Modus umschalte, und die Drucktasten (key_up oder key_down) betätige, wird nicht gleich die Taste betätigen. Also manchmal vom ersten Klick erhöht/verringert sich die Zahlen und manchmal nach 2/3 Klicken.
Das Problem liegt an das Programm und nicht im technischen Bereich.
Das Programm habe ich auch hochgeladen.

Ich bitte um die Erklärung
Vielen Dank im Voraus

Programm.ino (8.36 KB)

matrixsy:
Ich bitte um die Erklärung

Wer hat das Programm geschrieben? Den Stil möchte ich eigenwillig nennen.

Teil 1:

#include <LiquidCrystal.h>
#include<EEPROM.h>
#define ROW_NUM 2
#define COL_NUM 16
int index = 0;
#define INDEX_MAX (COL_NUM * ROW_NUM)
#define ROW(x) (x / COL_NUM)
#define COL(x) (x % COL_NUM)
#define pwm_pin  21
#define Mag_Pin 20

int count;
unsigned long st;
bool changeing = 1;
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

union date_num
{
  int int_num;
  byte byte_num[4];
};

date_num  now_wasser;
date_num  target_wasser;
date_num  pwm_num;


class key
{
  public:
    begin(byte A)
    {
      this->pin = A;
      pinMode(pin, INPUT_PULLUP);
    }
    bool is_click()//Stellen Sie fest, ob der Tastschalter gedrückt ist
    {
      if (digitalRead(pin) == 0)
      {
        delay(10);
        if (digitalRead(pin) == 0)
          return 1;

        else
          return 0;
      }

      else
        return 0;
    };
  private:
    byte pin;
};

key key_start;//Beginn
key key_up;//Plus
key key_down;//Minus
key key_enter;//sicher_Anwender
key key_change_mode;//on,off_ Druckschalter
key key_enter1;//sicher_Techniker

//Anwender...
void run_mode()
{
  lcd.setCursor(0, 0);
  lcd.print("Wassertank");
  lcd.setCursor(0, 1);
  lcd.print("konnektiert?");
  while (1)
  {
    if (key_start.is_click() == 1)// Ob der Tastschalter gedrückt wird
    {
      while (key_start.is_click());// Wenn der Tastschalter gedrückt wird, wird das Programm geschlossen
      break;
    }
  }
  lcd.clear();

  lcd.setCursor(0, 0);
  lcd.print("Wasser soll:" + String(target_wasser.int_num) + "L   ");
  lcd.setCursor(0, 1);
  lcd.print("Wasser ist:");
  while (1)//Endlosbetrieb
  {

    bool click = 0;
    if (click)
    {
      lcd.setCursor(12, 0);
      lcd.print(target_wasser.int_num);
      lcd.print("  ");
    }

    if (key_enter.is_click() == 1) //Beginn
      pinMode(20, HIGH);
    break;
  }
  st = millis();
  int i = 0;
  unsigned long st = millis();
  attachInterrupt(2, count_pwm, FALLING);//Unterbrechungsfunktion
  while (1)
  {
    if (millis() - st >= 500)
    {
      pinMode(20, HIGH);
      st = millis();
      lcd.setCursor(12, 0);
      lcd.print(target_wasser.int_num);
      lcd.setCursor(11, 1);
      lcd.print(now_wasser.int_num);
      lcd.println("L     ");
    }
    if (target_wasser.int_num == now_wasser.int_num)
    {
      pinMode(20, LOW
             );
      detachInterrupt(2);//Unterbrechnungsfunktion schließen
      lcd.setCursor(12, 0);
      lcd.print(target_wasser.int_num);
      lcd.setCursor(11, 1);
      lcd.print(now_wasser.int_num);
      while (1)
      {
        if (key_start.is_click() == 1)
        {
          while (key_start.is_click());
          break;
        }
      }
      break;
    }
  }
  lcd.clear();


  lcd.setCursor(0, 0);
  lcd.print("Wasser ist:" + String(now_wasser.int_num) + "L   ");
  lcd.setCursor(0, 1);
  lcd.print("Wassertank dekonnetiert?");
  st = millis();
  i = 0;
  while (1)
  {
    if (key_start.is_click() == 1)
    {
      while (key_start.is_click());
      break;
    }
    if (millis() - st >= 500)
    {
      st = millis();
      lcd.scrollDisplayLeft();
      i++;
      if (i >= 40)
      {
        lcd.setCursor(0, 0);
        lcd.print("Wasser ist:" + String(now_wasser.int_num) + "L   ");
        lcd.setCursor(0, 1);
        lcd.print("Wassertank dekonnetiert?");
        i = 0;
      }
    }
  }
  lcd.clear();
}

Teil 2:

//Techniker...


void change_mode()// on/off Druckschalter
{
  Serial.begin(9600);

  while (1)
  {
    lcd.setCursor(0, 0);
    lcd.print("Parament aendern?");
    lcd.setCursor(0, 1);
    lcd.print("OK");
    while (key_enter1.is_click() != 1);
    lcd.clear();

    lcd.setCursor(0, 0);
    lcd.print("Wasser soll:" + String(target_wasser.int_num) + "L   ");
    lcd.setCursor(0, 1);
    lcd.print("OK");
    while (key_enter1.is_click() == 1);
    while (1)
    {
      bool click = 0;
      if (key_up.is_click() == 1)
      {
        target_wasser.int_num++;//Plus
        click = 1;
      }

      if (key_down.is_click() == 1)
      {
        target_wasser.int_num--;//Minus
        click = 1;
      }

      if (click)
      {
        if (target_wasser.int_num < 0)
          target_wasser.int_num = 0;
        for (int i = 10; i < 14; i++) //int target_wasser.int_num = 520 (Dezimalsystem) ---- 0010 0000 1000 (Zwweizahlensystem)
          EEPROM.write(i, target_wasser.byte_num[i - 10]);

        lcd.clear();

        lcd.setCursor(0, 0);
        lcd.print("Wasser soll:" + String(target_wasser.int_num) + "L   ");
        lcd.setCursor(0, 1);
        lcd.print("OK");
      }
      if (key_enter1.is_click()) break;

      while (key_up.is_click() || key_down.is_click()) ; //Wenn Impuls oder Minus-Drucktaster gedrückt wird
    }

    while (key_enter1.is_click());
    lcd.clear();


    lcd.setCursor(0, 0);
    lcd.print("Impulse soll:" + String(pwm_num.int_num) + "   ");
    lcd.setCursor(0, 1);
    lcd.print("OK");
    while (1)
    {
      bool click = 0;
      if (key_up.is_click() == 1)
      {
        pwm_num.int_num++;
        click = 1;
      }

      if (key_down.is_click() == 1)
      {
        pwm_num.int_num--;
        click = 1;
      }

      if (click)
      {
        if (pwm_num.int_num < 0)
          pwm_num.int_num = 0;
        for (int i = 14; i < 18; i++) //int pwm_num.int_num= 475 (01 1101 1011)
          EEPROM.write(i, pwm_num.byte_num[i - 14]); //schreiben
        lcd.clear();
        Serial.print(pwm_num.int_num);

        lcd.setCursor(0, 0);
        lcd.print("Impulse soll:" + String(pwm_num.int_num) + "   ");
        lcd.setCursor(0, 1);
        lcd.print("OK");
      }
      if (key_enter1.is_click()) break;
      while (key_up.is_click() || key_down.is_click()) ;
    }

    while (key_enter1.is_click());

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Programm beenden?");
    lcd.setCursor(0, 1);
    lcd.print("OK?");

    bool finish = 0;//false
    while (1)
    {
      if (key_enter1.is_click())
      {
        finish = 1;
        break;
      }

      if (key_up.is_click() || key_down.is_click() )
      {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Programm fortfue   ");
        lcd.setCursor(0, 1);
        lcd.print("hren?  ok ");
        while (key_enter1.is_click() != 1);
        break;
      }
    }
    if (finish)
      break;
    while (key_up.is_click() || key_down.is_click()) ;
  }
  lcd.clear();
}
//...
void count_pwm()//zählen
{
  count++;
  if (count >= pwm_num.int_num)//Impuls ist größer als 470 oder gleich wie 470
  {
    now_wasser.int_num++;
    count = 0;
  }
}
//...
void setup() {

  for (int i = 10; i < 14; i++)
  {
    target_wasser.byte_num[i - 10] = EEPROM.read(i);
    pwm_num.byte_num[i - 10] = EEPROM.read(i + 4);
  }
  //...
  key_start.begin(14);//Pin=14
  key_up.begin(15);//Pin=15
  key_down.begin(16);//Pin=16
  key_change_mode.begin(18);//Pin=18
  key_enter1.begin(17); //Pin=17
  //...
  Serial.begin(9600);
  lcd.begin(16, 2);// LCD beginnen

  if (key_change_mode.is_click())
  {
    change_mode();//on
  }

  else
  {
    run_mode();//off
  }
}

void loop() {

}

Hallo agmue,

Danke erstmal für Deine Rückmeldung.

Das Programm habe ich nicht geschrieben, denn ich bin zurzeit nur einen Praktikant bei einem Unternehmen und ich muss versuchen, das Problem zu lösen.
Das Programm wurde (soweit ich weiß) von einer Praktikantin geschrieben.

Ich habe das Programm angeschaut und da gab es nur paar Syntax-Fehlern. War das der Grund?

Ich würde das Programm ganz neu schreiben. Die Logik ist nicht überall korrekt.

Ich würde es einsortieren als "it compiles, let's ship it" :frowning:

matrixsy:
Das Programm habe ich nicht geschrieben, denn ich bin zurzeit nur einen Praktikant bei einem Unternehmen und ich muss versuchen, das Problem zu lösen.
Das Programm wurde (soweit ich weiß) von einer Praktikantin geschrieben.

dann mach es besser als deine Vorgängerin und mach zunächst eine Programmbeschreibung, Ablaufdiagramm, UseCase Katalog - was auch immer in deiner Firma gefragt ist und dann behebe den Fehler.

Hallo DrDiettrich und noiasca,

Danke für Eure Rückmeldung.

Ich habe mich bisher überhaupt nicht mit Arduino beschäftigt. Ich kenne mich mit Python und Java gut aus, aber im Vergleich zur Arduino sind ja paar Unterschiede zu erkennen.
Das Problem bei mir, dass ich nicht weiß mit was ich anfangen soll.

Bis jetzt habe ich drei Möglichkeiten gefunden, die möglicherweise den Fehler beheben kann:

  1. Möglichkeit: die Bedingungen der Klasse (key) zu ändern
  2. Möglichkeit: auf delay verzichten
  3. Möglichkeit: das Code beim Taste drücken zu ändern (s. Bild)

Die Klasse prüft bei is_click() mit delay() ob die Taste ausreichend lange (entprellt) gedrückt ist. Das kann man eigentlich so lassen.

Es kommt also nur noch drauf an, bei Bedarf die Tasten abzufragen und entsprechend zu reagieren. Vermutlich kommt alles auf einen Modus (Techniker...) an, welche Tasten dann welche Funktion haben sollen. Als Entwicklunshilfe das alles als ein Ablaufdiagramm oder einen endlichen Automaten aufschreiben und anschließend dementsprechend auskodieren. Vielleicht gibt ja der Auftrag für den Praktikanten zur Aufgabenstellung was her?

Die Programmiersprache bei Arduino ist C/C++.

Ein Ablaufplan bzw eine Funktionslogik / Programmablauf / Programmlogib müßte sich zu den anderen Programmiersprachen die Du kennst nicht ändern. Wenn Du das Programm in Python und Java schreiben würdest mußt Du Dir ja auch zuerst überlegen was es wie machen soll.

Ist wie einen Brief schreiben; Was Du schreiben willlst mußt Du Dir immer vorher überlegen egal ob der Brief dann auf deutsch, italienisch oder englisch geschrieben wird.

Grüße Uwe