26.04.2019, 18:08
Da ich in meinen Projekten oftmals einen oder mehrere Taster verwende und ich zum entprellen nicht gleich eine "riesige" Library einbinden will, habe ich mal eine kleine PushButton-Klasse geschrieben. Die verbraucht nur wenig Speicher und hat doch alles, was ich so brauche (inkl. konfigurierbarer Tastenwiederholung).
Diese Klasse verwendet keine Interrupts!
Der Tastenzustand wird jedes Mal bei "Btn.pressed()" ausgelesen, was bedeutet, dass die Methode jedes Mal in der Loop-Funktion aufgerufen werden muss.
Und die Loop-Funktion darf nicht blockierend programmiert sein (was sich sowieso von selbst verstehen sollte). Delays unbedingt vermeiden!
Im Anhang befindet sich noch ein Beispiel-Sketch für einen Arduino-Nano.
Diese Klasse verwendet keine Interrupts!
Der Tastenzustand wird jedes Mal bei "Btn.pressed()" ausgelesen, was bedeutet, dass die Methode jedes Mal in der Loop-Funktion aufgerufen werden muss.
Und die Loop-Funktion darf nicht blockierend programmiert sein (was sich sowieso von selbst verstehen sollte). Delays unbedingt vermeiden!
Show ContentPushButton.h:
Code:
#ifndef PushButton_h
#define PushButton_h 1
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
/****************************************************************************************************************
PushButton-Klasse zum entprellen von Tastern
Version: 1.0.0.1 (26.04.2019)
Autor: Thomas Stephan (Gorathan)
Homepage: https://forum.technik-hobby.de
PushButton-Parameter:
Anschluss-Pin (0...255)
Pinmodus (0 = INPUT, 1 = INPUT_PULLUP, Standard = 1)
Reaktion (0 = LOW-aktiv, 1 = HIGH-aktiv, Standard = 0)
Entprellzeit (0...255 in ms, Standard = 30)
Wiederholzeit (0...65535 in ms, Standard = 0 / keine Tastenwiederholung)
Verzoegerungszeit (0...65535 in ms, Standard = 500) bis zur ersten Tastenwiederholung
Beispiel: [] = optional
PushButton Btn(Anschluss-Pin[, Pinmodus][, Reaktion][, Entprellzeit][, Wiederholzeit][, Verzoegerungszeit]);
Abfrage:
if (Btn.pressed()) {...}
Wiederholzeit setzen:
Btn.setRepeatTime(repeatTime, delayTime);
*****************************************************************************************************************/
class PushButton {
private:
const uint8_t _pin, _dbTime;
const bool _edge;
uint16_t _RepeatTime, _DelayTime;
bool _newState, _oldState, _state, _1stClick;
uint32_t _dbMillis, _repMillis;
public:
// Konstruktor
PushButton(const uint8_t pin, const bool pullup = 1, const bool edge = 0, \
const uint8_t dbTime = 30, const uint16_t repeatTime = 0, const uint16_t delayTime = 500);
// Methoden
bool pressed(void);
void setRepeatTime(const uint16_t repeatTime, const uint16_t delayTime = 500) {
_RepeatTime = repeatTime;
_DelayTime = delayTime;
};
};
#endif
Show ContentPushButton.cpp:
Code:
#include "PushButton.h"
/***** Konstruktor *****/
PushButton::PushButton(const uint8_t pin, const bool pullup, const bool edge, \
const uint8_t dbTime, const uint16_t repeatTime, const uint16_t delayTime):
_pin(pin), _edge(edge), _dbTime(dbTime), _RepeatTime(repeatTime), _DelayTime(delayTime)
{
pinMode(pin, pullup ? INPUT_PULLUP : INPUT);
}
/***** Methode *****/
bool PushButton::pressed(void) {
const uint32_t nowMillis = millis();
bool pressed = false;
_newState = digitalRead(_pin) == _edge;
if (_newState != _oldState) {
if (nowMillis - _dbMillis > _dbTime) {
_repMillis = nowMillis;
_1stClick = true;
_oldState = _newState;
if (_newState) pressed = true;
}
_dbMillis = nowMillis;
} else if (_RepeatTime && _newState && nowMillis - _repMillis > _RepeatTime + _1stClick * _DelayTime) {
_repMillis = nowMillis;
_state ^= 1;
_1stClick = false;
pressed = _state;
}
return pressed;
}
Im Anhang befindet sich noch ein Beispiel-Sketch für einen Arduino-Nano.