Is it possible to make a USB device that would alter mouse data on the fly?

I have a friend who is struggling to find mouse drivers/manufacturers that support various options for dyslexia. Inverting the X and Y axes are a simple feature that most programs and drivers are ignorant of.

The thought occurred to me that it might be possible to construct a small USB device (similar to a thumb drive or PS/2 adapter) that a user could plug a USB mouse into and, using a couple of DIP switches, invert one or both axes.

I have a basic familiarity with programming (C#/C+) and electronics, but am not sure if there is a standard protocol for USB mice.

I'd prefer to avoid using a serial converter (though I know it has a more or less standard protocol). Has anyone used USB mice with a custom electronics project, or can explain whether constructing a USB-to-USB adapter to invert movement is possible?

-
Another way to invert the X and Y axes would be to simply turn the mouse upside down. Try it for a few minutes, the challenge is good for your brain. –  Kevin Vermeer Mar 30 '12 at 21:03
"Easy" way of starting is to start with a non optical USB mouse (= old) and interface at the rotary interrupters from the ball. You are completely outside any protocols or software and working wit the physical environment. You could eg pick up signals from one mouse, process and insert into another if desired. Far from idal but liable to allow very quick getting going. –  Russell McMahon Mar 30 '12 at 21:04
@Kevin The problem with inverting the mouse physically is that it renders the various buttons more difficult (if not nearly impossible) to use. Don't get me wrong, however, the dyslexic person in question has done just that off and on when no other solution was available. –  JYelton Mar 30 '12 at 21:10

While this is probably far from the cheapest or most elegant solution, it is one that will give you great flexibility.

An Arduino single board computer can look to a Windows host computer like a Human Interface Device (HID), in other words a mouse. It is not limited to mice however; keyboards and other devices are HID as well.

You could hook a serial mouse directly to the Arduino's serial port or if you prefer to use a USB mouse you could connect it to the Arduino via a USB host shield.

Since you can program the Arduino in C you can translate any sorts of inputs from the mouse into any commands you like going to the PC. You could for example translate a triple click of the right mouse button into a keyboard input command, the sky is the limit.

-
I think this is the closest to actually making it possible to implement a hardware solution. The software answers were helpful as were the PS2 serial suggestions, but ultimately this is probably what I will try as I have Arduino prototyping kits and this sounds like a good approach. –  JYelton Apr 5 '12 at 15:12

This would be a fairly difficult thing to achieve. Your device would have to behave as both a USB host and a USB peripheral. There may be microcontrollers out there which can do that, but you might end up having to use two, one to be the host, and one the slave.

If you are suggesting something like using a serial mouse, then your job would be much easier to achieve. You'd just need a microcontroller with 2 serial ports, plus two serial interface chips (Like MAX202, or whichever is the newer version).

An even easier option might be to try to write a windows program which would do the inversion.

-
I agree, software solution would be easier and better way to achieve what you want. –  Armandas Mar 30 '12 at 21:03
I'd love to write a software solution, but my knowledge of low-level drivers is lacking. Also I'm not sure if something can be easily written that is compatible with various brands of input devices, or works in a friendly way with the native manufacturer drivers. MAFMouse exists, but appears to be out of date. If finding or writing software was easier, believe me I wouldn't have thought of engineering a small USB device. :) –  JYelton Mar 30 '12 at 21:15
How about a PS2 device ? –  Rocketmagnet Mar 30 '12 at 21:35
I've written a software version, since there doesn't seem to be a nice working solution anywhere. superuser.com/questions/406502/… –  Polynomial Mar 30 '12 at 23:33
@Poly Thanks very much for your effort! I will have to give that a try, though I think I'll still attempt a hardware solution just for the challenge. –  JYelton Apr 5 '12 at 15:13

On Windows, you can intercept the mouse actions with an application, which can be as simple as this AutoHotKey script:

#NoEnv
SetBatchLines -1
Process Priority,,R

BlockInput Mouse        ; user mouse input is ignored during MouseMove
CoordMode Mouse, Screen ; absolute coordinates
SysGet m, Monitor       ; get the screen edges
mLeft += 1, mRight -= 2, mTop += 1, mBottom -= 2
SetMouseDelay -1        ; fastest action

MouseGetPos x0, y0      ; get initial mouse pointer location
SetTimer WatchMouse, 1  ; run the subroutine fast (10..16ms)
Return

WatchMouse:
MouseGetPos x, y     ; get current mouse position
x0 += 2*(x0-x), x0 := x0 < mLeft ? mLeft : (x0 > mRight  ? mRight  : x0)
y0 += 2*(y0-y), y0 := y0 < mTop  ? mTop  : (y0 > mBottom ? mBottom : y0)
MouseMove x0, y0, 0  ; set new position as old, for the next timer
Return

!z::ExitApp             ; stop the madness; make the script persistent


The same logic can be used to solve the problem in any application programming environment (C++, C#, etc.) which can access the Windows cursor functions.

On Linux, it's as simple as modifying a property for your mouse with xinput, as ben wrote:

xinput set-int-prop "USB Optical Mouse"  "Evdev Axis Inversion" 8 0 1


You'll need to substitute your device name (xinput -list | grep -i 'mouse') for "USB Optical Mouse".

Further questions on this software should be directed to Stack Overflow, our site for programming.

-
But I agree, that I would be great thing to have usb device solution "in-the-box", that person would just stick in USB port and that would be it. Installing sw takes some time, but creating such a device, programming it and making it work would take even more time. –  Pan.student Mar 30 '12 at 21:13
Software solutions for this are sadly very few. It seems that mouse manufacturers should include this by default in their device control panel, to ensure they are of benefit to those with disabilities as much as possible. It is, after all, an extremely simple mathematical function. –  JYelton Mar 30 '12 at 21:17

You can use the open source LUFA stack to do native USB HID (human interface device) projects. Adafruit carries an open source dev board that is compatible with the LUFA stack.

To use a USB mouse with your custom board would be tricky. Using a PS/2 mouse should be much easier though. The protocol is simpler and you can probably find a library out there somewhere. Here is an Arduino library that can read from a PS/2 mouse which might be of some use.

For the PS/2 connector, SparkFun carries a breakout board and port that should work.

Odds are you could also change some software on the computer to do this, which would be cheapest, but less portable. A quick google search shows that this is basically one command for a Linux computer.

-

OK, here's a possible solution:

As ben said, this would be much easier if you were using a PS/2 mouse, because that's basically simple serial data.

However, if you really need this to be a USB device, then maybe maybe you an use a USB-PS/2 converter, and a PS/2-USB converter, and place your device inbetween them.

I had a look around and couldn't immediately find a chipset which will do the job, although they must exist. But you could just buy the units:

-
Unfortunately, those pictured devices are simply wiring adapters that allow some mice that were designed internally to handle both low speed USB and PS/2 serial protocols to be plugged in to the other port. There are no active circuits inside. –  RBerteig Mar 30 '12 at 23:31
Is that true? No wonder they don't always work! –  Rocketmagnet Mar 31 '12 at 13:38
HID devices based on a specific Cypress low-speed USB chip set can detect at power up whether the data wires are connected to a PS2 port or to low-speed USB. So all that is required to use a mouse or keyboard based on those chips on either port is the right shape of connector, hence the existence of these things. Not all low speed devices are implemented to support this trick, and I believe it is a lot more difficult to tell full speed (or hi speed) USB from a PS2 port so those device will generally not do this trick. –  RBerteig Apr 2 '12 at 23:38

Yet another solution would be to install MAF-Soft mouse axis inverter driver for windows.

-