Multifunktionstaster- Toggeln und Ein/Aus für LED

Hallo zusammen, ich hatte es in diesem Thread ja schon angesprochen: http://forum.arduino.cc/index.php?topic=128558.0 ... es bahn sich 'was an ;-)

Wie evtl. schon erwähnt: Ich bin absoluter Newbie.

Aufgabenstellung: Schalte eine 3-stufig dimmbare 12V LED.

Das reine "Toggeln" war recht einfach umsetzbar:

https://www.youtube.com/watch?v=uXRPARqqMto

Jetzt habe ich noch versucht das in den Conde von der "Zeitsteuerung" einzubauen.

// Abschnitt für Toggeln
const int ledPin1 = 1; 
const int ledPin2 = 2; 
const int ledPin3 = 4; 
int count = 0; 
boolean lastButton; 
boolean currentButton = false;
boolean ledOn = false;


// Abschnitt für Abfrage Druckzeit
int tastehoch = 0;
int tastehochState = 0;
int druckzeit = 2000; //zeit die es brauch damit taster anspricht
unsigned long aktuellezeit;
unsigned long vorherigezeit;
int a = 0;


// VOID SETUP()
void setup()
{
// Abschnitt Toggeln
pinMode(tastehoch, INPUT);
pinMode(ledPin1, OUTPUT); 
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
count = 0;
digitalWrite(ledPin1, HIGH); 
digitalWrite(tastehoch, HIGH);
}
//debounce function to stabilise the button
boolean debounce(boolean last)
{
boolean current = digitalRead(tastehoch);
if (last != current)
{
delay(5);
current = digitalRead(tastehoch);
}
return current;


// Abschnitt Druckzeit
  pinMode(tastehoch, INPUT);
  //pinMode(13, OUTPUT);
  digitalWrite(tastehoch, HIGH);
}



// VOID LOOP()
void loop()
{  
  tastehochState = !digitalRead(tastehoch);
                                             
  if (tastehochState == HIGH)
  {
    if (a == 0)
    {
      vorherigezeit = millis();
      a = 1;
    }
    aktuellezeit = millis();
    if (aktuellezeit - vorherigezeit >= druckzeit)
    // Abschnitt ausschalten
    {
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, LOW);
    }
  }
  else
  {
   lastButton = currentButton;
currentButton = debounce(lastButton);
if (lastButton == false && currentButton == true)
{
if (count == 0)
{
count++;
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
}
else if (count == 1)
{
count++;
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, LOW);
}
else if (count == 2)
{
count = 0;
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, HIGH);
}
}
    a = 0;
  }
}

... und läuft ... leider nicht optimal.

  1. Das Toggeln reagiert nicht auf jeden Tastendruck. Man muss tw schon mehrfach drücken.
  2. Nach dem Ausschalten geht tw eine LED wieder an. Aber nur wenn ich von LED 2 und 3 ausschalte, geht dann die folgende LED wieder an. Also 3 und 1. Aber auch nicht immer. Wenn ich von LED 1 aus ausschalte bleibt alles aus.
  3. Das Wiedereinschalten funktioniert auch nur auf mehrfachen Tastendruck "sporadisch".

Wie gesagt: Ich bin Newbie und der Code ist bestimmt hoffnunglos kompliziert und umständlich.

Danke und Gruß der "Stevie"

Hallo,

ohne ordentliche Einrückung ist der Code sehr schlecht lesbar. Vorallendingen mit den vielen if Verschachtelungen.

Bsp. bessere Lesbarkeit

// VOID LOOP()
void loop()  { 
  tastehochState = !digitalRead(tastehoch);
                                             
  if (tastehochState == HIGH)  {
    if (a == 0)  {
      vorherigezeit = millis();
      a = 1;
    }
    aktuellezeit = millis();
    if (aktuellezeit - vorherigezeit >= druckzeit)  {
      // Abschnitt ausschalten
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      digitalWrite(ledPin3, LOW);
    }
  }
  else  {
    lastButton = currentButton;
    currentButton = debounce(lastButton);
    if (lastButton == false && currentButton == true)  {
      if (count == 0)  {
        count++;
        digitalWrite(ledPin1, HIGH);
        digitalWrite(ledPin2, LOW);
        digitalWrite(ledPin3, LOW);
      }
      else if (count == 1)  {
        count++;
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, HIGH);
        digitalWrite(ledPin3, LOW);
      }
      else if (count == 2)  { 
        count = 0;
        digitalWrite(ledPin1, LOW);
        digitalWrite(ledPin2, LOW);
        digitalWrite(ledPin3, HIGH);
      }
    }
    a = 0;
  }
}

nur irgendwie fehlt mir was beim bouncen. Ist das wirklich der komplette Code? Ohne Bounce Librarie? Denn mir fehlt zum Bsp. die Entprellzeit vom Taster. Dein "druckzeit" verstehe ich auch anders. Das ist sicherlich die Zeit, die gewartet wird, in der man den Taster nicht drückt und dann die LED ausschaltet.

Du möchtest einen Taster drücken, erste LED geht an, innerhalb einer gewissen Wartezeit wieder drücken, 2. LED geht an, wieder drücken innerhalb einer Zeit, 3. LED geht. Wartet man zu lange mit dem Taster drücken gehen alle LEDs aus. Richtig?

Doc_Arduino: Hallo,

ohne ordentliche Einrückung ist der Code sehr schlecht lesbar. Vorallendingen mit den vielen if Verschachtelungen.

Bsp. bessere Lesbarkeit

// VOID LOOP()
void loop()  { 
  tastehochState = !digitalRead(tastehoch);
                                             
 ...
    a = 0;
  }
}

.... danke. Ja, werde ich in Zukunft beachten. Musste mal wieder schnell gehen ;-)

Doc_Arduino: nur irgendwie fehlt mir was beim bouncen. Ist das wirklich der komplette Code? Ohne Bounce Librarie? Denn mir fehlt zum Bsp. die Entprellzeit vom Taster. Dein "druckzeit" verstehe ich auch anders. Das ist sicherlich die Zeit, die gewartet wird, in der man den Taster nicht drückt und dann die LED ausschaltet.

Du möchtest einen Taster drücken, erste LED geht an, innerhalb einer gewissen Wartezeit wieder drücken, 2. LED geht an, wieder drücken innerhalb einer Zeit, 3. LED geht. Wartet man zu lange mit dem Taster drücken gehen alle LEDs aus. Richtig?

... ich habe den Debounce-Codeschnipsel "irgendwo" im Netzt gefunden. So wie es aussieht kommt diese Debounce-Funktion ohne die Debounce Library aus. Ja, das ist der komplette Code. Es werden ja "nur" boolsche Werte verglichen und dann ein delay vom 5ms zwischengeschoben. So meine Interpretation. Die "druckzeit" ist die Zeit, die der Taster gedrückt gehalten werden muss, um die gerade leuchtende LED auszuschalten.

Die drei LEDs sollen unabhängig von einer Zeit durchgeschaltet werden können. Der erste Tastendruck schaltet LED 1 ein. Es leuchtet immer nur eine LED! Die entsprechend leuchtende LED soll bei Bedarf über das Halten des Tasters für 2 sek. ausgeschaltet werden können.

Danke und Gruß der "Stevie"

Hallo,

hab mich mal schlau gemacht. Es gibt doch tatsächlich eine integrierte Debounce Lib in der IDE. Oh ha. :) Sieht man aber nur in den mitgelieferten Bsp. Ich habe bisher immer eine zusätzliche externe (Bounce2) Lib eingebunden.

Dir fehlt nämlich noch die Vorgabe der Taster Entprellzeit. Deshalb vermute ich ein Tasten prellen bei dir, worauf dein Code nicht ganz das macht was er soll, weil dein µC sehr schnell ist und pro Tastendruck mehrere High/Low Wechsel sieht und diese auch verarbeitet. Und wenn du im Code auf High-Pegel abfragst, hast Du einen Pulldown Widerstand extern dran?

Den originalen Code zum Debounce findest Du in der IDE unter: Datei > Beispiele > Digital > Debounce

Guck dir das nochmal in Ruhe an und probiere, ansonsten, ich/wir sind immer da. :)

Edit: bau das vielleicht erstmal klein auf. Also das du mit jedem Tastendruck nur eine LED sicher umschaltest. Wenn das stabil funktioniert, kannste alle LEDs reinnehmen.

Doc_Arduino: Hallo,

hab mich mal schlau gemacht. Es gibt doch tatsächlich eine integrierte Debounce Lib in der IDE. Oh ha. :) Sieht man aber nur in den mitgelieferten Bsp. Ich habe bisher immer eine zusätzliche externe (Bounce2) Lib eingebunden.

Dir fehlt nämlich noch die Vorgabe der Taster Entprellzeit. Deshalb vermute ich ein Tasten prellen bei dir, worauf dein Code nicht ganz das macht was er soll, weil dein µC sehr schnell ist und pro Tastendruck mehrere High/Low Wechsel sieht und diese auch verarbeitet. Und wenn du im Code auf High-Pegel abfragst, hast Du einen Pulldown Widerstand extern dran?

... hmmm ??? Aber ist das "delay(5)" nicht die Entprellzeit?

Und über "digitalWrite(tastehoch, HIGH) ist doch der interne Pullup aktiviert. Den Taster schalt ich gegen Masse.

Doc_Arduino: Den originalen Code zum Debounce findest Du in der IDE unter: Datei > Beispiele > Digital > Debounce

