Shop OBEX P1 Docs P2 Docs Learn Events
Playstation Controller Wired (PS2) — Parallax Forums

Playstation Controller Wired (PS2)

rough_woodrough_wood Posts: 61
edited 2005-01-26 00:19 in BASIC Stamp
I am new enough to this that I dont know if there is a difference between PS2 and PS1 controllers. For clarity I have been using a stock PS2 controller.

Using the program by Jon Williams, I chopped it up to try to make it smaller and quicker. This is my first night tinkering with it, so it isnt near done.

I am trying to use it to control a robot (which I dont have yet so I just use servos) kind of like in the article. Problem is the article doesnt really go into driving motion. Here is my version, which leaves the servo a little choppy when moving, but doesnt constantly stutter back and forth when the joystick is still. I am guessing this is because there are only 256 positions on the joystick, while moving over a range of 500 for the servo's range of motion in steps of 2. Here is what text I have in the editor: (BTW like i said this is my first program so dont risk damaging your system by just copying my well intended text, the way it is, it might be damaging the servo until the analog LED is on, but I THINK the servo is just sitting at 1010.)

' {$STAMP BS2}
' {$PBASIC 2.5}
' Based on Jon Williams program
PsxAtt PIN 8
PsxClk PIN 9
PsxCmd PIN 10
PsxDat PIN 11
Servo· PIN 15
Direct CON 0
ClockMode CON Direct
idx VAR Nib
psxOut VAR Byte
psxIn VAR Byte
psxID VAR Byte
psxThumbL VAR Byte
psxThumbR VAR Byte
psxStatus VAR Byte
psxJoyRX VAR Byte
psxJoyRY VAR Byte
psxJoyLX VAR Byte
psxJoyLY VAR Byte
duration VAR Word
HIGH PsxAtt
OUTPUT PsxCmd
PsxClk = ~ClockMode
OUTPUT PsxClk
DO
· GOSUB Get_PSX_Packet
· DEBUG HOME, BIN8 psxThumbL, " ", BIN8 psxThumbR, " "
· DEBUG DEC3 psxJoyLX, " ", DEC3 psxJoyLY, " ",
········DEC3 psxJoyRX, " ", DEC3 psxJoyRY, CR
duration = psxJoyLX
duration = duration */ 512
duration = duration + 500
DEBUG DEC4 duration, CR
LOOP
Get_PSX_Packet:
·LOW PsxAtt
·psxOut = $01 : GOSUB PSX_TxRx
·psxOut = $42 : GOSUB PSX_TxRx
·psxId = psxIn
·psxOut = $00 : GOSUB PSX_TxRx
·psxStatus = psxIn
·GOSUB PSX_TxRx : psxThumbL = psxIn
·GOSUB PSX_TxRx : psxThumbR = psxIn
·GOSUB PSX_TxRx : psxJoyRX = psxIn
·GOSUB PSX_TxRx : psxJoyRY = psxIn
·GOSUB PSX_TxRx : psxJoyLX = psxIn
·GOSUB PSX_TxRx : psxJoyLY = psxIn
·HIGH PsxAtt
·RETURN
PSX_TxRx:
PULSOUT 15, duration
·FOR idx = 0 TO 7
· PsxCmd = psxOut.LOWBIT(idx)
· PsxClk = ClockMode
· psxIn.LOWBIT(idx) = PsxDat
· PsxClk = ~ClockMode
·NEXT
·RETURN

Note mainly the location of the pulsout command, it is in the PSX_TxRx, outside the for-next While <8. I figured putting it inside the for-next it'd need pauses and would likely have a poor effect on reaction time etc. Where it is seems to get plenty of hits since its link seems to be pointed to regularly in the Get_PSX_Packet. Does anyone have any pointers on how to get the rotation to smooth out while keeping or improving on its steadyness once at its proper radial?

