TSwitch (Arduino Library)

The second library component I would like to present is TSwitch. TSwitch handles hardware switches attached to the Arduino. It does the debouncing, reads the state and detects long and short press (aka doubleclick) :

The easiest way to instantiate the class is (for more details please refer to the  code):

TSwitch switch = TSwitch(arduino_pin);

Then you poll the object continously

switch.poll();

switch.poll() returns the state  which can be more comfortably obtained through the following class members:

switch.hasChanged(); // Signals if there was a change since last read - destructive read
switch.wasLong(); // Signals if > 3 seconds passed since last change
switch.wasShort(); // Signals if < 250ms passed since transition
switch.get(); // state of the switch 0=0ff 1=on

TSwitch.h

</pre>
#ifndef _TSWITCH_H_
#define _TSWITCH_H_

#define PULLUP HIGH
#define PULLDOWN LOW

#define _SWITCH_OFF_ 0
#define _SWITCH_ON_ 1
#define _SWITCH_SHORT_ 2
#define _SWITCH_LONG_ 4
#define _SWITCH_CHANGE_ 8
#define _SWITCH_STABLE_ 16

#define _SWITCH_MS_LONG_ 3000
#define _SWITCH_MS_SHORT_ 250

class TSwitch {

private:
 uint8_t _pin; // CPU Pin of button
 uint8_t _mode; // PULLUP or PULLDOWN mode
 uint8_t _state; // State
 unsigned int _debounceTime; // Config for number of ms debouncing delay
 int _lastPinRead; // pin status last time the pin was read
 unsigned long _toggledAt; // last time the pin changed
 unsigned long _elapsedA; // last time the switch was stable
 unsigned long _elapsedB; // prior last time the switch was stable

public:
 // Constructor with Initialize timer
 TSwitch(uint8_t pin, uint8_t mode = PULLUP, unsigned int debounceTime=20);

// Run single debounce cycle - returns full state
 uint8_t poll();

 // Signals if there was a change since last read - destructive read
 uint8_t hasChanged();

 // Signals if the last transition was long
 uint8_t wasLong();

// Signals if the last transition was fast
 uint8_t wasShort();

 // Returns the current state with all flags
 uint8_t getState();

 // Returns the switch state
 uint8_t get();
};

#endif
<pre>

TSwitch.cpp

</pre>
#include <Arduino.h>
#include <limits.h>
#include <TSwitch.h>
// ---------------------------------------------------------------------------
TSwitch::TSwitch(uint8_t pin, uint8_t mode, unsigned int debounceTime) {

 _pin = pin;
 _mode = mode;
 _debounceTime = debounceTime;

_state = (_lastPinRead != _mode) ? _SWITCH_ON_:_SWITCH_OFF_;
 _lastPinRead = digitalRead(_pin);
 _toggledAt = millis();

 if (_mode == PULLUP) {
 digitalWrite(_pin, HIGH);
 }
 else {
 digitalWrite(_pin, LOW);
 }
}

// ---------------------------------------------------------------------------
boolean TSwitch::hasChanged() {

boolean changeFlag = _state & _SWITCH_CHANGE_;

 // Delete change flag as it has been read
 _state &= ~_SWITCH_CHANGE_;

 return changeFlag;
}
// ---------------------------------------------------------------------------
uint8_t TSwitch::getState() {
 return _state;
};

// ---------------------------------------------------------------------------
uint8_t TSwitch::get() {
 return _state & _SWITCH_ON_;
};

// ---------------------------------------------------------------------------
uint8_t TSwitch::wasLong() {
 return (_state & _SWITCH_LONG_)?1:0;
};

// ---------------------------------------------------------------------------
uint8_t TSwitch::wasShort() {
 return (_state & _SWITCH_SHORT_)?1:0;
};
// ---------------------------------------------------------------------------
uint8_t TSwitch::poll() {

 unsigned long now = millis();

 // read pin
 int pinRead = digitalRead(_pin);

 // If a change occurred start debouncing
 if ( pinRead != _lastPinRead ) {
 // Delete change and stable flag
 _state &= ~(_SWITCH_CHANGE_ | _SWITCH_STABLE_);

 // Maintain current state to handle debouncing
 _lastPinRead = pinRead;
 _toggledAt = now;
 }
 else if ( (_state & _SWITCH_STABLE_) == 0 ) {
 // If debounce time passed without a change the switch is stable
 if ( (now - _toggledAt) >= _debounceTime ) {

// Identify state
 _state = (_lastPinRead != _mode) ? _SWITCH_ON_:_SWITCH_OFF_;
 _state |= _SWITCH_CHANGE_ | _SWITCH_STABLE_ ;

// Identify double and long presses
 if (now - _elapsedA > _SWITCH_MS_LONG_ ) _state |= _SWITCH_LONG_;
 if (now - _elapsedB < _SWITCH_MS_SHORT_) _state |= _SWITCH_SHORT_;

 // Shift elapsed time
 _elapsedB = _elapsedA;
 _elapsedA = now;

 // Save current time to later determine the stable duration
 _toggledAt = now;
 }
 }

 return _state;
}
<pre>

TSwitch as library including an example can be found here for download

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s