PS3 controller driver -> uinput-> python? somehow? - python

I'm trying to read from a PS3 controller in python on Ubuntu and I'm not having much luck. I started with the ps3joy driver from Willow Garage (http://www.ros.org/wiki/ps3joy) which supposedly publishes all the important bits of the PS3 controller to something I had never heard of called "uinput". Apparently it's a linux feature that allows userspace drivers to provide system events. ...Why the WG driver requires root access given that it's supposedly a userspace driver is beyond me, but that's not my question.
Anyway, the current state of me trying to get it to work is that I've got the driver working, and I've verified that it responds to button presses on the controller, but I don't know how to pull any of that data out so I can use it.
My first guess was to use pygame to (hopefully) read from /dev/uinput (which I'm pretty sure is where the driver sends the data):
from pygame import joystick
if not joystick.get_init():
joystick.init()
js = joystick.Joystick(0) # there is only one joystick... even if the driver isn't running(!)
js.init()
print js.get_numbuttons() # perhaps coincidentally correctly prints 17 which is the number of buttons on a PS3 controller
for i in range(js.get_numaxes()):
print js.get_axis(i) # always prints 0, no matter what I'm doing with the controller
but it didn't work. The most telling part of the problem is that it does the same thing if I don't have the WG driver running at all.
I'm sure this is something easy, that I'm just not reading the right information, but googling has not helped me find what the right information is and I'm getting tired and desperate.

You don't need the driver. Assuming the controller exposes itself as a HID, you can use the event subsystem to read controller events directly from the device.

I know it's too late, but if anyone will ever need the code or is struggling with it, you can use mine. I've wrote a script in python that gets ps3 data from USB and sends it to specific a MAC address via PC's bluetooth (you can use ps3controller.py only for data).
This was made for my quadcopter project.
https://github.com/urbanzrim/ps3controller

Try
pygame.event.pump()
before you read the joystick. I needed it to work with the 360 controller

I believe you need the following at the very least:
from pygame import joystick, event, display
display.init()
joystick.init()
js=joystick.Joystick(0)
js.init()
...
for foo in bar:
event.pump()
...
if foo:
event.pump()
...
while bar:
event.pump()
...
I believe that display.init() has to be there because it is needed for event handling...
Also, you can skip a lot of that with
import pygame
pygame.init()
js=pygame.joystick.Joystick(0)
js.init()
...
for foo in bar:
pygame.event.pump()
...
if foo:
pygame.event.pump()
...
while bar:
pygame.event.pump()
....
I could be wrong, but I think your issues are:
A) No event.pump in your if/while/for clauses
B) No display.init()
Sources:
http://webcache.googleusercontent.com/search?q=cache:I56GyE7I4CkJ:iamtherockstar.com/archive/making-hid-devices-easier-using-pygame-joysticks/+&cd=1&hl=en&ct=clnk&gl=us
and
http://www.pygame.org/docs/ref/event.html
"The input queue is heavily dependent on the pygame display module."

Solving similar problem right now: communicate/receive data from PS3 bluetooth remote with python in GNU/Linux.
What i found helpful:
Debugging PS3 Controller http://www.pabr.org/sixlinux/sixlinux.en.html
Looks like working project, for PS3 Remote http://kitlaan.twinaxis.com/projects/bluez-ps3remote/ (it requires to patch bluez 1st) did not tested, yet.
pybluez BT wrapper http://code.google.com/p/pybluez/ (checking it right now)

Related

Is there a way in Python to block only a particular device (keyboard)?