Guck dir das nochmal in Ruhe an und probiere, ansonsten, ich/wir sind immer da. :)

Edit: bau das vielleicht erstmal klein auf. Also das du mit jedem Tastendruck nur eine LED sicher umschaltest. Wenn das stabil funktioniert, kannste alle LEDs reinnehmen.

... das Interessante ist ja, dass der Code ohne die Erweiterung um die Funktion des "Gedrückt-Haltens" funktioniert hat. Also toggeln ohne Problem. Nix Prellen. Ich schau mir auch nochmal den Code des "mitgebrachten" Debouncen" an und was meine hier zur Verfügung stehende "Fachliteratur" dazu sagt.

EDITH sagt: Jetzt hab ich noch eine Idee: Um sicher zu gehen, dass es "nur" am Prellen" liegt könnte ich doch auch auf einem parallel installierten Arduino den "Entprell-Code" laufen lassen, der dann den "Taster" am anderen Arduino mit dem Toggle Code simuliert. Klingt umständlich - ist es auch ;-)

Danke und Gruß der "Stevie"

Kann man nicht Taster besser entprellen, wenn man sie alle z.B. 20ms abfragt anstatt ein delay (auch wenn es nur 5ms sind) zu verwenden?

Dann könnte man ja einen Zähler inkrementieren und darüber den langen Klick abfragen.

Hallo,

eigentlich nimmt man dafür schon millis statt delay, hier mag das noch funktionieren. Sonst blockiert man seinen kompletten Programmablauf.

Habe mir deinen Code nochmal angeschaut. Jetzt fällt mir auf, der ist total wild zusammengeschustert. Der Taster Input ist doppelt deklariert. Und die Debounce Funktion steht in Setup. Die gehört in die loop. Der Code kann nie funktioniert haben.

Also guck dir nochmal den original Code an und versuche ihn zu verstehen. Darin wird auf erkannten Tastendruck hin eine LED umgeschaltet. Du müßtest jetzt die Tastendruckerkennung dazu nutzen einen Zähler hochzuzählen und [u]danach[/u] je nach Zählerstand eine Aktion ausführen um die gewünschten LED zuschalten.

Deine Anfangsdefinitionen solltest Du aufräumen und nicht wild verstreuen. Und vorallendingen kommentieren.

Vorschlag, nimm den Bsp. Code und lasse erstmal auf Tastendruck hin einen Zähler zählen. Wenn das klappt, lasse ihn nur von 0 bis 3 und bei nach 3 wieder auf 0 springen.

Dazu solltest Du die Pins 0 und 1 nicht belegen. Die sollten für die serielle zum debugen frei bleiben.

Doc_Arduino: Hallo, ..... Und wenn du im Code auf High-Pegel abfragst, hast Du einen Pulldown Widerstand extern dran?

... natürlich nicht.

Wobei mir dazu etwas aufgefallen ist. Ich war davon ausgegangen, dass wenn ich den PIin auf "High" lege, automatisch der interne Pullup-Widerstand "aktiviert" wird.

Jetzt habe ich aber eine interessante Entdeckung gemacht ;-) Wenn ich "pinMode (Pin, INPUT_PULLUP)" versuche auf meinen Digispark zu spielen, kommt eine Fehlermeldung. Beim Nano und Mini Pro nicht. Haben die Programmer unterschiedliche Befehlssätze?

Doc_Arduino: Hallo,

eigentlich nimmt man dafür schon millis statt delay, hier mag das noch funktionieren. Sonst blockiert man seinen kompletten Programmablauf.

Habe mir deinen Code nochmal angeschaut. Jetzt fällt mir auf, der ist total wild zusammengeschustert. Der Taster Input ist doppelt deklariert. Und die Debounce Funktion steht in Setup. Die gehört in die loop. Der Code kann nie funktioniert haben.

Also guck dir nochmal den original Code an und versuche ihn zu verstehen. Darin wird auf erkannten Tastendruck hin eine LED umgeschaltet. Du müßtest jetzt die Tastendruckerkennung dazu nutzen einen Zähler hochzuzählen und [u]danach[/u] je nach Zählerstand eine Aktion ausführen um die gewünschten LED zuschalten.

Deine Anfangsdefinitionen solltest Du aufräumen und nicht wild verstreuen. Und vorallendingen kommentieren.

Vorschlag, nimm den Bsp. Code und lasse erstmal auf Tastendruck hin einen Zähler zählen. Wenn das klappt, lasse ihn nur von 0 bis 3 und bei nach 3 wieder auf 0 springen.

Dazu solltest Du die Pins 0 und 1 nicht belegen. Die sollten für die serielle zum debugen frei bleiben.

... jaja, ich weiß. Total chaotisch. Ich bin jetzt dabei zu entrümpeln und noch mehr zu verstehen.. Ich taste mich langsam ran.

Danke bis hierher und Gruß der "Stevie"