Comments

  • rough_woodrough_wood Posts: 61
    edited 2005-01-22 03:27
    By the way, for the connection between the controller and breadboard was this:

    A friend had a broken PS2, I tore it apart, kept many things including the controller ports.

    I pried the circuit board off the plasic part which can be seen when no controller is plugged in.

    The little sheet metal curled blank·female pluge remained with the circuit board, I just desoldered.

    I soldered on 3 inch insulated 22 guage wires, then wrapped a little electric tape around the exposed metal.

    Just slide them onto the pins in the controllers plug, then into the breadboard. Not a hard connection, but good for prototyping I figure.
  • rough_woodrough_wood Posts: 61
    edited 2005-01-22 04:21
    Well I think I found the solution to all my problems, I just dont know how to do it yet. The choppy servo motion and slow reaction can be improved on alot by only reading the joystick, and not all the other buttons and stuff I am not using. Problem is the controller probably sends these bytes out in an order. It's about time to hit the sack so I dont have time to really look into how to do it. Sounds so simple, yet the joysticks are the last to be read, and I dont think those $## values will affect this. If the joysticks were read first, you could just read them, delete the other lines, and put the HIGH PSXATT right after the joystick reading. Oh well off to bed.
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-01-24 14:54
    If your first night of tinkering turns out faster than a program I spent several days with (and after·20 years of programming) I will send you a free BASIC Stamp. Trust that I spent a lot of time on that code, and that it works around the quirks of the PS2 controller. One of the side projects I'm working on is a serial interface (using an SX micro programmed with SX/B to allow the Stamp to get data and control "shake" motors in the PS2 controller by using a single IO pin.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
  • rough_woodrough_wood Posts: 61
    edited 2005-01-24 17:41
    I was only really making it faster by getting rid of the buttons I wasnt using etc, which I still havent figured out fully. The other chunks I deleted just to make the program simpler for me to read and understand. Do you figure the choppy servo is due to the lag between pot readings? If so moving the pulsout command probably isnt the solution, but finding a way to read only the joystick byte and skipping the others is. I did speed it up slighly by changing from the left joystick to the right, then removing the left joystick readings and putting the PSXAtt HIGH. I still havent figured out how to skip:

    GOSUB PSX_TxRx : psxThumbL = psxIn
    ·GOSUB PSX_TxRx : psxThumbR = psxIn

    I need to trick it into thinking it already sent those bytes...
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-01-24 21:00
    Yes, the choppy servo is being caused by the delay between readings. You cannot fool the device into sending less information that it wants to send. You can "fix" the problem by using a dedicated servo controller, or build a PSX interface using an SX chip and SX/B (something I'm actually working on). If you insist on doing everything in PBASIC you are going to have to deal with the way things work.

    I think the best you going to do -- speed-wise -- that just gives you the joystick data is this:

    Get_Joysticks_Fast:
      LOW PsxAtt                                    ' select controller
      SHIFTOUT PsxCmd, PsxClk, LSBFIRST, [noparse][[/noparse]$01, $42] ' send "start"
      SHIFTIN PsxDat, PsxClk, LSBPOST,
        [noparse][[/noparse]psxJoyRX, psxJoyRX, psxJoyRX, psxJoyRY, psxJoyLX]
      GOSUB PSX_TxRx : psxJoyLY = psxIn
      HIGH PsxAtt                                   ' deselect controller
      RETURN
    
    

    Note that this ignores the "ready" byte from the controller, so there's no way to tell if the joystick values are valid.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
  • rough_woodrough_wood Posts: 61
    edited 2005-01-24 21:33
    Thanks for the tip, I will try it when I get home. As for the other chips, I am a 21 year old just fresh from being layed off twice at the same time and eating ramen noodles twice a day. Full die design responsibility with half the pay makes spending sprees few and far between. Hopefully I get the review I want (75% die design pay) before too long, I am really taking an interest in these things. I always programmed my TI-92 in highschool, and to have a similar language that can have physical action is pretty cool. Your job must have some nice perks.
  • rough_woodrough_wood Posts: 61
    edited 2005-01-26 00:19
    Worked great, for a long time it would jitter when I had the joystick still (probably if I used your original text it wouldnt have happened). What finally fixed it was getting rid of most the debug values I didnt need displayed. Here is the final code I came up with:

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    ' Based on Jon Williams program
    PsxAtt PIN 8
    PsxClk PIN 9
    PsxCmd PIN 10
    PsxDat PIN 11
    Servo· PIN 15
    Direct CON 0
    ClockMode CON Direct
    idx VAR Nib
    psxOut VAR Byte
    psxIn VAR Byte
    psxID VAR Byte
    psxStatus VAR Byte
    psxJoyRX VAR Byte
    duration VAR Word
    HIGH PsxAtt
    OUTPUT PsxCmd
    PsxClk = ~ClockMode
    OUTPUT PsxClk

    DO
    · GOSUB Get_Joysticks_Fast
    · DEBUG HOME, DEC3 psxJoyRX, CR
    duration = psxJoyRX
    duration = duration */ 512
    duration = duration + 500
    DEBUG DEC4 duration, CR
    PULSOUT servo, duration
    LOOP

    Get_Joysticks_Fast:
    · LOW PsxAtt··································· ' select controller
    · SHIFTOUT PsxCmd, PsxClk, LSBFIRST, [noparse][[/noparse]$01, $42] ' send "start"
    · SHIFTIN PsxDat, PsxClk, LSBPOST,
    ··· [noparse][[/noparse]psxJoyRX, psxJoyRX, psxJoyRX]
    · FOR idx = 0 TO 7
    · PsxCmd = psxOut.LOWBIT(idx)
    · PsxClk = ClockMode
    · psxIn.LOWBIT(idx) = PsxDat
    · PsxClk = ~ClockMode
    ·NEXT
    · psxJoyRX = psxIn
    · HIGH PsxAtt································ ' deselect controller
    · RETURN


    It probably wouldnt be too tough to make a small vehicle with front wheels on 1 servo, which when turned just rotates the whole axis, horrible steering geometry but who cares. Then on the psxJoyRy you could put on a motor that would move it forward and back (I think you would need an H-Bridge for reverse) without really compomising the steering that much. Skid steer would be easy by changing to Y's. I am pretty pleased with it. I still dont have an application for it but at least I am finally understanding some of the basics behind using microcontrollers. Well off to rent "Napolean Dynamite" which I hear is more stupid-funny than "Dumb and Dumber". Again thanks for helping get my feet on the ground Jon.
Sign In or Register to comment.