Go Down

### Topic: Xbox Keyboard Mouse Adapter Using Arduino (Read 2599 times)previous topic - next topic

#### xXhighpowerXx

##### Sep 13, 2010, 05:40 amLast Edit: Sep 13, 2010, 05:49 am by xXhighpowerXx Reason: 1
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 [glow]moves faster diagonally than the X or Y axis alone[/glow]. Will need to add yet another filter to the chain to compensate. But keyboard and anything else is working correctly

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).
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/

AIM: maximusextreme64

#### xXhighpowerXx

#1
##### Sep 13, 2010, 05:43 am
Quote

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

//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;
}

#### xXhighpowerXx

#2
##### Sep 13, 2010, 06:02 am
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 Because since the Xbox controller joystick zone are a circle that why make the diagonal move so fast

#### PaulS

#3
##### Sep 13, 2010, 11:06 am
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?

#### xXhighpowerXx

#4
##### Sep 13, 2010, 08:40 pm
mouse is "PS2 mouse(m_clockPin, m_dataPin);"
and 1 byte is equal to 8 bit

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

#### Fletcher_Chr

#5
##### Sep 14, 2010, 03:02 pm
Hi there

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

1)
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.

2) 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

#### xXhighpowerXx

#6
##### Sep 14, 2010, 08:53 pm
Quote
Hi there

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

1)
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.

2) 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

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

Go Up