Skip to content

Commit de81c99

Browse files
committed
Button debouncing
1 parent a44234f commit de81c99

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

src/PHPi/External/Generic/Button.php

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,53 @@ class Button extends Input
3232
const DEFAULT_HOLD_PERIOD = 1;
3333
const DEFAULT_PRESS_PERIOD = 0.05;
3434

35+
/**
36+
* Period (in seconds) to ignore subsequent press events
37+
*/
38+
const DEFAULT_DEBOUNCE_PERIOD = 0.25;
39+
3540
const EVENT_PRESS = 'press';
3641
const EVENT_HOLD = 'hold';
3742
const EVENT_RELEASE = 'release';
43+
/**
44+
* @var float
45+
*/
46+
private $debounce_period;
3847

3948

40-
public function __construct(Pin $pin, $active_high = true, $press_period = self::DEFAULT_PRESS_PERIOD, $hold_period = self::DEFAULT_HOLD_PERIOD)
49+
public function __construct(Pin $pin, $active_high = true,
50+
$press_period = self::DEFAULT_PRESS_PERIOD,
51+
$hold_period = self::DEFAULT_HOLD_PERIOD,
52+
$debounce_period = self::DEFAULT_DEBOUNCE_PERIOD)
4153
{
4254
parent::__construct($pin);
4355

4456
$this->press_period = $press_period;
4557
$this->hold_period = $hold_period;
4658
$this->active_high = $active_high;
59+
$this->debounce_period = $debounce_period;
4760
}
4861

4962

63+
/**
64+
* Function to setup the listerner on pin change. There is a 'once' listener because it needs to be removed and
65+
* re-added for debounce. This could also be changed to have some 'debouncing' flag etc.
66+
*/
67+
private function registerPressEvent()
68+
{
69+
//Do it like this so it can be hidden from userspace
70+
$press_event = $this->active_high ? Pin::EVENT_LEVEL_HIGH : Pin::EVENT_LEVEL_LOW;
71+
$this->pin->once($press_event, function () {
72+
$this->onPinPressEvent();
73+
74+
//Re-add the press event after the debounce period
75+
$this->pin->getBoard()->getLoop()->addTimer($this->debounce_period, function () {
76+
$this->registerPressEvent();
77+
});
78+
});
79+
80+
}
81+
5082
/**
5183
*
5284
* Internal function for dealing with a press (high or low) event on the pin
@@ -82,11 +114,7 @@ public function eventListenerAdded($event_name)
82114
return;
83115
}
84116

85-
//Do it like this so it can be hidden from userspace
86-
$press_event = $this->active_high ? Pin::EVENT_LEVEL_HIGH : Pin::EVENT_LEVEL_LOW;
87-
$this->pin->on($press_event, function () {
88-
$this->onPinPressEvent();
89-
});
117+
$this->registerPressEvent();
90118
}
91119

92120

0 commit comments

Comments
 (0)