Begrenzung des Wertebereichs Encoder (Drehgeber) und Anwendung

Hallo zusammen, für mein Projekt möchte ich ein Display basteln, welches ich mit einem Encoder bedienen möchte.
Durch Drehung des Encoders sollen sich 4 verschiedene Menüpunkte anzeigen lassen. (Beispiel: Display zeigt das Wort "Mittel" an. Drehe ich nach links soll das Wort "Klein" erscheinen, drehe ich weiter "sehr klein". Drehe ich nach rechts soll das Wort groß erscheinen")

Nun wollte ich den Encoder bezüglich des Wertebereichs eingrenzen. Mein Code sieht bisher wie folgt aus (habe die Datei auch mal beigefügt) :

#include <Encoder.h>


#include <Wire.h>


#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  


int aktuellerwert=10;
int merker=2;
const int clk=6;
const int dt=5;
int sw=2;


Encoder meinEncoder(dt,clk); //Erstellen eines neuen Projektes (möglicher Fehler!)




/////////////////////////
///////SETUP////////////
///////////////////////
void setup() {
Serial.begin(9600);


pinMode(8,OUTPUT); //5V an Pin 8 aktivieren
digitalWrite(8,HIGH);


pinMode(sw,INPUT); // Pin 2 als Input für Schalter des encoders


lcd.init();
lcd.backlight();


}




void loop() {
 
int aktuellerwert=meinEncoder.read(); //Die aktuelle Position des Encoders wird gelesen, mit diesem Wert soll auch in void merkermacher eingestiegen werden!!


if (aktuellerwert < 0);{meinEncoder.write(0);} //wenn der Encoderwert kleiner 0 soll 0 angenommen werden (min.Wert)
if (aktuellerwert >123);{meinEncoder.write(123);} //wenn der Encoderwert größer 123 soll 123 angenommen werden (max.Wert)
aktuellerwert = constrain(aktuellerwert,0,123); // der Wertebereich wird von 0-123 beschränkt


Serial.println(aktuellerwert);


merkermacher();//ausführen der Funktion merkermacher 
lcd.println(merker);




}


void merkermacher() {
delay(200);
lcd.clear();
lcd.setCursor(0,0);
if (aktuellerwert < 31) //Die Variable "aktuellerwert" soll aus dem Loop-Teil entnommen werden und nicht aus der Definition des Programmkopfes
merker=1;


if (aktuellerwert < 62 && aktuellerwert > 30)
merker=2; 


if (aktuellerwert < 93 && aktuellerwert > 61)
merker=3; 


if (aktuellerwert <124 && aktuellerwert > 92)
merker=4;
}

Nun meine Fragen:
1.Was macht der Befehl "Encoder" genau, wo ich "meinEncoder" definiert habe?
2. Ich glaube, dass die Void "merkermacher" nicht den Wert für die Variable "aktuellerwert" aus dem Loop-Teil nimmt, sondern durchgehend den Wert aus dem Kopfteil des Programmes (int aktuellerwert=10). Daher ändert sich bei mir die Anzeige auf dem Display auch nicht.

3. Ist es im Allgemeinen möglich und sinnvoll, einen Drehgeber(Encoder) zu verwenden, um sich menüpunkte anzeigen zu lassen und mit dem im Encoder verbauten Taster durch Drücken einen der Menüpunkte auszuwählen und eine Aktion folgen zu lassen (d.h. nach Auswählen des Menüpunktes "klein" soll eine kleine Menge an Wasser gepumpt werden)
--> Ist es hier sinnvoller bzw. viel leichter, mit einem Schalter und Drehpotentiometer zu arbeiten?

Vielen Dank schon mal für eure Hilfe

LCD_und_Encorder.ino (1.6 KB)

#include <Encoder.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
int aktuellerwert = 10;
int merker = 2;
const int clk = 6;
const int dt = 5;
int sw = 2;
Encoder meinEncoder(dt, clk); //Erstellen eines neuen Projektes (möglicher Fehler!)
/////////////////////////
///////SETUP////////////
///////////////////////
void setup() {
  Serial.begin(9600);
  pinMode(8, OUTPUT); //5V an Pin 8 aktivieren
  digitalWrite(8, HIGH);
  pinMode(sw, INPUT); // Pin 2 als Input für Schalter des encoders
  lcd.init();
  lcd.backlight();
}
void loop() {

  int aktuellerwert = meinEncoder.read(); //Die aktuelle Position des Encoders wird gelesen, mit diesem Wert soll auch in void merkermacher eingestiegen werden!!
  if (aktuellerwert < 0); {
    meinEncoder.write(0); //wenn der Encoderwert kleiner 0 soll 0 angenommen werden (min.Wert)
  }
  if (aktuellerwert > 123); {
    meinEncoder.write(123); //wenn der Encoderwert größer 123 soll 123 angenommen werden (max.Wert)
  }
  aktuellerwert = constrain(aktuellerwert, 0, 123); // der Wertebereich wird von 0-123 beschränkt
  Serial.println(aktuellerwert);
  merkermacher();//ausführen der Funktion merkermacher
  lcd.println(merker);
}
void merkermacher() {
  delay(200);
  lcd.clear();
  lcd.setCursor(0, 0);
  if (aktuellerwert < 31) //Die Variable "aktuellerwert" soll aus dem Loop-Teil entnommen werden und nicht aus der Definition des Programmkopfes
    merker = 1;
  if (aktuellerwert < 62 && aktuellerwert > 30)
    merker = 2;
  if (aktuellerwert < 93 && aktuellerwert > 61)
    merker = 3;
  if (aktuellerwert < 124 && aktuellerwert > 92)
    merker = 4;
}

Hallo,

du definierst eine globale und eine lokale Variable in loop names aktuellerwert. Die lokale hat Vorrang.
Nimm bei der lokalen den Datentyp weg und das passt.

Encoder ist eine Klasse. Du definierst mit meinEncoder ein Objekt mit den Eigenschaften der Klasse Encoder. Fortan kannst du mit deinem Objekt alle Member und Methoden der Klasse verwenden. Den Umfang dessen legt der Programmierer der Lib fest.

Und ja du kannst ein Menü bauen. Encoder ist viel besser als Poti, weil ohne Anschlag aber mit "Raster"-Haptik.

Hallo
schalte im IDE die Ausgabe von allen Compiler-Meldungen ein.

Vielen Dank für eure schnelle Hilfe :smiley:

Den Fehler mit der globalen Variable habe ich wohl übersehen, super dass du das entdeckt hast @Doc_Arduino..
Entspricht der Encoder-Befehl bzw. Klasse also dem LiquidCrystal_I2C lcd(0x27, 16, 2) beim Display?

Nun läuft mein Programm aber noch immer nicht wie gewollt:

Der Wert im seriellen Monitor entspricht immer dem Max. Wert (in diesem Fall 123), egal ob ich den Encoder drehe oder nicht.
Bisher habe ich folgendes versucht, was erfolglos blieb:
1. Begrenzung aufgehoben: hier ist der Wert beim Drehen des Encoders langsam gestiegen, egal in welche Richtung ich gedreht habe
2. Den "Delay" im void merkermacher gelöscht. Auch das blieb erfolglos.

Habt ihr Ideen, woran es liegen könnte?

Das Display habe ich definitiv richtig angeschlossen, es zeigt den Wert "4" an, der bei 123 auch erscheinen soll.
Den Encoder habe ich mit Ground und 5v versorgt. Außerdem habe ich CLK an PIN6 und DT an PIN5 angeschlossen. (SW an PIN2, spielt hier aber vermutlich keine Rolle da noch nicht implementiert)

Danke im Vorhinein schon mal :slight_smile:

Hallo,

zeige bitte den aktuellen Code, ansonsten könnten wir aneinander vorbeireden. Gerade bei dem was du nun konkret mit der Variable gemacht hast. Entweder wieder als Anhang oder in code Tags.

Entspricht der Encoder-Befehl bzw. Klasse also dem LiquidCrystal_I2C lcd(0x27, 16, 2) beim Display?

Richtig. LiquidCrystal_I2C ist der Klassenname und du hast davon ein Objekt namens lcd erstellt.
Von 'Befehlen' spricht man in der Beziehung eher nicht.
Du hast doch sicherlich eine Werkzeugkiste mit allen möglichen drin.
Die Werkzeugkiste ist die Klasse. Die Werkzeuge da drin sind die verfügbaren 'Funktionen', bei Klassen Methoden genannt, zur Unterscheidung von den Funktionen im Hauptprogrammcode, und diese Methoden haben die Namen Hammer, Seitenschneider, Akkuschrauber usw. Verwenden kannste diese Methoden nur, wenn du im Besitz der Werkzeugkiste bist wo diese drin sind.

mdziad:
--> Ist es hier sinnvoller bzw. viel leichter, mit einem Schalter und Drehpotentiometer zu arbeiten?

4 Zustandsabfragen? 4 Taster? -> an einem Eingang geht das. Du schreibst nicht, was für ein Board....

Sonst vielleicht..

#include <Encoder.h>
#include <Wire.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

byte aktuellerWert = 10;
int merker = 2;
const int clk = 6;
const int dt = 5;
int sw = 2;

Encoder meinEncoder(dt, clk); //Erstellen eines neuen Projektes (möglicher Fehler!)

void setup() {
  Serial.begin(9600);
  pinMode(8, OUTPUT); //5V an Pin 8 aktivieren
  digitalWrite(8, HIGH);
  pinMode(sw, INPUT); // Pin 2 als Input für Schalter des encoders
  lcd.init();
  lcd.backlight();
}

void loop()
{
  byte encoderWert = meinEncoder.read(); //Die aktuelle Position des Encoders wird gelesen, mit diesem Wert soll auch in void merkermacher eingestiegen werden!!
  if (encoderWert < 0);
  {
    meinEncoder.write(0); //wenn der Encoderwert kleiner 0 soll 0 angenommen werden (min.Wert)
  }
  if (encoderWert > 123);
  {
    meinEncoder.write(123); //wenn der Encoderwert größer 123 soll 123 angenommen werden (max.Wert)
  }
  aktuellerWert = constrain(encoderWert, 0, 123); // der Wertebereich wird von 0-123 beschränkt
  Serial.println(aktuellerWert);
  lcd.println(merkermacher(aktuellerWert));
}


byte merkermacher(const byte auswahl)
{
  lcd.clear();
  lcd.setCursor(0, 0);
  switch (auswahl)
  {
    case 0 ... 30:
      merker = 1;
      break;
    case 31 ... 61:
      merker = 2;
      break;
    case 62 ... 92:
      merker = 3;
      break;
    case 93 ... 123:
      merker = 4;
      break;
  }
  return merker;
}
#include <Encoder.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);  

int aktuellerwert=10;
int merker=2;
const int clk=6;
const int dt=5;
int sw=2;

Encoder meinEncoder(dt,clk); // Definieren der Methode "Encoder"


/////////////////////////
///////SETUP////////////
///////////////////////
void setup() {
Serial.begin(9600);

pinMode(8,OUTPUT); //5V an Pin 8 aktivieren
digitalWrite(8,HIGH);

pinMode(sw,INPUT); // Pin 2 als Input für Schalter des encoders

lcd.init();
lcd.backlight();

}


void loop() {
  
aktuellerwert=meinEncoder.read(); //Die aktuelle Position des Encoders wird gelesen, mit diesem Wert soll auch in void merkermacher eingestiegen werden!!

if (aktuellerwert < 0);{meinEncoder.write(0);} //wenn der Encoderwert kleiner 0 soll 0 angenommen werden (min.Wert)
if (aktuellerwert >123);{meinEncoder.write(123);} //wenn der Encoderwert größer 123 soll 123 angenommen werden (max.Wert)
aktuellerwert = constrain(aktuellerwert,0,123); // der Wertebereich wird von 0-123 beschränkt

Serial.println(aktuellerwert); //Ausgabe des aktuellen Wertes im seriellen Monitor

merkermacher();//ausführen der Funktion merkermacher 
lcd.println(merker);


}

void merkermacher() {
delay(100);
lcd.clear();
lcd.setCursor(0,0);
if (aktuellerwert < 31) //Die Variable "aktuellerwert" soll aus dem Loop-Teil entnommen werden und nicht aus der Definition des Programmkopfes
merker=1;

if (aktuellerwert < 62 && aktuellerwert > 30)
merker=2; 

if (aktuellerwert < 93 && aktuellerwert > 61)
merker=3; 

if (aktuellerwert <124 && aktuellerwert > 92)
merker=4;
}

Der Code sieht aktuell so aus, habe nur die Definition der lokalen Variable entfernt. Das Problem habe ich ja schon im letzten Beitrag beschrieben (Wert bleibt immer bei Max.=123, auch wenn ich den Wert für Max änder (z.B. auf 300) bleibt dieser bei max=300)..

Ich verwende einen Arduino UNO :slight_smile:

my_xy_projekt:
4 Zustandsabfragen? 4 Taster? -> an einem Eingang geht das. Du schreibst nicht, was für ein Board....

Sonst vielleicht..

#include <Encoder.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

byte aktuellerWert = 10;
int merker = 2;
const int clk = 6;
const int dt = 5;
int sw = 2;

Encoder meinEncoder(dt, clk); //Erstellen eines neuen Projektes (möglicher Fehler!)

void setup() {
 Serial.begin(9600);
 pinMode(8, OUTPUT); //5V an Pin 8 aktivieren
 digitalWrite(8, HIGH);
 pinMode(sw, INPUT); // Pin 2 als Input für Schalter des encoders
 lcd.init();
 lcd.backlight();
}

void loop()
{
 byte encoderWert = meinEncoder.read(); //Die aktuelle Position des Encoders wird gelesen, mit diesem Wert soll auch in void merkermacher eingestiegen werden!!
 if (encoderWert < 0);
 {
   meinEncoder.write(0); //wenn der Encoderwert kleiner 0 soll 0 angenommen werden (min.Wert)
 }
 if (encoderWert > 123);
 {
   meinEncoder.write(123); //wenn der Encoderwert größer 123 soll 123 angenommen werden (max.Wert)
 }
 aktuellerWert = constrain(encoderWert, 0, 123); // der Wertebereich wird von 0-123 beschränkt
 Serial.println(aktuellerWert);
 lcd.println(merkermacher(aktuellerWert));
}

byte merkermacher(const byte auswahl)
{
 lcd.clear();
 lcd.setCursor(0, 0);
 switch (auswahl)
 {
   case 0 ... 30:
     merker = 1;
     break;
   case 31 ... 61:
     merker = 2;
     break;
   case 62 ... 92:
     merker = 3;
     break;
   case 93 ... 123:
     merker = 4;
     break;
 }
 return merker;
}

Habe den Code auch ausprobiert, gleiches Problem. Der Wert bleibt bei 123..

mdziad:
Der Code sieht aktuell so aus, habe nur die Definition der lokalen Variable entfernt. Das Problem habe ich ja schon im letzten Beitrag beschrieben (Wert bleibt immer bei Max.=123, auch wenn ich den Wert für Max änder (z.B. auf 300) bleibt dieser bei max=300)..

Was macht der Code, der in diesem Example dargestellt ist?

my_xy_projekt:
Was macht der Code, der in diesem Example dargestellt ist?
Nr. 33 - Der Rotary Encoder KY-040 - Funduino - Kits und Anleitungen für Arduino

Der Code läuft. Drehe ich in die eine Richtung, erhöht sich der Wert und drehe ich in die andere Richtung, so verkleinert sich der wert. Jedoch ist hier der Wertebereich nicht beschränkt

mdziad:
Der Code läuft.

Nächster Versuch:

#include <Encoder.h>    // Verwendung der <Encoder.h> Bibliothek 

const int CLK = 6;      // Definition der Pins. CLK an D6, DT an D5.
const int DT = 5;
const int SW = 2;       // Der Switch wird mit Pin D2 Verbunden. ACHTUNG : Verwenden Sie einen interrupt-Pin!
long altePosition = -999;  // Definition der "alten" Position (Diese fiktive alte Position wird benötigt, damit die aktuelle Position später im seriellen Monitor nur dann angezeigt wird, wenn wir den Rotary Head bewegen)

Encoder meinEncoder(DT, CLK); // An dieser Stelle wird ein neues Encoder Projekt erstellt. Dabei wird die Verbindung über die zuvor definierten Varibalen (DT und CLK) hergestellt.

void setup()   // Beginn des Setups
{
  Serial.begin(9600);
  pinMode(SW, INPUT);   // Hier wird der Interrupt installiert.
  attachInterrupt(digitalPinToInterrupt(SW), Interrupt, CHANGE); // Sobald sich der Status (CHANGE) des Interrupt Pins (SW = D2) ändern, soll der Interrupt Befehl (onInterrupt)ausgeführt werden.
}
void loop()
{
  long neuePosition = meinEncoder.read();  // Die "neue" Position des Encoders wird definiert. Dabei wird die aktuelle Position des Encoders über die Variable.Befehl() ausgelesen.
  if (neuePosition != altePosition)  // Sollte die neue Position ungleich der alten (-999) sein (und nur dann!!)...
  {
    neuePosition = constrain(neuePosition, 0, 123);
    meinEncoder.write(neuePosition);
    altePosition = neuePosition;
    Serial.println(neuePosition);      // ...soll die aktuelle Position im seriellen Monitor ausgegeben werden.
  }
}


void Interrupt() // Beginn des Interrupts. Wenn der Rotary Knopf betätigt wird, springt das Programm automatisch an diese Stelle. Nachdem...
{
  Serial.println("Switch betaetigt"); //... das Signal ausgegeben wurde, wird das Programm fortgeführt.
}

my_xy_projekt:
Nächster Versuch:

#include <Encoder.h>    // Verwendung der <Encoder.h> Bibliothek 

const int CLK = 6;      // Definition der Pins. CLK an D6, DT an D5.
const int DT = 5;
const int SW = 2;       // Der Switch wird mit Pin D2 Verbunden. ACHTUNG : Verwenden Sie einen interrupt-Pin!
long altePosition = -999;  // Definition der "alten" Position (Diese fiktive alte Position wird benötigt, damit die aktuelle Position später im seriellen Monitor nur dann angezeigt wird, wenn wir den Rotary Head bewegen)

Encoder meinEncoder(DT, CLK); // An dieser Stelle wird ein neues Encoder Projekt erstellt. Dabei wird die Verbindung über die zuvor definierten Varibalen (DT und CLK) hergestellt.

void setup()   // Beginn des Setups
{
 Serial.begin(9600);
 pinMode(SW, INPUT);   // Hier wird der Interrupt installiert.
 attachInterrupt(digitalPinToInterrupt(SW), Interrupt, CHANGE); // Sobald sich der Status (CHANGE) des Interrupt Pins (SW = D2) ändern, soll der Interrupt Befehl (onInterrupt)ausgeführt werden.
}
void loop()
{
 long neuePosition = meinEncoder.read();  // Die "neue" Position des Encoders wird definiert. Dabei wird die aktuelle Position des Encoders über die Variable.Befehl() ausgelesen.
 if (neuePosition != altePosition)  // Sollte die neue Position ungleich der alten (-999) sein (und nur dann!!)...
 {
   neuePosition = constrain(neuePosition, 0, 123);
   meinEncoder.write(neuePosition);
   altePosition = neuePosition;
   Serial.println(neuePosition);      // ...soll die aktuelle Position im seriellen Monitor ausgegeben werden.
 }
}

void Interrupt() // Beginn des Interrupts. Wenn der Rotary Knopf betätigt wird, springt das Programm automatisch an diese Stelle. Nachdem...
{
 Serial.println("Switch betaetigt"); //... das Signal ausgegeben wurde, wird das Programm fortgeführt.
}

Mega, der Code läuft und tut was er soll! Vielen Dank, dann versuche ich morgen mal das ganze für ein Display-Menü zu verwenden :slight_smile:

Hallo,

oh oh oh. In einem Interrupt benutzt man nichts was selbst einen Interrupt benötigt. Auch wenn Serial hin und wieder in einer ISR funktioniert ist das keine gute Idee. Was mich auch etwas missmutig stimmt, seit wann verwendet man für einen einfachen Taster einen Interrupt?

mdziad:
Mega, der Code läuft und tut was er soll! Vielen Dank, dann versuche ich morgen mal das ganze für ein Display-Menü zu verwenden :slight_smile:

Dann das Ganze mal aus Deinem Code umgebaut - ungetestet, aber zuminndest darstellend, was geht...

#include <Encoder.h>
#include <Wire.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

long letzterWert = 10;

const int clk = 6;
const int dt = 5;
const int sw = 2;

Encoder meinEncoder(dt, clk); //Erstellen eines neuen Projektes (möglicher Fehler!)

void setup() {
  Serial.begin(9600);
  pinMode(8, OUTPUT); //5V an Pin 8 aktivieren
  digitalWrite(8, HIGH);
  pinMode(sw, INPUT); // Pin 2 als Input für Schalter des encoders
  lcd.init();
  lcd.backlight();
}

void loop()
{
  long encoderWert = meinEncoder.read(); //Die aktuelle Position des Encoders wird gelesen, mit diesem Wert soll auch in void merkermacher eingestiegen werden!!
  encoderWert = constrain(encoderWert, 0, 123); // der Wertebereich wird von 0-123 beschränkt
  if (letzterWert != encoderWert)
  {
    Serial.println(encoderWert);
    meinEncoder.write(encoderWert);
    letzerWert = encoderWert;
    lcd.clear();
    lcd.println(merkermacher(encoderWert));
  }
}


byte merkermacher(const byte auswahl)
{
  lcd.clear();
  lcd.setCursor(0, 0);
  byte merker = 0;
  switch (auswahl)
  {
    case 0 ... 30:
      merker = 1;
      break;
    case 31 ... 61:
      merker = 2;
      break;
    case 62 ... 92:
      merker = 3;
      break;
    case 93 ... 123:
      merker = 4;
      break;
  }
  return merker;
}

Doc_Arduino:
oh oh oh. In einem Interrupt benutzt man nichts was selbst einen Interrupt benötigt.

Das Beispiel kam nicht von mir - es war und ist nur die Frage zu lösen was da tatsächlich passiert, da ja in den letzten Posts nichts wirklich rauskam, was half.

Sowas würde ich einem Neuling erst gar nicht zeigen. Hier hätte man eine Funktion mit millis zeigen können.

Ja.. Sowas gibt es eben halt. Ob ich das weiterverwende was andere zeigen, darüber kann man geteilter Meinung sein.
Es war nur die Funktionalität des Encoders gefragt - das Beiwerk hab ich ehrlich gesagt nicht mal beachtet.
Und in einer nie genutzten ISR kann man auch ein Serial.println() reinschreiben :wink:

Aberja, so bissl recht hast ja....

Hallo,

:slight_smile: Hauptsache der TO kommt klar. Ansonsten kann er ja fragen ... :slight_smile:

Ich habe gestern nochmal das ganze mit dem Display ausprobiert. Hierbei ist mir aufgefallen, dass sehr oft die Meldung "Switch betätigt" kam, obwohl ich diesen garnicht gedrückt habe. Das hängt dann wohl vermutlich mit dem "interrupt" zusammen, den Doc_Arduino erwähnt hat? Was genau hat es mit der Millis Funktion auf sich ?

Aktuell habe ich das Gefühl, dass der Code für mein Anliegen noch keineswegs zielführend ist :frowning: Sobald ich das Display verkabel und einbeziehe, steigen die Werte (0-123) beim Drehen viel schneller, als sie beim Drehen in die entgegengesetzte Richtung sinken..

Soll ich meinen aktuellen Code nochmals posten?

Gibt es von euch vielleicht andere Tipps zur Umsetzung meines Anliegens? Vielleicht bin ich mit dem Code ja auch auf dem Holzweg..

Nochmal zum Anliegen: Ich möchte dass auf dem Display folgendes Bild erscheint:

| Bitte Größe wählen: |
| klein |

nachdem der Encoder etwas gedreht wurde :
| Bitte Größe wählen: |
| mittel |

hinter klein und mittel soll dann eine Pumpe für eine gewisse Zeit angesteuert werden nachdem ich den button/switch betätigt habe (bei "klein" z.B. für 20 Sekunden,bei "mittel" für 30 Sekunden usw.)

Vielleicht habt ihr ja allgemeine Vorschläge oder Codes, mit denen ich dieses Anliegen erfüllen kann :slight_smile:

mdziad:
Hierbei ist mir aufgefallen, dass sehr oft die Meldung "Switch betätigt" kam, obwohl ich diesen garnicht gedrückt habe. Das hängt dann wohl vermutlich mit dem "interrupt" zusammen, den Doc_Arduino erwähnt hat?

Ja... Da kommt dann wohl ein EMV-Problem auf Dich zu, wenn es kein Kontaktproblem ist. (Steckbrett)
Es geht auch ohne die ISR.
Schönes Beispiel von agmue:
https://forum.arduino.cc/index.php?topic=701098.0

Da ist auch das mit den millis() drin...

Hallo,

der Pin für den Switch ist nur als Input konfiguriert. Du brauchst zwingend einen Pullup oder Pulldown am Eingang.
Dann ist dieser eine Spuk vorbei. Der µC bringt einen internen Pullup mit.

Der andere Spuk ist, dein Taster prellt und dadurch kommt es zu mehrfach Auslösungen, die du wahrscheinlich auch schon mitbekommen hast.

Bsp. mit millis bringt die IDE mit. Andere Erklärungen zur Nutzung von millis haben diese netten User geschrieben.

Theseus erklärt millis()

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung

Danach solltest du den Taster zyklisch aller paar ms (bspw. 30) abfragen können ohne die loop zu blockieren und ohne Interrupt.

Wenn du dich für das Eingemachte interessiert, kann ich dir diese Lektüre empfehlen.
https://www.mikrocontroller.net/articles/Entprellung