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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy