Zähler

Hallo brauche mal wieder Eure Hilfe

Bei dem Sketch soll der Zähler „ ZaehlerAchseX „ bei betätigen des Tasters „TasterXPlus„ den Wert um 1 hoch zählen und bei betätigen des Tasters „TasterXMinus“ den Wert um 1 runter zählen, egal wie lange die Taster betätigt werden.
Die Werte werden hoch und runter gezählt, aber nicht um den Wert 1.

Was habe ich falsch gemacht?

Gruß BJS

    const int TasterXPlus = 8;
    int TasterXPlusStatus;
    const int TasterXMinus = 7;
    int TasterXMinusStatus;
    
    int ZaehlerAchseX;
    int AchseX = 0;
    
    void setup()
    {
      Serial.begin(9600);
      pinMode(TasterXPlus, INPUT_PULLUP);
      pinMode(TasterXMinus, INPUT_PULLUP);
    }
    
    void loop()
    {
      TasterXPlusStatus = digitalRead(TasterXPlus);
      if (TasterXPlusStatus == LOW)
      {
        AchseX = 1;
      }
      if (TasterXPlusStatus == HIGH && AchseX == 1)
      {
        ZaehlerAchseX++;
        AchseX = 0;
      }
      Serial.println(ZaehlerAchseX);
    
    
      TasterXMinusStatus = digitalRead(TasterXMinus);
      if (TasterXMinusStatus == LOW)
      {
        AchseX = 1;
      }
      if (TasterXMinusStatus == HIGH && AchseX == 1)
      {
        ZaehlerAchseX--;
        AchseX = 0;
      }
      Serial.println(ZaehlerAchseX);
    }

Schalter/Taster prellen, d.h. sie geben mehrere Impulse pro Schaltvorgang.
Stichworte: Entprellen, Bounce, Debounce

Gruß Tommy

Frage Deine Taster alle 30 ms ab und Du hast sie entprellt.

Ich habe die Taster mit 30, 100 und 200 ms abgefragt. Wenn ich länger als die eingestellte Zeit den Taster betätige, zählt er weiter. Nicht so schnell aber er zählt weiter.

Hi

Nach dem Erkennen, daß der Taster gedrückt wurde, musst Du auch darauf warten, daß der Taster wieder los gelassen wird.
Z.B. mit einer einfachen While-Schleife - blockiert aber den Code.

Zum Debonce fiel mir gerade ein Link vor die Füße:
Debounce auf popovic.info

MfG

Das Problem kann nicht die Tasterentprellung sein.

Nachfolgend der original Sketch der einwandfrei funktioniert.
Hier zählt der Zähler bei loslassen des Tasters hoch.
Ich habe den Sketch umgeschrieben das er hoch und runter Zählt, was mir nicht gut gelungen ist.

const int TasterXPlus = 8;                                     
int TasterXPlusStatus;                                        

int ZaehlerAchseX;                                                  
int AchseX = 0;                                               

void setup() {
  Serial.begin(9600);
  pinMode(TasterXPlus, INPUT_PULLUP);                         
}

void loop() {
  TasterXPlusStatus = digitalRead(TasterXPlus);                
  if (TasterXPlusStatus == LOW)                               
  {
    AchseX = 1;                                               
  }
  if (TasterXPlusStatus == HIGH && AchseX == 1)               
  {
    ZaehlerAchseX++;                                                
    AchseX = 0;                                              
  }
  Serial.println(ZaehlerAchseX);                                 
}

postmaster-ino:
Zum Debonce fiel mir gerade ein Link vor die Füße:
Debounce auf popovic.info

Warum kommt ihr eigentlich immer wieder mit diesen debounce-Libs daher? Die sind doch nur unnütze Ressourcen-Fresser.
Wie es geht hat doch oben schon agmue beschrieben: Den Taster einfach nur alle 30ms abfragen und gut is. Das Abfrageintervall muss nur größer als die Prellzeit der Taster sein.

@BJS-1952:
Grundsätzlich verwendest Du ja schon eine Statusvariable für die Flankenerkennung: AchseX
Dein Problem ist, dass Du für beide Tasten die gleiche verwendest. Du brauchst für jede Taste eine eigene Statusvariable.

So geht es:

const int TasterXPlus = 8;
bool TasterXPlusStatus;
bool AchseXPlus = 0;
const int TasterXMinus = 7;
bool TasterXMinusStatus;
bool AchseXMinus = 0;
uint32_t aktMillis, altMillis;

int ZaehlerAchseX;

void setup()
{
  Serial.begin(9600);
  pinMode(TasterXPlus, INPUT_PULLUP);
  pinMode(TasterXMinus, INPUT_PULLUP);
}

void loop()
{
  aktMillis = millis();
  if (aktMillis - altMillis >= 30) {
    altMillis = aktMillis;
    AchseXPlus = TasterXPlusStatus;
    TasterXPlusStatus = digitalRead(TasterXPlus);
    if (TasterXPlusStatus && !AchseXPlus)
    {
      ZaehlerAchseX++;
      Serial.println(ZaehlerAchseX);
    }

    AchseXMinus = TasterXMinusStatus;
    TasterXMinusStatus = digitalRead(TasterXMinus);
    if (TasterXMinusStatus && !AchseXMinus)
    {
      ZaehlerAchseX--;
      Serial.println(ZaehlerAchseX);
    }
  }
}

