Shop OBEX P1 Docs P2 Docs Learn Events
psx contoller problem/limitation — Parallax Forums

psx contoller problem/limitation

OwenOwen Posts: 100
edited 2007-09-29 19:01 in Propeller 1
I'm using a psx2 controller connected to my propellar chip amd have a problem with the output of the device. the psx outputs one byte for each axis of the joystick so joystick foward is 255 joystick down is 0 joystick centered is 127. the problem is that the joystick physically has a circle shaped opening at the joystick instead of a square preventing the joystick from a full diagonal position. it is not possible for both x and y to be 255 , does anyone know what the purpose of this is? or is there a way around it with software? whouldn't the playstation want the full byte of information? thanks in advance

Owen

Comments

  • ColeyColey Posts: 1,110
    edited 2007-09-27 07:11
    Owen,

    It seems not all controllers are the same I have two sony controllers and they are as you describe but I have a cheapo Logic 3 controller and I can get both ends of the scale at the same time, I've also found that most don't always centre on 127 either.
    Why don't you change your thresholds in your code and reduce the range from say 5 - 250 that way you can achieve your goal.

    Best regards,

    Coley
  • BaggersBaggers Posts: 3,019
    edited 2007-09-27 10:03
    Owen,
    The reason they can't both get 255 is because it's a circular gap for the stick to go through to the outside of the joypad, thus max X and Y is 0 and 255, yet on diagonals it changes due to it having circular motion.
    Also, like Coley states, don't use 127 as center, have a dead area ( from about 96 to 159 ) and force that to 127, I used that on the Playstation games I've done, as some sticks are way out.

    Hope this helps clarift things for you a little.

    Have fun,
    Jim.
  • OwenOwen Posts: 100
    edited 2007-09-27 14:52
    I always use a dead area but I don't understand why the playstation would want to be missing the diagonal data from the controller. When I use it connect to my proppelar device it is quite awkward not to have full speed in the corners and doesn't feel anything like any psx game I have played. Any idea how the games get around this limitation?
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-09-27 15:11
    You could convert the x,y values into a magnitude and direction, basically if you get 255 with full right stick then at the diagonal the distance from the centre to the stick will still be effectively 255 but the x and y values will be less than 255. Its not that the data is missing as such its just that they must combine x and y values to give the speed.

    speed = sqrt(x^2 + y^2)

    Graham
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-09-27 15:12
    p.s. If there is an assembly PS2 controller object it might be possible to insert some cordic code to do the conversion.
  • OwenOwen Posts: 100
    edited 2007-09-27 15:47
    Great! this is the information I was looking for I'll give it a try
    thanks
  • BaggersBaggers Posts: 3,019
    edited 2007-09-27 17:05
    Owen to convert it to length and direction, even if you use the mega fast ( from my 8bit days ) hypot routine (which is without any sqrt or multiplies) for the line length, you'll still have to calculate the direction.
    Surely you could just decrease the maximum value from 255 to say 240, or whatever you max out to in the corners, then scale your values from 16 to 240, then subtract 16 to limit to 0-224, then * (65536/224) and then >>8 and voila.

    x := ( ( ( ( x-16 ) #>0 ) #<224 ) * 292 ) >>8
    y := ( ( ( ( y-16 ) #>0 ) #<224 ) * 292 ) >>8

    Baggers.
  • OwenOwen Posts: 100
    edited 2007-09-28 05:13
    could anyone elaborate on how to use cordic code to do the conversion? I looked up cordic on wikipedia but I don't realy understand how to implement it.
  • OwenOwen Posts: 100
    edited 2007-09-28 05:50
    Badgers I understand using a smaller range but I don't understand why you multiply by (65536/224) and then >>8
    can you explain how this works in more detail.
    x := ( ( ( ( x-16 ) #>0 ) #<224 ) * 292 ) >>8
    y := ( ( ( ( y-16 ) #>0 ) #<224 ) * 292 ) >>8
    I appreciate the help
    Owen.
  • BaggersBaggers Posts: 3,019
    edited 2007-09-28 07:35
    Hi Owen, ( it's Baggers btw [noparse]:)[/noparse] )

    The reason I multiply by 65535 / 224, then >>8 is to put it back in the range from 0 to 255
    Because 65535 ( 65535 being the max number for >>8 to =255) / Max ( of small range ) gives us 292.5etc but we're usint integers, so 292 is the number to scale our small 0-224 value by to make from 0 - 65535.

    EG. Take your new MAX value, 224, then run it through the conversion.
    224*292 = 65408 then >> 8 = 255.5 but since registers are integer based not float, it becomes 255

    hope this clears it up a bit more for you.

    Baggers
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-09-28 08:07
    Owen, what object are you using for the joystick, perhaps I can add the required code, it can also provide the angle automatically.

    Graham
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-09-28 09:58
    Just another thought Owen and it really depends what you are trying to do but say you wanted to move a sprite around the screen with the joystick all you really need is the ratio between the x and y value:

    Example 1:

    x = 255
    y= 0

    Move the sprite zero x for every y pixel moved

    Example 2:

    x = 180
    y = 180

    Move the sprite one in y for every one in y moved, this would move the sprite at 45 degrees

    Example 3:

    x = 100
    y = 50

    Move the sprite 1 in y every two pixels in x.

    Graham

    Post Edited (Graham Stabler) : 9/28/2007 10:03:03 AM GMT
  • RicardoPRicardoP Posts: 13
    edited 2007-09-28 18:46
    On a somewhat related note, I'm using the propeller to emulate (not read) a ps2 controller. And I had this bug where if x == y (top left and bottom right diagonals) the PS2 would not respond to re-centering input (128,128) the easy fix was to nudge the x value by 1 when they were equal. I just thought this was really strange or does it make sense to anyone?
  • OwenOwen Posts: 100
    edited 2007-09-28 19:57
    i'm not sure how to use this in my project. I'm controlling two motor to drive a remote camera mount X and Y axis. the way it's set up now the value from the joystick is used to control the speed and control of the motors. the higher the value of x the faster the x axis motor speed and so on... so i'm not sure if i could modify this for speed and direction very easily because it would then need to be translated back to speed and direction for both motors. Maybe I'm missing something simple here.

    Owen
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-09-28 20:28
    Can you tell me more about how your camera mount axes are set up physically?
  • BaggersBaggers Posts: 3,019
    edited 2007-09-28 20:58
    RicardoP, Can you elaborate a bit more? you were getting it to emulate, therefore emulating the self centering too, I presume, is there any chance you could post the snippet of code, so we can look and see where the fault was, as guessing what the problem is without the source, is gonna be extremely hard.
  • OwenOwen Posts: 100
    edited 2007-09-28 21:04
    It is a motorized pan and tilt head, one motor drives the tilt up and down and a second motor drives the pan left and right. I attached a picture (sorry for the poor photo quality) of the device if interested.

    Thanks
    Owen
    1000 x 996 - 85K
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-09-28 21:16
    Thanks owen, I had a feeling it was angular rather than x,y let me give it some thought.

    Graham

    p.s. Looks nice!
  • BaggersBaggers Posts: 3,019
    edited 2007-09-28 21:36
    Owen, give my code a try.
    Oh, and don't forget to add the dead zone in the middle
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-09-29 19:01
    I think I've got it. Essentially the distance of the stick from the centre (radius) is the speed and the ratio of x and y gives the direction.

    Work out the radius to provide the speed, this will vary from 0 - 255 or whatever.

    The motor that needs to go the greatest speed will be asigned this speed and the other motor will be asigned a fraction of this speed taken from the values for x and y.

    e.g. 1:

    say x = 180 and y = 180 from controller, calculate R as 255 apply this to both motors as they have equal components.

    e.g. 2:

    say x = 100 and y = 50 calculate radius as 111 apply this to the x motor and apply (50/100)*111 to the y motor (half the speed).

    e.g. 3:

    x = 10 y = 50 calculate r = 51 apply this to y (as larger) and apply (10/50)*51 to z motor.

    Not sure of the easiest way to work out the radius perhaps Baggers can remember something about that fast method.

    Graham

    p.s. I'm still not completely sure all this is necessary, I think you will find that the angular speed of the camera going to a diagonal with both motors at 180 will be the same as the angular speed going to one side with a single motor going at 255 simply because when going to the diagonal the motors don't need to move as far for a given angle. In fact it comes from the fact that the two axes are orthogonal, the hypotenuse will always be longer than either of the other two sides and so will the speed in that direction.
Sign In or Register to comment.