2626_IRQ_RISING_FALLING = Pin .IRQ_RISING | Pin .IRQ_FALLING
2727
2828_DEBOUNCE_DELAY = const (50 ) # ms
29- _KEPT_PRESSED_DELAY = const (200 ) # ms
29+ _LONG_PRESS_DELAY = const (200 ) # ms
3030
3131_IRQ_LAST_STATE = const (0 )
3232_IRQ_IDLE_STATE = const (1 )
3333_IRQ_LAST_TIME = const (2 )
34- _IRQ_AVAILABLE = const (3 )
34+ _IRQ_ONE_BUT_LAST_TIME = const (3 )
35+ _IRQ_AVAILABLE = const (4 )
3536
36- _BUTTON_EVENT_RELEASED = const (0 )
37- _BUTTON_EVENT_PRESSED = const (1 )
38- _BUTTON_EVENT_KEPT = const (2 )
37+ _BUTTON_EVENT_PRESS = const (0 )
38+ _BUTTON_EVENT_LONG_PRESS = const (1 )
3939
4040class Button ():
4141 '''button handling class; initiated by ui.__init__'''
4242
43- def __init__ (self , pin_number : int , pull_up : bool = False , trigger_kept_pressed : bool = False ) -> None :
43+ def __init__ (self , pin_number : int , pull_up : bool = False , long_press : bool = False ) -> None :
4444 self .pin_number = pin_number
45- self .trigger_kept_pressed = trigger_kept_pressed
46- self .irq_data = array ('l' , [_NONE , _NONE , 0 , 0 ])
45+ self .long_press = long_press
46+ self .irq_data = array ('l' , [_NONE , _NONE , 0 , _NONE , 0 ])
4747 self .irq_data [_IRQ_IDLE_STATE ] = int (pull_up )
4848 _pin = Pin
4949 pull_direction = _pin .PULL_UP if pull_up else _pin .PULL_DOWN
5050 _pin = _pin (pin_number , _pin .IN , pull_direction )
5151 self .pin = _pin
52- self .last_pressed_time = _NONE
5352 _pin .irq (self ._callback , _IRQ_RISING_FALLING )
5453
5554 def close (self ) -> None :
5655 self .pin .irq (handler = None )
5756
5857 @micropython .viper
5958 def value (self ) -> int :
60- '''return 1 if triggered and trigger_kept_pressed == False, 1 if short pressed and trigger_kept_pressed == True, 2 if
61- kept pressed and trigger_kept_pressed == True, 0 if released and trigger_kept_ressed == True or _NONE if no new data is
62- available (yet ); called by ui.process_user_input'''
59+ '''if long_press == False: return _BUTTON_EVENT_PRESS if pressed; if long_press == True: return _BUTTON_EVENT_PRESS if pressed
60+ shorter then _LONG_PRESS_DELAY milliseconds or return _BUTTON_EVENT_LONG_PRESS if pressed longer ( if kept pressed the trigger
61+ happens after _LONG_PRESS_DELAY milliseconds ); called by ui.process_user_input'''
6362 irq_data = ptr32 (self .irq_data ) # type: ignore
6463 if not irq_data [_IRQ_AVAILABLE ]:
6564 return _NONE
6665 now = int (time .ticks_ms ())
6766 if int (time .ticks_diff (now , irq_data [_IRQ_LAST_TIME ])) < _DEBOUNCE_DELAY :
6867 return _NONE
6968 pressed = irq_data [_IRQ_LAST_STATE ] != irq_data [_IRQ_IDLE_STATE ]
70- if bool (self .trigger_kept_pressed ):
69+ if bool (self .long_press ):
7170 if pressed :
72- if int (self .last_pressed_time ) == _NONE :
73- self .last_pressed_time = irq_data [_IRQ_LAST_TIME ]
74- difference = int (time .ticks_diff (now , int (self .last_pressed_time )))
75- if difference < _KEPT_PRESSED_DELAY :
71+ difference = int (time .ticks_diff (now , irq_data [_IRQ_LAST_TIME ]))
72+ if difference < _LONG_PRESS_DELAY :
7673 return _NONE
7774 irq_data [_IRQ_AVAILABLE ] = 0
78- return _BUTTON_EVENT_KEPT
79- difference = int (time .ticks_diff (irq_data [_IRQ_LAST_TIME ], int (self .last_pressed_time )))
80- self .last_pressed_time = _NONE
75+ return _BUTTON_EVENT_LONG_PRESS
76+ difference = int (time .ticks_diff (irq_data [_IRQ_LAST_TIME ], irq_data [_IRQ_ONE_BUT_LAST_TIME ]))
8177 irq_data [_IRQ_AVAILABLE ] = 0
82- return _BUTTON_EVENT_PRESSED if difference < _KEPT_PRESSED_DELAY else _BUTTON_EVENT_RELEASED
78+ return _BUTTON_EVENT_PRESS if difference < _LONG_PRESS_DELAY else _NONE
8379 irq_data [_IRQ_AVAILABLE ] = 0
84- return _BUTTON_EVENT_PRESSED if pressed else _NONE
80+ return _BUTTON_EVENT_PRESS if pressed else _NONE
8581
8682 @micropython .viper
8783 def _callback (self , pin ):
@@ -92,4 +88,5 @@ def _callback(self, pin):
9288 return
9389 irq_data [_IRQ_LAST_STATE ] = state
9490 irq_data [_IRQ_AVAILABLE ] = 1
91+ irq_data [_IRQ_ONE_BUT_LAST_TIME ] = irq_data [_IRQ_LAST_TIME ]
9592 irq_data [_IRQ_LAST_TIME ] = int (time .ticks_ms ())
0 commit comments