Beregnungsanlage mit einem Arduino MEGA 2560 in OOP

Hallo, ich habe mir vorgenommen, meine Beregnungsanlage mit einem Arduino MEGA 2560 zu Automatisieren. In der einfachen Programmierung kein Problem, aber 6 Taster mit gleichem Programm machen das sehr unübersichtlich. Also mit Objekten, habeich mir so gedacht. Gebraucht wird nur eine bool-Variable und da ist das Problem. Ich kann im Objekt eingeben was ich will (was mir so in den unwissenden Kopf kommt. Der Kompilerlauf ist immer i.O.. Gebe ich aber im Hauptprogramm Serial.print ein, um den Zustand der Variable zu sehen, kommt sofort Fehler. Ich gebe mal die Programmteile ein und hoffe das jemand die Lösung hat. Ich brauche entweder den Wert der LED oder des Ein_Speichers.

class TasterClass {

private:
int LEDPin;
int TasterPin; // Pin-Nummer für Taster
int TasterPinWert;
int LEDPinWert;
bool Wert_Taster; // Taster Ein = true oder false
bool einSpeicher;
bool Speicher;
bool Flanke;

public: //Setzen der Pin-Nummer und Initialisierung der Pin-Modi

void setPin( int TasterPinWert, int LEDPinWert) {
LEDPin = LEDPinWert;
TasterPin = TasterPinWert;
pinMode (LEDPin, OUTPUT);
pinMode (TasterPin, INPUT_PULLUP);

}

void CheckStatus() {

Wert_Taster = !digitalRead(TasterPin); // Lesen des Taster-Pins und Invertieren des Wertes (Taster gedrückt = true)

if (Wert_Taster == true && Speicher == false) {
Flanke = true;
Speicher = true;}
if (Wert_Taster == false) {
Speicher = false;}

if ( Flanke == true && einSpeicher == true) {
einSpeicher = false;
LEDPin = false;
Flanke = false;}

if ( Flanke == true && einSpeicher == false) {
einSpeicher = true;
LEDPin = true;
Flanke = false;}

// Methode zum Abrufen Zustand LED

//bool geeinSpeicher() {
return einSpeicher;} // LED

};

#include "FlipFlop.h"

TasterClass TasterE;
TasterClass TasterH; //Erzeugen einer Instanz TasterClass für den ersten Taster
TasterClass TasterA;
TasterClass TasterV1;
TasterClass TasterV2;
TasterClass TasterV3;

void setup() {
TasterE.setPin (40, 26); //Taster mit Pullup-Wiederstand
TasterH.setPin (41, 27);
TasterA.setPin (42, 28);
TasterA.setPin (43, 29);
TasterA.setPin (44, 30);
TasterA.setPin (45, 31);

Serial.begin(4800); // Initialisierung der seriellen Kommunikation mit 115200 Baud

}

void loop() {

TasterE.CheckStatus();
Serial.print("Taster wurden gedrückt: ");
//Serial.println(TasterE.geEin_Speicher());
}

Vielen Dank im voraus
Jens

Und wer hat den Code geschrieben? Ich frag' so böd, weil du nur TasterE verwendest aber jede Menge anderes Zeug definierst.

Dieser Titel ist häufig zutreffend und daher unspezifisch.

Etwas wie "Beregnungsanlage mit einem Arduino MEGA 2560 in OOP" hätte einen besseren Wiedererkennungswert. Du kannst den Titel ändern.

Bitte in code-Tags eingeben, dann ist Dein Programm besser lesbar und kopierbar. Dazu kannst Du Deinen Beitrag verändern.

```
Dein Programm
```

Ja, das ist eine gute Idee :grinning_face:

Warum machst Du CheckStatus (Methodennamen beginnen allgemein mit einem Kleinbuchstaben) void und nicht bool und gibst dort den aktuellen Wert zurück, den Du dann im Hauptprogramm auswerten kannst.

Anstelle der Aufzählung der Tasten könntest Du auch ein Array verwenden und die Pins im Konstruktor setzen.

Gruß Tommy

4 mal Taster A zu parametrisieren kann nur falsch sein.

Ich rate zu einem Konstruktor, und deine Taster in ein Array zu stopfen. Denn durchnummerieren führt meist genau zu solchen Fehlern.

Viel zu viel Code.

Das mache ich einfach in der void loop() Routine.

If Taste_1 == High {
'mach was
}

reicht völlig aus.

Ich als Faulpelz habe mir ein PCF7574 via Adapter an ein 16 er Membranenfeld angeklemmt und dann das ganze einfach via Libs abgefragt. Sind keine 5 Zeilen Code.

Gib einfach : "arduino 16er tastatur via i2c anschließen" bei Google ein.
Den Code den die KI dann schreibt stimmt (ausnahmsweise).

Ach ja, es ist egal wenn es weniger Tasten sind. Die die nicht da sind liefern logoweis kein Ergebnis. Man muss halt nur die Matrix beachten.

Auf die Weise hat man 1 Bauteil mehr und spart ne Menge Kabel und Code.

Gruß

Pucki

Der TO hat ein Mega 2560 wo zu noch Expander ?

ungetestet, kompiliert.

//edit: TPin und LPin in der Reihenfolge getauscht

// Forensketch - LED togglen mit jedem Tastendruck
// https://forum.arduino.cc/t/c-ich-habe-nur-begrenzte-ahnung/1441024

constexpr bool OFF {LOW};
constexpr bool ON {!OFF};
constexpr bool isPressed {LOW};
constexpr uint32_t debounceTime {50};

struct CHANNEL
{
  uint8_t TPin;
  uint8_t LPin;
  uint32_t lastPressTime;
  bool lastState ;
};

CHANNEL channel[] =
{
  {40, 26, 0, !isPressed,},
  {41, 27, 0, !isPressed,},
};

void setup()
{
  Serial.begin(115200);
  delay(300);
  Serial.println(F("\r\nStart...\r\n"));

  for (CHANNEL &c : channel)
  {
    pinMode(c.LPin, OUTPUT);
    digitalWrite(c.LPin, OFF);
    pinMode(c.TPin, INPUT_PULLUP);
  }
}

void loop()
{
  for (CHANNEL &c : channel)
  { tasterCheckAndToggleLed(c); }
}

void tasterCheckAndToggleLed(CHANNEL &c)
{
  if (digitalRead(c.TPin) == isPressed)
  {
    if (c.lastState != isPressed)
    {
      c.lastState = isPressed;
      c.lastPressTime = millis();
      digitalWrite(c.LPin, !digitalRead(c.LPin));
    }
  }
  else if (c.lastState == isPressed)
  {
    if (millis() - c.lastPressTime > debounceTime)
    { c.lastState = !isPressed; }
  }
}

bitte stelle deinen Code im ersten Beitrag in Code Tags damit es lesbar wird. In der Zwischenzeit klopfe ich etwas zusammen.

Basierend auf #8 eine Variante mit "mehr OOP" durch eine Methode der Struktur anstelle einer Funktion:

// Forensketch - LED togglen mit jedem Tastendruck
// https://forum.arduino.cc/t/c-ich-habe-nur-begrenzte-ahnung/1441024

constexpr bool OFF{ LOW };
constexpr bool ON{ !OFF };
constexpr bool isPressed{ LOW };
constexpr uint32_t debounceTime{ 50 };

struct CHANNEL {
  uint8_t TPin;
  uint8_t LPin;
  uint32_t lastPressTime;
  bool lastState;
  uint8_t schritt;

  void init() {
    pinMode(LPin, OUTPUT);
    digitalWrite(LPin, OFF);
    pinMode(TPin, INPUT_PULLUP);
  }

  void tasterCheckAndToggleLed() {
    if (digitalRead(TPin) == isPressed) {
      if (lastState != isPressed) {
        lastState = isPressed;
        lastPressTime = millis();
        digitalWrite(LPin, !digitalRead(LPin));
      }
    } else if (lastState == isPressed) {
      if (millis() - lastPressTime > debounceTime) { lastState = !isPressed; }
    }
  }
};

CHANNEL channel[] = {
  { 40, 26, 0, !isPressed, 0 },
  { 41, 27, 0, !isPressed, 0 },
};

void setup() {
  Serial.begin(115200);
  delay(300);
  Serial.println(F("\r\nStart...\r\n"));

  for (CHANNEL &c : channel) { c.init(); }
}

void loop() {
  for (CHANNEL &c : channel) { c.tasterCheckAndToggleLed(); }
}

Weil die Ansteuerung viel einfacher ist.
Und ich das Teil gegen ein ESP32 austauschen würde.

Mehr Speicher, bessere Ansteuerung einen feinen Display und vielleicht sogar, wenn er mehr in der Materie ist, eine Rückmeldung wenn das Wasserdepot leer ist.

Was nämlich meine Anlage demnächst verpasst bekommt. Die Abschaltung der Pumpen ist eh Pflicht, wenn das Depot leer ist, weil sonst die Pumpen kaputt gehen.
Außer er meint eine Anlage mit einen schaltbaren Druckventil und Wasser aus den Hahn. Dann muss er aber auf die Relais-Steuerung aufpassen.

Gruß

Pucki

Unsinn.
Alle müssen das machen was pucki meint, ach ja alles klarr.

dafür reicht auch ein Mega, zu dem ist der Vorhanden.
Kein ESP hat so viele Pins wie ein Mega.
Wen interessiert was du vorhast.
Mach neuen Beitrag auf da kannst dich austoben, las das hier mit deinem Müll in Ruhe

Hallo, ihr wisst schon, das meine Kenntnisse sehr gering sind. Manche Sachen muß ich erst einmal bei Googel nachfragen. Das ist nur ein Ausschnitt aus dem vollen Pogramm, denn wenn einer nicht funktioniert, ist das bei den Anderen genau so. Bei 4x TasterA liegt es daran, das ich die Zeilen nur kopiert habe aber nicht geändert. Im Objekt soll eigendlich nur realisiert werden, daß Taster drücken "Ein", nochmal drücken "Aus" und das funktioniert ja auch. Die LED-Ansteuerung kann da ja auch raus, wenn ich den Wert des ein_Speichers nach draußen bekomme. Dann würde ich LED`s mit den 4 Reais ansteuern, die in diesem Programmteil nicht drin sind. Dazu kommen noch 3 Ventile, die in der Automatik jeweils 30min (millis) angesteuet werden. Im Handbetrieb kommt noch eine max. Lauzeit dazu, da ich eine Tauchpumpe habe, die man nicht hört wenn sie läuft. Ich werd alles genau lesen und melde mich auf jeden Fall wieder.
Vielen Dank erst einmal
Jens

Dürfen nicht direkt vom Mega angesteuert werden so wie die Pumpe, sonst kannst dir neuen Mega kaufen.

Mit "draußen" meinst Du vermutlich außerhalb der Struktur/Klasse?

Das macht beispielsweise eine Methode getState(), die als Rückgabewert den Wert einer Variablen oder den Zustand der LED haben kann.

// Forensketch - LED togglen mit jedem Tastendruck
// https://forum.arduino.cc/t/c-ich-habe-nur-begrenzte-ahnung/1441024

constexpr uint8_t testLedPin { 13 };
constexpr bool OFF{ LOW };
constexpr bool ON{ !OFF };
constexpr bool isPressed{ LOW };
constexpr uint32_t debounceTime{ 50 };

struct CHANNEL {
  uint8_t TPin;
  uint8_t LPin;
  uint32_t lastPressTime;
  bool lastState;
  uint8_t schritt;

  void init() {
    pinMode(LPin, OUTPUT);
    digitalWrite(LPin, OFF);
    pinMode(TPin, INPUT_PULLUP);
  }

  void tasterCheckAndToggleLed() {
    if (digitalRead(TPin) == isPressed) {
      if (lastState != isPressed) {
        lastState = isPressed;
        lastPressTime = millis();
        digitalWrite(LPin, !digitalRead(LPin));
      }
    } else if (lastState == isPressed) {
      if (millis() - lastPressTime > debounceTime) { lastState = !isPressed; }
    }
  }

  bool getState() {
    return digitalRead(LPin);
  }
};

CHANNEL channel[] = {
  { 40, 26, 0, !isPressed, 0 },
  { 41, 27, 0, !isPressed, 0 },
};

void setup() {
  Serial.begin(115200);
  delay(300);
  Serial.println(F("\r\nStart...\r\n"));
  pinMode(testLedPin, OUTPUT);

  for (CHANNEL &c : channel) { c.init(); }
}

void loop() {
  for (CHANNEL &c : channel) { c.tasterCheckAndToggleLed(); }
  digitalWrite(testLedPin, channel[0].getState());
}

Die eingebaute LED an Pin 13 leuchtet synchron zur LED an Pin 26.


Neuer Thementitel
:+1:

Empfehlung ist da eher hier oder ein Buch.
Die Trefferrate kann natürlich bei einigen Fragen funktionieren, aber wer mit class schon mal angefangen hat, ist weiter als ich...

Du kannst anstelle des PIN einen bool nehmen und erhälst den selben Effekt.

// Forensketch - LED togglen mit jedem Tastendruck
// https://forum.arduino.cc/t/c-ich-habe-nur-begrenzte-ahnung/1441024

constexpr bool OFF {LOW};
constexpr bool ON {!OFF};
constexpr bool isPressed {LOW};
constexpr uint32_t debounceTime {50};

struct CHANNEL
{
  uint8_t TPin;
  bool state;
  uint32_t lastPressTime;
  bool lastState ;
};

CHANNEL channel[] =
{
  {26, OFF, 0, !isPressed,},
  {27, OFF, 0, !isPressed,},
};

void setup()
{
  Serial.begin(115200);
  delay(300);
  Serial.println(F("\r\nStart...\r\n"));

  for (CHANNEL &c : channel)
  { pinMode(c.TPin, INPUT_PULLUP); }
}

void loop()
{
  for (CHANNEL &c : channel)
  { tasterCheckAndToggleLed(c); }
}

void tasterCheckAndToggleLed(CHANNEL &c)
{
  if (digitalRead(c.TPin) == isPressed)
  {
    if (c.lastState != isPressed)
    {
      c.lastState = isPressed;
      c.lastPressTime = millis();
      c.state = !c.state;
      Serial.print(F("Neuer Zustand: "));
      Serial.println(c.state == ON ? "ON" : "OFF");
    }
  }
  else if (c.lastState == isPressed)
  {
    if (millis() - c.lastPressTime > debounceTime)
    { c.lastState = !isPressed; }
  }
}

mit channel[0].state hast Du den Status des ersten, den Du jederzeit abfragen kannst.

Wenn da zusätzlich aus einer anderen Funktion der Status geändert werden soll, ist das besser über Variablen - wie gezeigt - zu lösen und die jeweiligen Programmteile aufzuteilen in Aktion und Reaktion.

Ob da nun irgendwas automatisch anläuft oder per Hand, spielt dabei keine Rolle.

Mach was draus.

@agmue: danke, heute hatte ich die Referenz vergessen.

@glatzkopf
Kannst mir erklären warum Du ein Taster auf zwei Pins klemmt?
Wo her hast die Flipflop.h bin irgend wie blind.

Das sind LED-Pin und Taster-Pin

Gruß Tommy

Ok Dankeschön