Propeller C for PS2 Game Controller?
I would like to integrate a Lynxmotion PS2 Controller to the Propeller Activity Board. Two questions;
1. Pin connection diagram for the PS2 Controller to the Prop?
2. Is there a Prop C program for the PS2 Controller?
Thanks, Brian
1. Pin connection diagram for the PS2 Controller to the Prop?
2. Is there a Prop C program for the PS2 Controller?
Thanks, Brian
Comments
It's probably best to first check Lynxmotion's documentation on the product, but if all else fails, this PS2 Adapter Cable diagram seems helpful.
Thank you so very much!! Will give it a try!!
Very Much Appreciate It!!!
Brian
Are you aware most of the buttons on a PS2 controller are pressure sensitive? The controller has to be put into analog mode to read the analog values from the buttons.
I keep hoping to come up with some cool application for the analog buttons on a PS2 controller but I have yet to do so.
I added the ability to read these analog values to Juan Carlos Orozco's PS2 object. Here's a link to the thread on the subject.
http://forums.parallax.com/showthread.php/139611-PlayStation-2-Analog-Buttons
If someone wants to add analog button support to the C code they could look through my Spin/PASM code for some hints.
Success, sort of.
Duane,
Thanks for the reminder about the "Analog" mode; however;
Andy,
I checked the connection diagram from Lynxmotion and it matched your diagram except it didn't show a "branch" coming off of the DAT line going towards 3.3v, through the 10k resistor. I ran the program with the controller connected as per the Lynxmotion diagram and the results were;
I could read all of the buttons, however when I tried the "pressjoystick", nothing happened and when I tried moving the joysticks it was reading as though I was pressing a button. Example, right joystick up, read a "1" on the "triangle"; right joystick down, read a "1" on the "cross". The same on the left joystick, reading "1's" as though I'm pressing the 4-pos switch above it. I added the branch line with the 10k resistor just to eliminate that difference and got the same results.
Any ideas as to what I'm doing incorrectly?
Thank you for your help,
Brian
The Lynxmotion diagram probably assumes the microcontroller has internal pull-up resistors. The AVR chips used in Arduino boards have internal pull-up resistors but the Propeller doesn't.
I suggest testing the code using Andy's schematic and see if it works correctly.
The controller might start in button-only mode, and has to be switched over to add joystick info. If you changed the wiring already, go back to the setup that worked with the buttons, and verify that it is working. Then, press the Analog button on your controller (or it might say Mode). After that, try the joysticks, and hopefully the data will be correct.
Andy
As always your help is very much appreciated.
Brian
Also, the circuit that branches off the DAT line is called a pull-up resistor. The SONY wireless controller I used for prototyping needed it because its receiver sends either low or input. When it sends input, the pull-up resistor, pulls the voltage up to a 3.3 V high signal. The Lynxmotion version might have that pull-up resistor built-in. If so, it would make sense that it works either with or without the pull-up.
Andy
I remember this button only mode now. I'm pretty sure it's possible to switch modes with software.
As I mentioned earlier there's yet another mode which will read most of the buttons as analog values.
Thank you,
Brian
Brian, Let's try Duane's library and see if it works for you. That could provide clues as to whether we need to examine my code or your controller more closely. I modified the attached example code to work with your existing wiring and the Parallax Serial Terminal's default baud rate, and tested to make sure it communicated with my controllers.
Since this is a Spin example and library, here is a link to the Propeller Tool and Parallax Serial Terminal: https://www.parallax.com/downloads/propeller-tool-software
Tried pressing "B" with no change on buttons or joysticks. What do you all think?
Brian
I modified the Spin code so that it works with the wiring shown in post #2. Please try the Spin code attached to post #13 with the wiring that was already working (partially) with the C code.
Also, what happens when you press the Analog button twice, or three times?
I wired the controller per the diagram in Post #2 and ran the C-Code again just to verify it was responding as before. And, yes, the Analog light stayed on no matter what I pressed. All the buttons recorded a "1" when I pressed them and when I operated the joysticks, like before the button identifier for the button above that joystick would register a "1"; i.e. right joystick moved forward, triangle button would read a "1". Left joystick did the same thing. Pressing the "Analog" button on the controller didn't have any effect; light on constantly. Without changing any wiring I immediately ran the Spin code you provided with the Serial Terminal Enabled and the controller functioned correctly in "Analog" and "Analog Button" mode. On the joysticks I had full 0-255 on both up/down and left/right. All the buttons registered a "1" when pressed. The "Analog" light did stay on even in the "D" mode. The only time I got any change on the light was if I left the controller on and turn off power to the Prop and Controller Adapter card; the light would begin to flash. It appears the controller is working correctly, except for the light issue, just need guidance on what to change in the "C" code to read the joysticks.
Thank you again for your help!!
Brian
Andy
The new code did work, THANK YOU! Can you tell me what you did differently? For my education.
Interestingly, the ANALOG light on the controller stayed on no matter what I did. That is weird.
Again, Thank you Andy and Thank you Duane for your help!!!
Brian
The code (header, test harness, and library functions all flattened into a single file) is below. Hopefully you, Duane and others will add your names to the authors list in the comments as you make it awesome. After that, maybe it can be re-bundled and added to OBEX, or to the Simple Libraries.
About your question, it's probably a good idea to take a look at this page for background info on how the signalling and packet exchanges work this page.
The code that communicates with the controller is near the bottom, in the ps2_game function. That function gets launched into another cog by the pstgame_open function. I was in a hurry due to some pressing deadlines, so the ps2_game function uses a couple of hacks. The first is that shift_out and shift_in work with an active-high clock signal, but the PS2 controller depends on an active-low clock. So, the trick I used was to manually shift the first bit using a high to low signal. Then, the other shift_out functions that followed had the data shifted one bit to the right to make up for it and correctly transfer the bytes in the poll array to request updated data before shifting that data in. The shift_out and shift_in functions are half duplex SPI. Full duplex would be more appropriate because data also comes in with each clock pulse.
The ps2_game function (in a hurry) hacks seemed to work until your PS2 controller's Analog button refused to take the device into Analog joystick mode. But, Duane's spin object succeeded. To address this, I first revisited the spin library I was converting, and found the bug I had introduced while I was porting it. After that, I found out that that library (which shall not be named) had a bug in the PASM code that shifted bits and was missing one of the buttons, so I abandoned that approach and went back to the ps2gamelite library.
In ps2gamelite, I started by adding set, bytecount and *array to the ps2game_st structure so that the two functions running in different cogs could communicate. ps2game_setAnalog sets those values, and ps2_game was modified to monitor device->set, and call ps2_game_configure if device->set is not zero. (Note device-> is a pointer to an instance of the ps2game_t data type, which is a ps2game_st structure. This allows C to emulate Spin's object multi-instance.) The thing that causes the value of device->set to change from zero is a call to ps2game_start, which calls ps2game_setAnalog after launching ps2_game into another cog.
The ps2game_setAnalog function sets device->byteCount to 9, device->array to point at the first of three arrays that need to be shifted to the PS2 controller. After a 2 ms pause (where locks would probably be an improvement), device->set is set to 3. The ps2_game function running in the other cog notices this, and calls ps2game_configure, which has some custom shifting to transmit other array strings. It uses the address stored in device->array to transmit the enterEscape string. setAnalog waits until device->set drops from 3 to 2, which is the ps2game_configure function's way of signaling that it's done transmitting the array. After that ps2game_setAnalog repeats the process by setting up the setAnalogMode string for transmission, and after that, the exitEscape string. That's how the Propeller C code moves the controller into analog mode.
If you want the option of using the buttons without any analog joystick info, you could comment the ps2game_setAnalog(device) call from the ps2game_open function, and then just add it to your main function as a ps2game_setAnalog(player1) call, after a call to ps2game_open.
Very helpful and informative. I very much appreciate the "Education Lesson" also!
Thank you again for your work on this!!
Awesome!
Brian
The code I attached is still a work in progress, I left a lot of commented code in place to illustrate the changes made. Please accept that I am still a novice in C, have never worked with structures before, so things may look a little messy - but it does work.
Thanks Brian
Happy Thanksgiving!! Brian.