Go Down

Topic: Xbox Keyboard Mouse Adapter Using Arduino (Read 1 time) previous topic - next topic

xXhighpowerXx

Sep 13, 2010, 05:40 am Last 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 :P

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: http://www.youtube.com/watch?v=KLSd-YAKrrw
Twitter: http://twitter.com/xXhighpowerXx
AIM: maximusextreme64

xXhighpowerXx

Quote

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


xXhighpowerXx

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  :D  

PaulS

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

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

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

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

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