Xbox Keyboard Mouse Adapter Using Arduino

Hi Everyone:

I'm developing an Xbox Keyboard Mouse Adapter Using an Arduino Mega and 12Bit DAC MCP4922. I ran into some problem and i need your guy help. My problem is my mouse algorithms are not working correctly; playtesting in Halo the game somehow combines the X and Y thumbstick values so the thumbstick moves faster diagonally than the X or Y axis alone. Will need to add yet another filter to the chain to compensate. But keyboard and anything else is working correctly :stuck_out_tongue:

Here is my current configuration:

  1. Set mouse to 8 counts/mm (highest resolution available for PS/2).
  2. Set mouse sample rate to 200Hz (highest sample rate available for PS/2).
  3. Read X Y.
  4. Finds the absolute value of X Y.
  5. Since I set the mouse to 8 counts/mm so it only output -127 to 127. So we take X Y divided by 127 time it by 2048 because I'm currently using 12bit DAC MCP4922 (0 to 4095).
  6. Depend on the sign bit and the axis we either + or - from 2048.
  7. Send it to the DAC via SPI Protocol.
    And both mouse are using PS/2 Protocol you can find some of very helpful information here: http://www.computer-engineering.org/ps2protocol/

YouTube: Xbox Keyboard Mouse Using Arduino Mega - YouTube
Twitter: http://twitter.com/xXhighpowerXx
AIM: maximusextreme64

void readMouse()
{
byte m1, m2, m3, ack;
float x_move, y_move;
mouse.write(0xEB);
mouse.read(); // ack byte

m1 = mouse.read();
m2 = mouse.read();
m3 = mouse.read();

//Mouse X Axis Note: X is invert in the controller
if(((m1 >> 6) & 0x01) != 1) //Overflow bit
{
if(((m1 >> 4) & 0x01) == 1) //Sign bit
{
//negative

//find abs value
m2 = ~m2;
m2 += 1;
x_move = m2 / 127.0;
//map to the correct value
x_move = 2048.0 * x_move * 10.0;

x_move = 2048 + x_move;
if(x_move > 4095){x_move = 4095;} //Left
}
else
{
//positive
x_move = m2 / 127.0;

x_move = 2048.0 * x_move * 10.0;

x_move = 2048 - x_move;
if(x_move < 0){x_move = 0;} //Right
}
}

//Mouse Y Axis
if(((m1 >> 7) & 0x01) != 1) //Overflow bit
{
if(((m1 >> 5) & 0x01) == 1) //Sign bit
{
//negative
m3 = ~m3;
m3 += 1;
y_move = m3 / 127.0;

y_move = 2048.0 * y_move * 10.0 * 1.5;

y_move = 2048 - y_move;
if(y_move < 0){y_move = 0;} //DOWN
}
else
{
//positive
y_move = m3 / 127.0;

y_move = 2048.0 * y_move * 10.0 * 1.5;

y_move = 2048 + y_move;
if(y_move > 4095){y_move = 4095;} //UP
}
}

analogState[M_Y] = y_move;
analogState[M_X] = x_move;
}

I think i found a solution :-/ Here:

I think we have to clamp all the value inside the green circle. But I don't know the right formula for it please help me :frowning: Because since the Xbox controller joystick zone are a circle :slight_smile: that why make the diagonal move so fast :smiley:

What is mouse (as in mouse.read())? Why do you get 4 bytes from the mouse after each write? What do m1, m2, and m3 represent?

mouse is "PS2 mouse(m_clockPin, m_dataPin);"
and 1 byte is equal to 8 bit :stuck_out_tongue:

M1 = Byte 1
M2 = Byte 2
M3 = Byte 3

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Byte 1 Y overflow X overflow Y sign bit X sign bit Always 1 Middle Btn Right Btn Left Btn
Byte 2 X movement
Byte 3 Y movement

Hi there

The way I see it is that you move on the square and not the circle.

You need to calculate the lengh of the vector from (0,0) to (x_move,y_move). If the lengh is < 4095 you are inside the circle and you have no problem - just move.

  1. If lengh is > 4095 you are outside the circle and you have a problem.
    2a)Convert x_move and y_move til abs values.
    2b) Calculate the angle between your abs vector and x-axis (0,4095).
    2c) Calculate the intersect cordinats with the circal - this can be done since you know both the angle and the radius of your circle (4095). This is your new x_move and y_move.
    2d) Apply correct signs (+/-) to new x_move and y_move based on the original x_move and y_move - check the 4 quardrants.
    2e) Move.

-Fletcher

Hi there

The way I see it is that you move on the square and not the circle.

You need to calculate the lengh of the vector from (0,0) to (x_move,y_move). If the lengh is < 4095 you are inside the circle and you have no problem - just move.

  1. If lengh is > 4095 you are outside the circle and you have a problem.
    2a)Convert x_move and y_move til abs values.
    2b) Calculate the angle between your abs vector and x-axis (0,4095).
    2c) Calculate the intersect cordinats with the circal - this can be done since you know both the angle and the radius of your circle (4095). This is your new x_move and y_move.
    2d) Apply correct signs (+/-) to new x_move and y_move based on the original x_move and y_move - check the 4 quardrants.
    2e) Move.

-Fletcher

Thank for helping :slight_smile:

But this is not my problem :frowning: if you move the mouse diagonally it seen faster than up, down, left, and right. We need to clamp the value inside the circle not chop it off i'm not good at math so i need some help here :frowning: