Problem mit Tastersteuerung und deren Tasterbeleuchtung

Hallo liebe Community,

ich bin erst seit wenigen Tagen im Arduino Kosmos und habe schon einmal in der Schule mit C# Berührungspunkte gehabt. Bitte seht es mir aber nach, wenn die Codes umständlich geschrieben oder meine Fragen / Erklärungen etwas unklar formuliert sind - ich gebe mein bestes. :slight_smile:
Bin aber gerne für Feedback offen und auch gern bereit meinen Code auf einer ganz anderen Logik neu zu schreiben!

Nun zu meiner Problematik:
Ich benutze einen Arduino Mega Nachbau (2560) von Joy-IT und möchte diesen in meinem Van verbauen.

Die Schalttafel die ich bereits gebaut habe, trägt mehrere Taster mit integrierten Leuchtringen, diese Taster steuern dann entsprechende Relais an.
Ich habe jedoch zwei Taster, welche Spezielle Funktionen erfüllen und den Sketch für mich gerade sehr kompliziert machen.
Schalter 1: Steuert mehrere Pins an - es soll damit quasi die gesamte Beleuchtung im Raum aktiviert werden, welche normalerweise über 5 separate Taster aktivierbar ist.
Schalter 2: aktiviert/deaktiviert die Leuchtringe der Taster.

in einem Versuchsaufbau (4 Taster & LEDS) habe ich den Sketch schon so weit geschrieben bekommen, dass ich vier Kanäle habe - zwei Kanäle die die späteren Verbraucher simulieren und zwei Kanäle die meine Spezialfunktionen übernehmen sollen.
Aktuell funktioniert der Code so:

  1. Kanal steuert eine LED (Leuchtring) und ein Relais für den Verbraucher an
  2. Kanal steuert eine LED (Leuchtring) und ein Relais für den Verbraucher an
  3. Kanal steuert nur eine LED an
  4. Kanal steuert auch nur eine LED an

Ich möchte also irgendwie den Bogen gespannt bekommen, die Tastenbeleuchtung an oder ausschalten zu können ohne die geschalteten Relais zu beeinflussen
genauso auch die Relais alle auf einmal ansteuern können wie oben schon beschrieben.

EDIT: Meine Taster haben einen Mulldown-Widerstand auf GND und schließen gegen VCC

Vielleicht kann mir jemand weiter helfen, mein Kopf qualmt schon ziemlich.

Hier mein überarbeiteter Sketch:

/* Falls der Schalter zu unkontrolliert geht, in die Kanal-Algorithmen einfügen:


          if (readingLHerd != lastButtonStateLHerd) {

            lastDebounceTime = millis();
          }


*/

//>>>>>>>>>Variablen und Konstanten für die Kanäle<<<<<<<<

//Kanal Alles
int ledStateAlles;                      // wird von if-Schleife mit HIGH / LOW belegt
int buttonStateAlles;                   // liest aus, ob Button des Kanals gedrückt ist oder nicht
int lastButtonStateAlles      = LOW;    // für das ganz oben ausgeklammerte, "erweiterte" Debouncen - aktuell nicht in Benutzung
const int buttonPinAlles      = 2;      // Button-Pinbelegung für den Kanal
const int ledPinAlles         = 8;      // LED-Pinbelegung für den Kanal




//Kanal für Tastenbeleuchtung              TaBel steht für Tastenbeleuchtung
int ledStateTaBel;                      // selbes Belegungsmuster wie im Kanal alles
int buttonStateTaBel;
int lastButtonStateTaBel      = LOW;
const int buttonPinTaBel      = 3;
const int ledPinTaBel         = 9;
int allLeds                  = (10, 11);

//Kanal LDusche (Licht-Dusche)
int ledStateLDusche;                    // hier ebenso
int buttonStateLDusche;
int lastButtonStateLDusche    = LOW;
const int buttonPinLDusche    = 4;
const int ledPinLDusche       = 10;

//Kanal LHerd
int ledStateLHerd;                      // hier ebenso
int buttonStateLHerd;
int lastButtonStateLHerd      = LOW;
const int buttonPinLHerd      = 5;
const int ledPinLHerd         = 11;


//Relais bereich:

int       relaisStateLHerd;                   // wird von if-Schleife mit HIGH / LOW belegt
int       toggleRelaisStateLHerd    = HIGH;   // wird von if Schleife mit HIGH / LOW belegt - ist mit HIGH gekennzeichnet, da sonst LED und KANAl asynchron starten ( LED an , relais aus & umgekehrt)
const int relaisLHerd               = 30;     // Pinbelegung

int       relaisStateLDusche;                 // hier wieder wie in den drei Zeilen darüber
int       toggleRelaisStateLDusche  = HIGH;
const int relaisLDusche             = 31;

//>>>>>>>>>Allgemeine Variablen<<<<<<<<<<

unsigned long lastDebounceTime = 10;          // teil der Schaltersteuerung, die den Taster zum Schalter macht
unsigned long debounceDelay = 50;             // ebenso teil der Schaltersteuerung



void setup() {

  Serial.begin(9600);
  //Pindefinitionen der Kanäle          Selbsterklärend

  pinMode(buttonPinAlles, INPUT);
  pinMode(ledPinAlles, OUTPUT);

  pinMode(buttonPinTaBel, INPUT);
  pinMode(ledPinTaBel, OUTPUT);

  pinMode(buttonPinLDusche, INPUT);
  pinMode(ledPinLDusche, OUTPUT);
  pinMode(relaisLDusche, OUTPUT);

  pinMode(buttonPinLHerd, INPUT);
  pinMode(ledPinLHerd, OUTPUT);
  pinMode(relaisLHerd, OUTPUT);


}

void loop() {
  //Variablen, Taster-Readout der Kanäle

  int readingAlles     = digitalRead(buttonPinAlles);
  int readingTaBel     = digitalRead(buttonPinTaBel);
  int readingLHerd     = digitalRead(buttonPinLHerd);
  int readingLDusche   = digitalRead(buttonPinLDusche);

  //if-Schleifen zur Tastermodellierung der Kanäle:

  //Kanal Alles

  if ((millis() - lastDebounceTime) > debounceDelay) {    // zum debouncen

    if (readingAlles != buttonStateAlles) {               // ist der reading pin ungleich dem vorher gespeicherten buttonstatus, dann..
      buttonStateAlles = readingAlles;                    // überschreibe den alten buttonstatus mit dem Wert des reading


      if (buttonStateAlles == HIGH) {                       // ist der neue Wert High, dann..
        ledStateAlles = ! ledStateAlles;                    // ändere die Variable (HIGH auf LOW, oder LOW auf HIGH)

      }
    }
  }


  lastButtonStateAlles = readingAlles;                    // das ist wieder fürs ausgeklammerte, "erweiterte" debouncen
  digitalWrite(ledPinAlles, ledStateAlles);               // setzt die neu belegten Variablen in die pinbelegung des Kanals und schaltet LED an / aus


  //Kanal TastenBeleuchtung                                       //funktionsweise nach dem selben Prinzip wie Kanal "alles"

  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (readingTaBel != buttonStateTaBel) {
      buttonStateTaBel = readingTaBel;

      if (buttonStateTaBel == HIGH) {
        ledStateTaBel = ! ledStateTaBel;

      }
    }
  }



  lastButtonStateTaBel = readingTaBel;
  digitalWrite(ledPinTaBel, ledStateTaBel);


  //Kanal Dusche                                                //funktionsweise nach dem selben Prinzip wie Kanal "alles" - beachte nun den Relais abschnitt
  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (readingLDusche != buttonStateLDusche) {
      buttonStateLDusche = readingLDusche;

      if (buttonStateLDusche == HIGH) {
        ledStateLDusche = ! ledStateLDusche;
      }
    }

    if (readingLDusche != relaisStateLDusche) {       // selbe arbeitsweise wie bei den if Schleifen für den Taster
      relaisStateLDusche = readingLDusche;


      if (relaisStateLDusche == HIGH) {
        toggleRelaisStateLDusche = ! toggleRelaisStateLDusche;

      }
    }
  }


  lastButtonStateLDusche = readingLDusche;
  digitalWrite(ledPinLDusche, ledStateLDusche);
  digitalWrite(relaisLDusche, toggleRelaisStateLDusche);      // Relais wird mit neu belegten Variablen belegt und steuert Pin an

  //Kanal Herd
  if ((millis() - lastDebounceTime) > debounceDelay) {


    if (readingLHerd != buttonStateLHerd) {
      buttonStateLHerd = readingLHerd;


      if (buttonStateLHerd == HIGH) {
        ledStateLHerd = ! ledStateLHerd;

      }
    }

    if (readingLHerd != relaisStateLHerd) {
      relaisStateLHerd = readingLHerd;


      if (relaisStateLHerd == HIGH) {
        toggleRelaisStateLHerd = ! toggleRelaisStateLHerd;

      }
    }
  }

  lastButtonStateLHerd = readingLHerd;

  digitalWrite(ledPinLHerd, ledStateLHerd);
  digitalWrite(relaisLHerd, toggleRelaisStateLHerd);

}

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

