Trees | Indices | Help |
---|
|
1 # Button.py 2 3 ''' 4 Class that represents a push button on some GPIO port. 5 6 7 This software is part of the raspibrickpi module. 8 It is Open Source Free Software, so you may 9 - run the code for any purpose 10 - study how the code works and adapt it to your needs 11 - integrate all or parts of the code in your own programs 12 - redistribute copies of the code777 13 - improve the code and release your improvements to the public 14 However the use of the code is entirely your responsibility. 15 ''' 16 17 import RPi.GPIO as GPIO 18 import time 19 from threading import Thread 20 21 DEBUG = False 22 23 # Button event constants 24 BUTTON_PRESSED = 1 25 BUTTON_RELEASED = 2 26 BUTTON_LONGPRESSED = 3 27 BUTTON_CLICKED = 4 28 BUTTON_DOUBLECLICKED = 5 29 BUTTON_LONGPRESS_DURATION = 2 # default (in s) the button must be pressed to be a long press 30 BUTTON_DOUBLECLICK_TIME = 1 # default time (in s) to wait for a double click event 31375539 if DEBUG: 40 print "===>ClickThread started" 41 self.isRunning = True 42 startTime = time.time() 43 while self.isRunning and (time.time() - startTime < BUTTON_DOUBLECLICK_TIME): 44 time.sleep(0.1) 45 if self.button.clickCount == 1 and not self.button.isLongPressEvent: 46 if self.button.xButtonListener != None: 47 self.button.xButtonListener(self.button, BUTTON_CLICKED) 48 self.button.clickThread = None 49 self.isRunning = False 50 if DEBUG: 51 print "===>ClickThread terminated"52617763 if DEBUG: 64 print "===>ButtonThread started" 65 self.isRunning = True 66 startTime = time.time() 67 while self.isRunning and (time.time() - startTime < BUTTON_LONGPRESS_DURATION): 68 time.sleep(0.1) 69 if self.isRunning: 70 if self.button.buttonListener != None: 71 self.button.buttonListener(BUTTON_LONGPRESSED) 72 if DEBUG: 73 print "===>ButtonThread terminated"7479 GPIO.setmode(GPIO.BOARD) 80 pinsEnabled = []18182 ''' 83 Creates a button instance at given pin. If enable = True, the button events are immediately enabled; 84 otherwise they must be enabled by calling setEnable(True). 85 ''' 86 self._isButtonEnabled = enable 87 self.pin = pin 88 GPIO.setup(pin, GPIO.IN, GPIO.PUD_UP) 89 if not pin in Button.pinsEnabled: 90 GPIO.add_event_detect(pin, GPIO.BOTH, self._onButtonEvent) 91 Button.pinsEnabled.append(pin) 92 else: 93 GPIO.remove_event_detect(pin) 94 GPIO.add_event_detect(pin, GPIO.BOTH, self._onButtonEvent) 95 self.buttonThread = None 96 self.clickThread = None 97 self._inCallback = False98100 ''' 101 Registers a listener function to get notifications when the pushbutton is pressed, released, clicked, 102 double-clicked or long pressed. Sequences are: 103 click: BUTTON_PRESSED, BUTTON_RELEASED, BUTTON_CLICKED 104 double-click: BUTTON_PRESSED, BUTTON_RELEASED, BUTTON_PRESSED, BUTTON_RELEASED, BUTTON_DOUBLECLICKED 105 long pressed: BUTTON_PRESSED, BUTTON_LONGPRESSED, BUTTON_RELEASED 106 @param listener: the listener function (with integer parameter event) to register. 107 ''' 108 self.addButtonListener(self._onXButtonEvent) 109 self.xButtonListener = listener110112 ''' 113 Registers a listener function to get notifications when the pushbutton is pressed and released. 114 @param listener: the listener function (with integer parameter event) to register. 115 ''' 116 self.buttonListener = listener117 118 # Hardware callback120 if not self._isButtonEnabled: 121 return 122 if self._inCallback: # inhibit reentrance 123 return 124 self._inCallback = True 125 # switch may bounce: down-up-up, down-up-down, down-down-up etc. in fast sequence 126 if GPIO.input(self.pin) == GPIO.LOW: 127 if self.buttonThread == None: # down-down is suppressed 128 if DEBUG: 129 print "->ButtonDown" 130 self.buttonThread = _ButtonThread(self) 131 self.buttonThread.start() 132 if self.buttonListener != None: 133 self.buttonListener(self, BUTTON_PRESSED) 134 else: 135 if self.buttonThread != None: # up-up is suppressed 136 if DEBUG: 137 print "->ButtonUp" 138 self.buttonThread.stop() 139 self.buttonThread.join(200) # wait until finished 140 self.buttonThread = None 141 if self.buttonListener != None: 142 self.buttonListener(self, BUTTON_RELEASED) 143 self._inCallback = False144146 if event == BUTTON_PRESSED: 147 if self.xButtonListener != None: 148 self.xButtonListener(btn, BUTTON_PRESSED) 149 self.isLongPressEvent = False 150 if self.clickThread == None: 151 self.clickCount = 0 152 self.clickThread = _ClickThread(self) 153 154 elif event == BUTTON_RELEASED: 155 if self.xButtonListener != None: 156 self.xButtonListener(btn, BUTTON_RELEASED) 157 if self.isLongPressEvent and self.clickThread != None: 158 self.clickThread.stop() 159 self.clickThread = None 160 return 161 if self.clickThread != None and self.clickThread.isRunning: 162 self.clickCount += 1 163 if self.clickCount == 2: 164 self.clickThread.stop() 165 self.clickThread = None 166 if self.xButtonListener != None: 167 self.xButtonListener(btn, BUTTON_DOUBLECLICKED) 168 else: 169 self.clickThread = None 170 171 elif event == BUTTON_LONGPRESSED: 172 self.isLongPressEvent = True 173 if self.xButtonListener != None: 174 self.xButtonListener(btn, BUTTON_LONGPRESSED)175
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Thu Jul 27 09:46:13 2017 | http://epydoc.sourceforge.net |