Debouncing, Ständiger analog read

Hallo
Um das Forum nicht zu zuspamen hab ich 2 Probleme in einen Thread verpackt.

Projekt ist eine Steuerung für diverse LEDs. Für den Prototypen ists auf 3 Dioden beschränkt. Mit einem Tastschalter sollen diverese Modi durchgeschaltet werden (blinken, faden, durchlauf, etc.). Ein Poti regelt die Geschwindigkeit, und eins dimmt (via a.Read).

  1. Ich versuche nun seit Stunden am Debouncing eines Tastschalters. Leider werd ich trotz dem Lesen/schauen diverser Anleitungen nicht schlau. Das ding scheint ja zu sein, dass der Wert über eine gewisse zeit tief sein muss, um einen hohen Wert als gültig zu erklären.
    Jedoch bin ich mit der Bibliothek etwas überfordert.

  2. Der Analog Read wird nur am anfang des Loops ausgeführt. Wenn ich aber jetzt den Val. welcher die Delayzeit bestimmt auf sehr langsam gestellt habe, gehts natürlich eine Ewigkeit, bis der Loop durch ist und der a.Read neu ausgewertet wird. Gibts dagegen eine saubere Lösung? ICh möchte, dass sobald ich am poti drehe, die Geschwindigkeit verändert wird.

Ausserdem scheint er irgenwie nicht mehr in den Modus 0 schalten zu wollen, sobald ich einmal durchgeklickt habe.

int const GRUN = 10;
int const GELB = 9;
int const ROT = 6;
int BUTTON1 = 7;
int val1 = 50;   //Dimmer
int val2 = 50;   //Geschwindigkei
int modus = 0;

void setup()
{
  pinMode (GRUN, OUTPUT);
  pinMode (GELB, OUTPUT);
  pinMode (ROT, OUTPUT);
pinMode (BUTTON1, INPUT);

}
void loop() {

  val1 = analogRead (A15);
  val2 = analogRead (A14);

    if (val1 < 50){
    val1 = 50;}
  if (val1 > 1000){
    val1 =1000;}
  if (val2 < 100){
    val2 = 100;}
  if (val2 > 1000){
    val2 = 1000;}
 
  
  if (digitalRead (BUTTON1) == HIGH){
    modus++;
    delay (10);
  }

  if (modus == 0){                    //Kein programm, alle LEDs dunkel  
    digitalWrite (GRUN, LOW);
    digitalWrite (GELB, LOW);
    digitalWrite (ROT, LOW);

   
  }
 
  if (modus == 1){                 //Programm 1, LED Durchlauf
  analogWrite (GRUN, val1/8);
  digitalWrite (GELB, LOW);
  digitalWrite (ROT, LOW);
  delay (val2);
  analogWrite (GELB, val1/32);
  digitalWrite (GRUN, LOW);
  digitalWrite (ROT, LOW);
  delay (val2);
  analogWrite (ROT, val1/50);
  digitalWrite (GRUN, LOW);
  digitalWrite (GELB, LOW);
  delay (val2);
  }

  if (modus == 2){                 // Programm 2, Alle LEDs blinken gleichzeitig
    analogWrite (GRUN, val1/8);
    analogWrite (GELB, val1/32);
    analogWrite (ROT, val1/50);
     delay (val2);
    digitalWrite (GRUN, LOW);
    digitalWrite (GELB, LOW);
    digitalWrite (ROT, LOW);
     delay (val2);
  
     }

if (modus > 2){                   //Schaltet zurück auf Programm 0
  modus = 0;}
  }
  if (digitalRead (BUTTON1) == HIGH){[color=#222222][/color]
    modus++;[color=#222222][/color]
    delay (20);[color=#222222][/color]
  }

Reicht bei wenigen Tastern vollkommen aus. Jedoch solltes du die anderen delays in deinem Programm entfernen! -> BlinkWithoutDelay. Denn solange die aktiv sind, dauert es ewig, bis der Tastr erneut gelesen werden kann.

Wenn ich aber jetzt den Val. welcher die Delayzeit bestimmt auf sehr langsam gestellt habe, gehts natürlich eine Ewigkeit, bis der Loop durch ist und der a.Read neu ausgewertet wird. Gibts dagegen eine saubere Lösung? ICh möchte, dass sobald ich am poti drehe, die Geschwindigkeit verändert wird.

Die saubere Lösung gibt es! Schön dass du selbst mekst, dass delay dafür nichts taugt:

Such mal Blink without Delay in den Beispielen.

Du merkst dir die Zeit (z.B. des letzten Wechsels) und kriegst so in jedem loop() Durchlauf raus, wie lange das her war.

loop kommt dann mehrfach je millisekunde dran (obwohl analogRead relativ langsam ist)

Beim Taster Abfragen musst du in der Regel natürlich wissen, ob der aktuelle Zustand "neu" ist, oder ob du schon reagiert hast. Das isat was anderes als Prellen :wink:

Um Prellen zu vermeiden, frage ich nur alle 20ms die Taster ab und speichere die Zustände in Statusvariablen. In diese Abfrage kann man auch dasanalog.Read mit reinpacken.

Alle 20ms abzufragen ist aber kein richtiges Entprellen. Hier können Fehler entstehen.

sschultewolter:
Alle 20ms abzufragen ist aber kein richtiges Entprellen. Hier können Fehler entstehen.

Kann durchaus sein. Ist aber einfach, und wenn man den Finger drauf lässt, kann man auch sehr einfach Werte hoch- und runterzählen. Und mit MCP230xx funtionierts auch. :smiley:

Ja, in den meisten Fällen kann das schon reichen. Nutze für sowas von Peter Dannegger die Komfort-Entprellroutine.
Beim MCP23xxx brauchst du eigentlich nicht sonderlich entprellen Die Eingänge der ICs fangen da schon gut was ab.