Pages: [1]   Go Down
Author Topic: Xbox Keyboard Mouse Adapter Using Arduino  (Read 1218 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-razz

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:
Twitter: http://twitter.com/xXhighpowerXx
AIM: maximusextreme64
« Last Edit: September 12, 2010, 10:49:02 pm by xXhighpowerXx » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-sad Because since the Xbox controller joystick zone are a circle smiley that why make the diagonal move so fast  smiley-grin  
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mouse is "PS2 mouse(m_clockPin, m_dataPin);"
and 1 byte is equal to 8 bit smiley-razz

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
Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 156
It was all digital
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley

But this is not my problem smiley-sad 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 smiley-sad
Logged

Pages: [1]   Go Up
Jump to: