我已经摸不着头脑了几个星期了,我在Linux上并没有多样化,所以它很容易被我忽视。
在我的系统中,我得到了一个通过I2C将数据发送到我的RaspberryPi的arduino。 PI查看数据,然后应该模拟系统中的按钮按下。 我使用python脚本和evdev来完成这个。 系统首先在吸引模式(游戏模拟器前端)启动,然后启动所需的模拟器+游戏。
我首先在rc.local中启动python脚本
sudo python myscript.py &
这使它运行。
它可以毫无问题地读取I2C,但evdev的东西可以按预期工作。
树莓派没有键盘插入。 在我的第一次测试中,我插入了一个用于测试目的的键盘,一切正常,python-evdev发送了按钮按下,在吸引模式下,然后在启动的模拟器中被识别。 大!我以为......
这是工作代码: `
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#DECLARATIONS
import smbus
import time
import subprocess
import alsaaudio
from evdev import UInput, ecodes as e
ui = UInput()
debug = True
bus = smbus.SMBus(1)
address = 0x18
keys = [
e.KEY_ESC,
e.KEY_0,
e.KEY_ENTER,
e.KEY_LEFT,
e.KEY_UP,
e.KEY_RIGHT,
e.KEY_DOWN,
e.KEY_1,
e.KEY_2,
e.KEY_3,
e.KEY_4,
e.KEY_5,
e.KEY_6]
state = []
oldState = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
backHold = False
backTime = 0
#FUNCTIONS
def readController():
global state
global oldState
try:
state = bus.read_i2c_block_data(address,0,15)
backBtn(state[0])
if oldState != state:
DEBUG(state)
return True
except IOError:
subprocess.call(["i2cdetect","-y","1"])
return False
def updateButtons():
i = 0
global state
global oldState
while(i < len(state)):
if state[i] != oldState[i] and state[i] == 0 or state[i] == 1:
DEBUG("Button State: " + str(state[i]))
oldState[i] = state[i]
if i < 13 and i > 0:
UInput(i,state[i])
if i >= 13:
volumeControl(i,state[i])
i = i+1
return
def UInput(btn,state):
ui.write(e.EV_KEY,keys[btn],state)
ui.syn()
DEBUG("Button Pressed: " + str(keys[btn]))
return
def volumeControl(btn,state):
m = alsaaudio.Mixer("PCM")
vol = m.getvolume()
vol = int(vol[0])
DEBUG("Current Volume: " + str(vol))
if state == 1:
if btn == 13:
#INCREASE
newVol = vol + 5
if newVol > 100:
newVol = 100
else:
#DECREASE
newVol = vol - 5
if newVol < 0:
newVol = 0
DEBUG("New Volume: " + str(newVol))
m.setvolume(newVol)
return
def backBtn(state):
global backHold
global backTime
if state == 1:
backHold = True
else:
backHold = False
backTime = 0
UInput(0,0)
if backHold:
backTime = backTime + 1
DEBUG ("Holding ESC Time: " + str(backTime))
if backTime == 50:
backTime = 0
UInput(0,1)
def DEBUG(msg):
if debug:
print msg
#MAIN LOOP
while True:
if readController():
updateButtons()
time.sleep(0.10)
`
然后我关闭了系统并拔下了键盘并重新启动了系统,现在我的问题就开始了; 没有键盘插入吸引模式和启动模拟器不会再识别任何按钮按下。 所以我试着做这里描述的内容: http://python-evdev.readthedocs.io/en/latest/tutorial.html#specifying-uinput-device-options并且得到了一些不同的结果。
现在我的按钮在“吸引模式”下运行良好,但在我启动模拟器后立即停止工作。 但是如果我在模拟器启动后重新运行我的脚本,按钮也会在那里工作。
这是我对代码的更改:
cap = {e.EV_KEY : [
e.KEY_ESC,
e.KEY_0,
e.KEY_ENTER,
e.KEY_LEFT,
e.KEY_UP,
e.KEY_RIGHT,
e.KEY_DOWN,
e.KEY_1,
e.KEY_2,
e.KEY_3,
e.KEY_4,
e.KEY_5,
e.KEY_6]
}
ui = UInput(cap, name='ArcadeController', version=0x1)
我真的不知道如何解决这个问题,如果我忽略了什么或者遗漏了什么。
我试过了:http://python-evdev.readthedocs.io/en/latest/tutorial.html#create-uinput-device-with-capabilities-of-another-device 并尝试在init.d中将我的脚本作为服务启动。 我监视键盘按下,所以当模拟器启动时,我看到我的脚本正在运行。
编辑:
如果我在使用脚本的第二个版本(那个在吸引模式下工作但没有在启动模拟器中运行,除非我再次运行脚本)运行cat /proc/bus/input/devices
,这就是我得到的:
I: Bus=0003 Vendor=0001 Product=0001 Version=0001
N: Name="ArcadeController"
P: Phys=
S: Sysfs=/devices/virtual/input/input1
U: Uniq=
H: Handlers=kbd event1
B: PROP=0
B: EV=3
B: KEY=1680 0 0 100008fe
我可以看到cat /dev/input/event1
它正在接收我的输入。
如果我运行的第一个版本只有在我得到外接键盘时才有效,这就是我得到的:
I: Bus=0003 Vendor=0001 Product=0001 Version=0001
N: Name="py-evdev-uinput"
P: Phys=
S: Sysfs=/devices/virtual/input/input3
U: Uniq=
H: Handlers=sysrq kbd event3 rfkill
B: PROP=0
B: EV=3
B: KEY=ff ffffffff 0 0 3f 3007f 1000f 7fff0fff 7fe001f ffff000f 7ffffff ffffffff ffffffff 3fdff 7fff8fff ff03ff 1ffffff ffffff07 ffffffff ffffffff ffffffff ffefffff ffffffff fffffffe
如果我在没有外接键盘的情况下运行相同的版本:
I: Bus=0003 Vendor=0001 Product=0001 Version=0001
N: Name="py-evdev-uinput"
P: Phys=
S: Sysfs=/devices/virtual/input/input1
U: Uniq=
H: Handlers=sysrq kbd event1 rfkill
B: PROP=0
B: EV=3
B: KEY=ff ffffffff 0 0 3f 3007f 1000f 7fff0fff 7fe001f ffff000f 7ffffff ffffffff ffffffff 3fdff 7fff8fff ff03ff 1ffffff ffffff07 ffffffff ffffffff ffffffff ffefffff ffffffff fffffffe