My cat keeps sitting on my laptop keyboard while I"m working. I use a USB keyboard/USB mouse and I want to disable only the laptop keyboard/touchpad. So what I want to do is this:
Instantly disable the laptop keyboard and mouse (whenever required)
Instantly enable them again (when needed)
Not have to restart the system for either changes
I have searched extensively for an answer to this and I've found no easy working solutions. All of them require a restart on windows 10 and they're extremely painful. Here are a few examples (and also reasons why this question is NOT a duplicate):
disable or lock mouse and keyboard in Python?
You're basically disabling EVERYTHING! Even the USB keyboard. There's no specific way of disabling on selected drivers.
Here's another option: Python Block Keyboard / Mouse Input
Again we're disabling EVERYTHING! How do we work if we disable both keyboards?
Here's another option: https://superuser.com/questions/346570/how-can-i-disable-my-laptops-built-in-keyboard-in-windows-7
Here the idea of using group policy to disable "all automatic driver installations" is an obvious overkill IMO! After a couple of weeks there will come a time when you need this and you'll be stuck trying to recall how to enable this. It also needs a restart.
All other answers on this page require you to restart your PC.
Question:
Is there a way in Python that can specify a particular driver and capture all input from it? Maybe we can modify this code so it works only on a particular device driver?
import pythoncom, pyHook
def uMad(event):
return False
hm = pyHook.HookManager()
hm.MouseAll = uMad
hm.KeyAll = uMad
hm.HookMouse()
hm.HookKeyboard()
pythoncom.PumpMessages()

One joystick works with pygame and another won't?

I am currently building a robot that I would like to control with a pair of nice joysticks I bought. Up until now I've been using pygame.joystick with no problems at all with my PS4 controller. However the new joysticks have a problem. They output the correct values for like twenty or thirty seconds and function properly, but then they just freeze on a value. I can't think of any reasons they would work fine for a certain amount time and then all of a sudden just freeze.
My code is as simple as:
pygame.init()
leftjoy = pygame.Joystick.joystick(0)
leftjoy.init()
while True:
print(leftjoy.get_axis(0))
pygame.event.pump()
Update:
I tried this same code on Windows instead of raspberry pi and it worked perfectly. I plan on using ssh when controlling the robot so it should work well for that application. But I would still like to know how to fix this problem for testing.
A couple shots in the dark, without access to your hardware...
Since the PS4 controller works, I'm guessing the code and the RasPi are in good health, so the joysticks themselves might be somewhat buggy. The problem could be that the joysticks momentarily disconnect (power issue, faulty cable, just faulty hardware), and upon reconnect are assigned a new address such as 1. I don't recall that being a common problem in RasPi in general, but PyGame might have issues. Here's another post with some code that might help you detect and debug joystick disconnects in software. To much more quickly test that possibility in hardware, intentionally do a momentary disconnect-connect early, while your game is "working" and see if the same result happens.
Finally, maybe the RasPi is polling too quickly and causes the joystick to freeze. To debug this, you could try putting a delay in your loop.

Communicating to USB devices in windows 7 and still use pre-existing drivers?

I'm looking to write a program to change the DPI setting on my logitech G502 mouse (My goal being to use the program with AutoHotkey to help automate a task where I switch my DPI allot and to learn a bit about USB). I'm fairly fluent in C++ , C# and python. But I'm not at all knowledgeable on USB or drivers.
So far I have: used the program USBlyser to identify a Control transfer sent to my mouse when using Logitech's software, which byte of the data corresponds to my DPI setting, and the product ID and Vendor ID of my mouse.
After looking around on the net I decided PyUSB would be a good option for communicating to my mouse. After installing libUsb for use with PyUSB I realised that this then replaces my current mouse driver and makes it unusable.
Am I just going about this all wrong? In my head all I want to do is send to my mouse the data "10 FF 0E CA 01 00 00", should I instead be somehow communicating with my existing logitech driver to do this? Or can I set-up libUsb without interfering with existing drivers?
Any help will be appreciated, cheers Bradley.
libusb doesn't interfere with anything. In PyUSB you choose to communicate directly with the device. To do this any other app holding this USB port have to be stopped.
Windows driver in your mouse case.
I think it may be possible for you to push the DPI activation code while driver is still using mouse, but how, I have no idea now.
Or you may detach mouse temporarily , pass the code, and then release mouse back to Windows, hoping that DPI config wouldn't be reseted.
If that doesn't pass, you may always completely emulate mouse driver. It is very easy.
There are code samples for PyUSB on internet on how to interpret mouse data. So you do it and you pass the recognized command to OS either directly through Windows API or using PyMouse library.
In this case you do not need driver, because your program is one, and it sends to mouse whatever you want.
You have a lot of options how to do what you want.
For instance, if this is only for your local use, and there is interface already doing what you want, automate that interface using pywinauto to perform a macro to activate/disable higher DPI.
There are more possibilities.
You can replace Windows driver with your own version, which will support what you wish, thus making your own layer in mouse stack. But this is extreme.
I think you should start in order I wrote:
See whether you can use PyUSB to send bytes needed without detaching mouse from OS
If not, see whether detaching mouse, changing DPI, and returning mouse back to OS using PyUSB keeps the set DPI.
3.1 If not, make your own artificial driver using PyUSB and PyMouse
or
3.2 Use pywinauto to automate the existing interface to change DPI for you.