@roobenpa
kannst du deinen Code so kommentieren dass deine Beschreibung einen Sinn macht oder in deinem Text jeweils dazuschreiben wie deine Variablen im Code heißen?

Schließen alle deine Taster gegen VCC und haben somit deine Eingänge einen Pulldown Widerstand auf GND?

Es ist hilfreich, wenn die Blöcke ordentlich eingerückt sind, damit man sieht welche noch offen oder geschlossen sind. STRG+T hilft dabei in der Arduino IDE

Es sieht so aus, als ob du IF-Abfragen ausführen willst, die nicht erreicht werden können, da sie von einer vorherigen IF-Abfrage abhängig sind. Nur eine Vermutung.

Vielen Dank für deine Antwort.
siehe Oben, pulldown vorhanden sowie neu Kommentierter Sketch

habe ich gemacht, hoffe das passt so. :slight_smile:
ja, ich habe schon mehrere Variationen probiert, die leider diese Spezialfunktionen nicht herbeigeführt haben und mir die selbe Vermutung gegeben haben, wie du sie hast. Habe den Sketch wieder so gesäubert, dass er zumindest die Funktionen die ich habe, wie sie im ursprünglichen Post beschrieben sind, erfüllt.

Diese Zeile ist nach 60 Millisekunden Laufzeit immer wahr. Das ist bestimmt nicht gewollt. Du solltest lastDebouncTime aktualisieren, wenn die If-Abfrage wahr ist.
Auch macht es in meinen Augen mehr Sinn, alle deine Taster in einer Debounce-Abfrage abzuhandeln, als 4mal die gleiche If-Abfrage auszuführen.

@roobenpa

ich hab zwar deine Programmlogik immer noch nicht aus deiner Beschreibung rauslesen können aber ...
a) würde ich Codeduplikate vermeiden und für die Buttons eine Klasse machen
b) und dann maximal zwei if Ebenen zum Umschalten der Pins verwenden.

in etwa so

//https://forum.arduino.cc/t/problem-mit-tastersteuerung-und-deren-tasterbeleuchtung/960749

class Button {                         // a simple class for buttons based on the "state change detection" example
    const byte buttonPin;
    const byte debounceDelay = 50;     // the debounce time; increase if the output flickers
    bool lastButtonState = LOW;       // the previous reading from the input pin
    uint32_t lastDebounceTime = 0;     // the last time the output pin was toggled - we check only ONE byte, so I didn't mess around with unsigned long

  public:
    Button(byte attachTo) : buttonPin(attachTo) {}

    void begin() {
      pinMode(buttonPin, INPUT);
    }

