几个星期以来,我一直在摸不着头脑,我对 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 并尝试将我的脚本作为服务启动初始化.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