Receiving data from HID game controller in Python

I am trying to communicate with a game controller Human Interface Device (HID) with a Python script, but I'm having trouble receiving data from the controller. I am using pywinusb 0.3.2 and Python 3.3. The game controller is a Logitech Gamepad F310.Link Here to pywinusb.
I have been able to get python to recognize the HID, but I am stuck as on where to go from there. My code for recognizing the controller is:
import pywinusb.hid as hid
target = hid.HidDeviceFilter(vendor_id = target_vendor_id, product_id = target_product_id)
allitems = target.get_devices()
device = allitems[0]
print(device)
This code returns something like this: HID device (vID=0x00a, pID=0xa000, v=0x0000); Logitech; Logitech Dual Action, Path: \(numbers and letters in a long sequence here)
I'm not sure if the approach here would work with a controller, or whether there is another library that is preferable to pywinusb. If I have to switch libraries, I would prefer to switch to one that is cross platform. The small amount of documentation in the examples section included was not enough for me to figure this out with.
My question is: How do I receive the data from the controller? Is there a command? I've worked with the Arduino a little bit and hooking it up to a Wii Nunchuk was a similar process. Will I have to be sending initialization sequences, similar to the Arduino? I need to know the x and y values of both sticks on the controller as well as whether the buttons are pressed.
My apologies if this is obvious or has already been answered. I have never worked with an HID in python before.
Take a look to how HID usages work (google around).
Use the show_hids.py example script to review if the device exposes standard usages.
If not, your only hope is to use raw reports handlers (check the example folders from the source, I recommend you to work with github's code).

Media Play/Pause Simulation

My keyboard contains a row of buttons for various non-standard keyboard tasks. These keys contain such functions as modifying the volume, playing or pausing, and skipping tracks. How can I simulate a basic play/pause with Python? I am on Windows, by the way.
I would use pywin32. Bundled with the installation is a large number of API-docs (usually placed at something like C:\Python32\Lib\site-packages.) It essentially wraps a lot of stuff in the Win32-library which is used for many low-levels tasks in Windows.
After installing it you could use the wrapper for keybd_event.
You could also use SendInput instead of keybd_event but it doesn't seem to be wrapped by PyWin32. SendMessage is also an option but more cumbersome.
You'll need to look up the virtual scan code for those special buttons, since I doubt the char-to-code mapping functions will help you here. You can find the reference here.
Then it is a simple matter of calling the function. The snippet below pauses Chuck Berry on my computer.
>>> import win32api
>>> VK_MEDIA_PLAY_PAUSE = 0xB3
>>> hwcode = win32api.MapVirtualKey(VK_MEDIA_PLAY_PAUSE, 0)
>>> hwcode
34
>>> win32api.keybd_event(VK_MEDIA_PLAY_PAUSE, hwcode)
MapVirtualKey gives us the hardware scan code which keybd_event needs (or more likely, the keyboard driver.)
Note that all this is snapped up by the keyboard driver, so you don't really have any control where the keystrokes are sent. With SendMessage you can send them to a specific window. It usually doesn't matter with media keys since those are intercepted by music players and such.
This was not working for me on Windows 10 64, all recent updates installed. I needed this (the 3rd parameter 2) before it'd work.
win32api.keybd_event(0xB3,0,2,0)
didn't bother looking into why it works, but threw it out there since this and other similar posts had me frustrated as for some reason not working on my PC.
This successfully paused/played Amazon Music on my PC.
You can use pyautogui. This library contains a lot of keyboard and mouse simulations.
To install run pip install pyautogui in cmd.
In order to simulate a play/pause keypress, you should use pyautogui.press("playpause").
Check out their docs at https://pyautogui.readthedocs.io/en/latest/keyboard.html to see the list of the supported keys and some other keyboard functions.

Categories

Resources