    bool wasPressed() {
      bool buttonState = LOW;                  // the current reading from the input pin
      byte reading = LOW;
      if (digitalRead(buttonPin) == HIGH) reading = HIGH;
      if ((millis() - lastDebounceTime) > debounceDelay)    // If the switch changed, AFTER any pressing or noise
      {
        if (reading != lastButtonState && lastButtonState == LOW)
        {
          buttonState = HIGH;
        }
        lastDebounceTime = millis();
        lastButtonState = reading;
      }
      return buttonState;
    }
};

//Kanal Alles
bool buttonStateAlles;
const byte buttonPinAlles      = 2;
const byte ledPinAlles         = 8;
const byte ledStateAlleLeds    = LOW;
Button btnAlles(buttonPinAlles);

//Kanal für Tastenbeleuchtung
bool ledStateTaBel;
const byte buttonPinTaBel      = 3;
const byte ledPinTaBel         = 9;
int allLeds                  = (10, 11);
Button btnBel(buttonPinTaBel);

//Kanal LDusche (Licht-Dusche)
const byte buttonPinLDusche    = 4;
const byte ledPinLDusche       = 10;
Button btnDusche(buttonPinLDusche);

//Kanal LHerd
const byte buttonPinLHerd      = 5;
const byte ledPinLHerd         = 11;
Button btnHerd(buttonPinLHerd);

//Relais bereich:
const byte relaisLHerd               = 30;
const byte relaisLDusche             = 31;

void setup() {
  Serial.begin(9600);
  //Pindefinitionen der Kanäle
  pinMode(ledPinAlles, OUTPUT);
  pinMode(ledPinTaBel, OUTPUT);
  pinMode(ledPinLDusche, OUTPUT);
  pinMode(relaisLDusche, OUTPUT);
  pinMode(ledPinLHerd, OUTPUT);
  pinMode(relaisLHerd, OUTPUT);
  btnAlles.begin();
  btnBel.begin();
  btnHerd.begin();
  btnDusche.begin();
}

void loop() {
  if (btnAlles.wasPressed())
  {
    Serial.println(F("alles"));
    buttonStateAlles = !buttonStateAlles;
    if (buttonStateAlles)
    {
      // was wäre  zum einschalten?
    }
    else
    {
      digitalWrite(relaisLDusche, LOW);
      digitalWrite(relaisLHerd, LOW);
    }
  }

  if (btnBel.wasPressed())
  {
    Serial.println(F("Bel"));
    ledStateTaBel = !ledStateTaBel;
    if (ledStateTaBel)
    {
      digitalWrite(ledPinAlles, HIGH);
      digitalWrite(ledPinTaBel, HIGH);
      digitalWrite(ledPinLDusche, HIGH);
      digitalWrite(ledPinLHerd, HIGH);
    }
    else
    {
      digitalWrite(ledPinAlles, LOW);
      digitalWrite(ledPinTaBel, LOW);
      digitalWrite(ledPinLDusche, LOW);
      digitalWrite(ledPinLHerd, LOW);
    }
  }

  if (btnHerd.wasPressed())
  {
    Serial.println(F("Herd"));
    //toggle
    if (digitalRead(relaisLHerd) == LOW)
    {
      digitalWrite(relaisLHerd, HIGH);
      digitalWrite(ledPinLHerd, HIGH); // ???
    }
    else
    {
      digitalWrite(relaisLHerd, LOW);
      digitalWrite(ledPinLHerd, LOW); // ???
    }
  }
  
  if (btnDusche.wasPressed())
  {
    Serial.println(F("Dusche"));
    //toggle
    if (digitalRead(relaisLDusche) == LOW)
    {
      digitalWrite(relaisLDusche, HIGH);
      digitalWrite(ledPinLDusche, HIGH);
    }
    else
    {
      digitalWrite(relaisLDusche, LOW);
      digitalWrite(ledPinLDusche, LOW);
    }
  }
}

falsch kann es sein, aber ich find es übersichtlicher.

edit: 20221802_van.ino - Wokwi Arduino and ESP32 Simulator

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.