Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.

eqol

Member Since 14 Jan 2011
Offline Last Active Jan 15 2011 06:00 PM
-----

Topics I've Started

Playstation 2 Controller interface

14 January 2011 - 04:54 PM

SUP HOMIES!

So i made this cool class with which you can instantly connect your playstation 2 controller to your netduino, assuming you have 4 GPIO-ports available. I use this at the moment to control 3 servos of which 2 i have attached to the analog sticks and 1 to the d-pad. This is still somewhat work in progress, since i have not yet implemented the polling of trigger, d-pad and button pressures.

Anyways this is a very straightforward interface which i think you'll find easy to use.

PS2Controller.cs
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace Robot3DOF
{
    class PS2Controller
    {
        // I/O wires
        private OutputPort attention;
        private OutputPort command;
        private OutputPort clock;
        private InputPort data;

        // Properties, first the analog sticks' positions
        private short leftX = 127;
        private short leftY = 127;
        private short rightX = 127;
        private short rightY = 127;

        // Triggers
        private bool leftTrigger1 = false;
        private bool leftTrigger2 = false;
        private bool rightTrigger1 = false;
        private bool rightTrigger2 = false;

        // D-Pad
        private bool left = false;
        private bool right = false;
        private bool up = false;
        private bool down = false;

        // Buttons
        private bool triangle = false;
        private bool circle = false;
        private bool square = false;
        private bool cross = false;

        // Other
        private bool select = false;
        private bool start = false;
        private bool leftStickPress = false;
        private bool rightStickPress = false;

        public bool LeftStickPress
        {
            get { return leftStickPress; }
            set { leftStickPress = value; }
        }
        public bool RightStickPress
        {
            get { return rightStickPress; }
            set { rightStickPress = value; }
        }
        public bool Select
        {
            get { return select; }
            set { select = value; }
        }
        public bool Start
        {
            get { return start; }
            set { start = value; }
        }
        public bool Triangle
        {
            get { return triangle; }
            set { triangle = value; }
        }
        public bool Circle
        {
            get { return circle; }
            set { circle = value; }
        }
        public bool Cross
        {
            get { return cross; }
            set { cross = value; }
        }
        public bool Square
        {
            get { return square; }
            set { square = value; }
        }
        public short RightX
        {
            get { return rightX; }
            set { rightX = value; }
        }
        public short LeftY
        {
            get { return leftY; }
            set { leftY = value; }
        }
        public short RightY
        {
            get { return rightY; }
            set { rightY = value; }
        }
        public short LeftX
        {
            get { return leftX; }
            set { leftX = value; }
        }
        public bool LeftTrigger1
        {
            get { return leftTrigger1; }
            set { leftTrigger1 = value; }
        }
        public bool LeftTrigger2
        {
            get { return leftTrigger2; }
            set { leftTrigger2 = value; }
        }
        public bool RightTrigger1
        {
            get { return rightTrigger1; }
            set { rightTrigger1 = value; }
        }
        public bool RightTrigger2
        {
            get { return rightTrigger2; }
            set { rightTrigger2 = value; }
        }
        public bool Left
        {
            get { return left; }
            set { left = value; }
        }
        public bool Right
        {
            get { return right; }
            set { right = value; }
        }
        public bool Down
        {
            get { return down; }
            set { down = value; }
        }
        public bool Up
        {
            get { return up; }
            set { up = value; }
        }

        public PS2Controller()
        {
            // Change these pins as necessary
            this.attention = new OutputPort(Pins.GPIO_PIN_D1, false);
            this.command = new OutputPort(Pins.GPIO_PIN_D2, false);
            this.clock = new OutputPort(Pins.GPIO_PIN_D3, false);
            this.data = new InputPort(Pins.GPIO_PIN_D4, false, Port.ResistorMode.PullUp);
        }

        // This brings the controller to "config mode"
        public bool toConfigMode()
        {
            this.command.Write(true);
            this.attention.Write(false);

            gameByte(0x01);
            gameByte(0x43);
            gameByte(0x00);
            gameByte(0x01);
            gameByte(0x00);

            this.command.Write(true);
            this.attention.Write(true);
            return true;
        }

        // This brings the controller back from config mode
        public bool fromConfigMode()
        {
            this.command.Write(true);
            this.clock.Write(true);
            this.attention.Write(false);

            gameByte(0x01);
            gameByte(0x43);
            gameByte(0x00);
            gameByte(0x00);
            gameByte(0x5A);
            gameByte(0x5A);
            gameByte(0x5A);
            gameByte(0x5A);
            gameByte(0x5A);

            this.command.Write(true);
            this.attention.Write(true);
            return true;
        }

        // This sets the controller's operating mode to "analog"
        public bool toAnalogMode()
        {
            this.command.Write(true);
            this.clock.Write(true);
            this.attention.Write(false);

            gameByte(0x01);
            gameByte(0x44);
            gameByte(0x00);

            gameByte(0x01);
            gameByte(0x03);
            gameByte(0x00);

            gameByte(0x00);
            gameByte(0x00);
            gameByte(0x00);

            this.command.Write(true);
            this.attention.Write(true);
            return true;
        }

        // This polls the controller with 3 bytes header and 6 bytes data payload.
        // This could be optimized for different operating modes, for example in the digital mode only 2 bytes of data 
        // are needed. This function takes around 31ms to complete.
        public bool pollController()
        {
            byte[] data = new byte[6];

            this.command.Write(true);
            this.clock.Write(true);
            this.attention.Write(false);

            gameByte(0x01);                                   // bite 0. header.
            gameByte(0x42);                                   // bite 1. header. (should possibly put test on this byte to detect unplugging of controller.)
            gameByte(0x00);                                   // bite 2. header.

            gameByte(0x00, ref data[0]);                         // Buttons1
            gameByte(0x00, ref data[1]);                         // Buttons2
            gameByte(0x00, ref data[2]);                         // Right joy X
            gameByte(0x00, ref data[3]);                         // Right joy Y
            gameByte(0x00, ref data[4]);                         // Left joy X
            gameByte(0x00, ref data[5]);                         // left joy Y

            #region Set properties

            // My goodness, i do this for all ya n000000000000bs
            if ((data[0] & (1 << 0)) == 0) // Select
                this.Select = true;
            else
                this.Select = false;

            if ((data[0] & (1 << 1)) == 0) // L3 (joy push)
                this.LeftStickPress = true;
            else
                this.LeftStickPress = false;

            if ((data[0] & (1 << 2)) == 0) // R3
                this.RightStickPress = true;
            else
                this.RightStickPress = false;

            if ((data[0] & (1 << 3)) == 0) // Start
                this.Start = true;
            else
                this.Start = false;

            if ((data[0] & (1 << 4)) == 0) // Up
                this.Up = true;
            else
                this.Up = false;

            if ((data[0] & (1 << 5)) == 0) // Right
                this.Right = true;
            else
                this.Right = false;

            if ((data[0] & (1 << 6)) == 0) // Down
                this.Down = true;
            else
                this.Down = false;

            if ((data[0] & (1 << 7)) == 0) // Left
                this.Left = true;
            else
                this.Left = false;

            if ((data[1] & (1 << 0)) == 0) // L2
                this.LeftTrigger2 = true;
            else
                this.LeftTrigger2 = false;

            if ((data[1] & (1 << 1)) == 0) // R2
                this.RightTrigger2 = true;
            else
                this.RightTrigger2 = false;

            if ((data[1] & (1 << 2)) == 0) // L1
                this.LeftTrigger1 = true;
            else
                this.LeftTrigger1 = false;

            if ((data[1] & (1 << 3)) == 0) // R1
                this.RightTrigger1 = true;
            else
                this.RightTrigger1 = false;

            if ((data[1] & (1 << 4)) == 0) // Triangle
                this.Triangle = true;
            else
                this.Triangle = false;

            if ((data[1] & (1 << 5)) == 0) // Circle
                this.Circle = true;
            else
                this.Circle = false;

            if ((data[1] & (1 << 6)) == 0) // Cross
                this.Cross = true;
            else
                this.Cross = false;

            if ((data[1] & (1 << 7)) == 0) // Square
                this.Square = true;
            else
                this.Square = false;

            #endregion

            this.command.Write(true);
            this.attention.Write(true);

            this.LeftX = data[4];
            this.RightX = data[2];

            return true;
        }

        // Send a byte, receive a byte
        void gameByte(byte command, ref byte dataByte)
        {
            byte i;

            for (i = 0; i < 8; i++)
            {
                if ((command & (1 << i)) == (1 << i))               // Adjust command wire according to the command
                    this.command.Write(true);
                else
                    this.command.Write(false);

                this.clock.Write(false);                            // CLK to low

                if (this.data.Read() == true)                       // Hacked delay
                    dataByte |= (byte)(1 << i);

                this.clock.Write(true);                             // CLK to high
            }
            this.command.Write(true);
        }
        
        // Send byte only
        void gameByte(byte command)
        {
            byte i;
            byte data = 0x00;

            for (i = 0; i < 8; i++)
            {
                if ((command & (1 << i)) == (1 << i))               // Adjust command wire according to the command
                    this.command.Write(true);
                else
                    this.command.Write(false);

                this.clock.Write(false);                            // CLK to low

                if (this.data.Read() == true)                       // Hacked delay
                    data |= (byte)(1 << i);

                this.clock.Write(true);                             // CLK to high
            }
            this.command.Write(true);
        }
    }
}

A small application example

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace Robot3DOF
{
    public class Program
    {
        public static void Main()
        {
            Servo servo2 = new Servo(Pins.GPIO_PIN_D6); // Setting up some servos to control
            Servo servo3 = new Servo(Pins.GPIO_PIN_D5);

            PS2Controller controller = new PS2Controller();

            servo2.Degree = 0;
            servo3.Degree = 0;
            float coeff = (180f / 255f); // Needed, since the analog stick gives an 8-bit value

            while (true)
            {
                controller.pollController();

                servo2.Degree = (int)(coeff * (float)controller.LeftX);
                servo3.Degree = (int)(coeff * (float)controller.RightX);
            }
        }
    }
}

So in a nutshell

  • Connect wires
  • Instantiate controller in code
  • Poll controller state
  • Assign properties to cool stuff

Note that the controller operates at 3.3V and should be connected accordingly.

Any ideas to make this interface better will yield an aggressive and sensuel brohug from yours truly.

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.