我有一个用gobject用python编写的游戏杆类,除了一个小问题外,它的效果很好。当我运行下面的代码时按钮反弹,它会多次按下所有按钮。如何以合理的准确度将每个按钮减少为一条消息?
'''
Copyright 2009 Jezra Lickter
This software is distributed AS IS. Use at your own risk.
If it borks your system, you have been forewarned.
This software is licensed under the LGPL Version 3
http://www.gnu.org/licenses/lgpl-3.0.txt
for documentation on Linux Joystick programming please see
http://www.mjmwired.net/kernel/Documentation/input/joystick-api.txt
'''
import gobject #needed for sending signals
import struct #needed for holding chunks of data
class Joystick(gobject.GObject):
'''The Joystick class is a GObject that sends signals that represent
Joystick events'''
EVENT_BUTTON = 0x01 #button pressed/released
EVENT_AXIS = 0x02 #axis moved
EVENT_INIT = 0x80 #button/axis initialized
#see http://docs.python.org/library/struct.html for the format determination
EVENT_FORMAT = "IhBB"
EVENT_SIZE = struct.calcsize(EVENT_FORMAT)
# we need a few signals to send data to the main
'''signals will return 4 variables as follows:
1. a string representing if the signal is from an axis or a button
2. an integer representation of a particular button/axis
3. an integer representing axis direction or button press/release
4. an integer representing the "init" of the button/axis
'''
__gsignals__ = {
'axis' :
(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_INT,gobject.TYPE_INT,gobject.TYPE_INT)),
'button' :
(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_INT,gobject.TYPE_INT,gobject.TYPE_INT))
}
def __init__(self,dev_num):
gobject.GObject.__init__(self)
#define the device
device = '/dev/input/js%s' % dev_num
#error check that this can be read
try:
#open the joystick device
self.device = open(device)
#keep an eye on the device, when there is data to read, execute the read function
gobject.io_add_watch(self.device,gobject.IO_IN,self.read_buttons)
except Exception,ex:
#raise an exception
raise Exception( ex )
def read_buttons(self, arg0='', arg1=''):
''' read the button and axis press event from the joystick device
and emit a signal containing the event data
'''
#read self.EVENT_SIZE bytes from the joystick
read_event = self.device.read(self.EVENT_SIZE)
#get the event structure values from the read event
time, value, type, number = struct.unpack(self.EVENT_FORMAT, read_event)
#get just the button/axis press event from the event type
event = type & ~self.EVENT_INIT
#get just the INIT event from the event type
init = type & ~event
if event == self.EVENT_AXIS:
signal = "axis"
elif event == self.EVENT_BUTTON:
signal = "button"
if signal:
print("%s %s %s %s" % (signal,number,value,init) )
self.emit(signal,number,value,init)
return True
if __name__ == "__main__":
try:
j = Joystick(0)
loop = gobject.MainLoop()
loop.run()
except Exception,e:
print(e)
答案 0 :(得分:2)
有许多方法可以去抖按钮。一种简单,无阻塞的方法是:
此方法要求检查程序以合理的固定间隔运行,因为反应时间由frequency*threshold
给出。
编辑:我没有实际运行此硬件的硬件,但是去抖动方法应该类似于:
if button_now() != button_state:
debounce_counter += 1
if debounce_counter == DEBOUNCE_THRESHOLD:
button_state = not button_state
else:
debounce_counter = 0
在上面的代码中:
button_now()
轮询硬件(根据按钮电路是关闭还是打开,返回True/False
),button_state
是程序的其余部分如何“看到”按钮(再次:根据按钮向下或向上按True/False
),“DEBOUNCE_THRESHOLD
是您根据公式reaction-time-of-the-button = frequency-of-debouncing-routine * threshold
定义的常量。HTH!
答案 1 :(得分:0)
通常,在x,y和按钮触点之间分别有一个1uF / 10uF电容器,并且GND会反跳,因此不需要代码。