1+ from machine import ExtInt
2+ from machine import Pin
3+ from utime import sleep_ms
4+ from queue import Queue
5+ import _thread
6+ import osTimer
7+
8+ key_evt_queue = Queue (8 )
9+
10+ def key_evt_thread_entry ():
11+ while True :
12+ self , event = key_evt_queue .get ()
13+ self .event_cb (self , event )
14+
15+ _thread .start_new_thread (key_evt_thread_entry , ())
16+
17+ class Key ():
18+
19+ class Event ():
20+ PRESSED = 0x01
21+ RELEASED = 0x02
22+ LONG_PRESSED = 0x04
23+
24+ class Error (Exception ):
25+ def __init__ (self , value ):
26+ self .value = value
27+
28+ def __str__ (self ):
29+ return repr (self .value )
30+
31+ def __init__ (self , pin , level_on_pressed , cared_event , event_cb , long_press_event = []):
32+ self .pin = pin
33+ if level_on_pressed == 0 :
34+ self .exti_pull = ExtInt .PULL_PU
35+ if cared_event == self .Event .PRESSED :
36+ self .exti_trigger_mode = ExtInt .IRQ_FALLING
37+ elif cared_event == self .Event .RELEASED :
38+ self .exti_trigger_mode = ExtInt .IRQ_RISING
39+ elif cared_event == self .Event .PRESSED | self .Event .RELEASED :
40+ self .exti_trigger_mode = ExtInt .IRQ_RISING_FALLING
41+ else :
42+ raise self .Error ("Value error of <cared_event>!" )
43+ elif level_on_pressed == 1 :
44+ self .exti_pull = ExtInt .PULL_PD
45+ if cared_event == self .Event .PRESSED :
46+ self .exti_trigger_mode = ExtInt .IRQ_RISING
47+ elif cared_event == self .Event .RELEASED :
48+ self .exti_trigger_mode = ExtInt .IRQ_FALLING
49+ elif cared_event == self .Event .PRESSED | self .Event .RELEASED :
50+ self .exti_trigger_mode = ExtInt .IRQ_RISING_FALLING
51+ else :
52+ raise self .Error ("Value error of <cared_event>!" )
53+ else :
54+ raise self .Error ("Value error of <level_on_pressed>!" )
55+
56+ self .level_on_pressed = level_on_pressed
57+ self .cared_event = cared_event
58+ self .event_cb = event_cb
59+ self .long_press_event = long_press_event
60+ self .exti = ExtInt (self .pin , self .exti_trigger_mode , self .exti_pull , self .exit_cb )
61+ self .exti .enable ()
62+ self .timer = osTimer ()
63+ self .sec = 0
64+
65+ def timer_cb (self , args ):
66+ self .sec += 1
67+ for n in self .long_press_event :
68+ if self .sec == n :
69+ key_evt_queue .put ((self , self .Event .LONG_PRESSED ))
70+ break
71+
72+ def exit_cb (self , args ):
73+ self .exti .disable ()
74+ sleep_ms (20 )
75+ gpio = Pin (args [0 ], Pin .IN , Pin .PULL_PU , 1 )
76+ level = gpio .read ()
77+ event = None
78+
79+ if self .level_on_pressed == 0 :
80+ if level == 0 :
81+ event = self .Event .PRESSED
82+ else :
83+ event = self .Event .RELEASED
84+ else :
85+ if level == 1 :
86+ event = self .Event .PRESSED
87+ else :
88+ event = self .Event .RELEASED
89+
90+ if event & self .cared_event :
91+ key_evt_queue .put ((self , event ))
92+
93+ if event == self .Event .PRESSED :
94+ self .sec = 0
95+ self .timer .start (1000 , 1 , self .timer_cb )
96+ else :
97+ self .timer .stop ()
98+
99+ self .exti = ExtInt (self .pin , self .exti_trigger_mode , self .exti_pull , self .exit_cb )
100+ self .exti .enable ()
101+
102+ if __name__ == '__main__' :
103+ k1 = Pin .GPIO4
104+ k2 = Pin .GPIO30
105+
106+ def event_cb (k , event ):
107+ if event != Key .Event .LONG_PRESSED :
108+ print ("%s is %s" % ("k1" if k .pin == k1 else "k2" , "pressed" if event == Key .Event .PRESSED else "released" ))
109+ if event == Key .Event .RELEASED :
110+ print ("do something when key is released after %d seconds" % k .sec )
111+ else :
112+ print ("%s is pressed for %d seconds" % ("k1" if k .pin == k1 else "k2" , k .sec ))
113+
114+ Key (k1 , 0 , Key .Event .PRESSED | Key .Event .RELEASED , event_cb )
115+ Key (k2 , 0 , Key .Event .PRESSED | Key .Event .RELEASED , event_cb , [2 , 4 , 6 ])
0 commit comments