Hi

MicroBahner:
Warum kommt ihr eigentlich immer wieder mit diesen debounce-Libs daher?

Immer ist wohl etwas übertrieben - bisher genau 1x allerdings war es eher Zufall, daß Da eine Lib verlinkt ist - mir ging es eher um das geschriebene Wort dort.
Wenn aber diese Lib ein Arduino-No-Go ist, hätte ich Das gerne gewusst - vll. mit Erklärung, macht die Sache 'runder'.
(sofern mehr als 'unnötiger Ballast' gegen diese Lib spricht)

Der Grund für den Link:
Probleme mit prellenden Kontakten UND über eine Auslassung zu diesem Thema gestolpert - eigentlich dachte ich, Das würde ganz gut zusammen passen.
AUCH, wenn eine andere Lösung bereits genannt wurde.

MfG

postmaster-ino:
Immer ist wohl etwas übertrieben

Sorry, das 'immer' war nicht an dich persönlich gerichtet. Aber es wird hier sehr oft auf die Lib hingewiesen. Dabei geht es mit der Methode von agmue viel einfacher und effizienter - vor allem wenn mehrere Taster eingelesen werden sollen. Im Parallelforum hatte ich das Verfahren auch schonmal erklärt. Ist vielleicht auch für den TE interessant.

Debounce-Libs sind kein NoGo für die Allgemeinheit. Es kommt halt nur immer darauf an, was hinter der Tasterabfrage hängt. Wenn das lange genug dauert, macht das die Entprellung quasi schon allein.

Gruß Tommy

Danke

Es dauert halt doch noch eine Weile bis ich aus dem Anfängerstatus herauskomme.

Gruß BJS

Hallo jetzt brauche ich doch nochmal Eure Hilfe

Wenn ich den TasterXPlus betätige erscheint am Seriellen Monitor eine 1und gleichzeitig soll LED1 leuchten.
Bei erneutem betätigen von TasterXPlus erscheint am Seriellen Monitor eine 2 und gleichzeitig soll LED1 ausgehen und LED2 leuchten.
Bei betätigen von TasterXMinus erscheint am Seriellen Monitor eine 1 und gleichzeitig soll LED2 ausgehen und LED1 leuchten.
Irgendwie habe ich mir das einfacher vorgestellt und bin mit meinem Sketch mal wieder auf dem Holzweg.

Würde mich freuen, wenn man mir noch einmal hilft.

Danke im Voraus.

const int TasterXPlus = 8;
bool TasterXPlusStatus;
bool AchseXPlus = 0;
const int TasterXMinus = 7;
bool TasterXMinusStatus;
bool AchseXMinus = 0;
uint32_t aktMillis, altMillis;

int ZaehlerAchseX;
bool ZaehlerAchseXStatus;

int LED1 = 12;
int LED2 = 13;

void setup()
{
  Serial.begin(9600);
  pinMode(TasterXPlus, INPUT_PULLUP);
  pinMode(TasterXMinus, INPUT_PULLUP);

  pinMode (LED1, OUTPUT);
  pinMode (LED2, OUTPUT);
}

void loop()
{
  aktMillis = millis();
  if (aktMillis - altMillis >= 30)
  {
    altMillis = aktMillis;
    AchseXPlus = TasterXPlusStatus;
    TasterXPlusStatus = digitalRead(TasterXPlus);
    if (TasterXPlusStatus && !AchseXPlus)
    {
      ZaehlerAchseX++;
      Serial.println(ZaehlerAchseX);

      ZaehlerAchseXStatus = (ZaehlerAchseX);
      if (ZaehlerAchseXStatus == 1)
      {
        digitalWrite(LED1, HIGH);
      }
      if (ZaehlerAchseXStatus == 2)
      {
        digitalWrite(LED1, LOW);
        digitalWrite(LED2, HIGH);
      }
    }
    
    AchseXMinus = TasterXMinusStatus;
    TasterXMinusStatus = digitalRead(TasterXMinus);
    if (TasterXMinusStatus && !AchseXMinus)
    {
      ZaehlerAchseX--;
      Serial.println(ZaehlerAchseX);

      ZaehlerAchseXStatus = (ZaehlerAchseX);
      if (ZaehlerAchseXStatus == 1)
      {
        digitalWrite(LED2, LOW);
        digitalWrite(LED1, HIGH);
      }
    }
  }
}

Hallo BJS,
das Problem ist deine Variable ZaehlerAchseXStatus. Wozu brauchst Du die überhaupt?
Du kannst doch in den Abfragen auf 1 bzw. 2 direkt ZahlerAchseX verwenden.
Ausserden ist ZaehlerAchseXStatus als boolean definiert, da macht es keinen Sinn mit 2 zu vergleichen.