Go Down

Topic: PS2 Controller over xBee (Read 2838 times) previous topic - next topic

Hello All,

I am trying to get some code working for this build that I followed: http://www.adafruit.com/blog/2012/04/23/weekend-project-arduino-xbee-ps2-controller-20-channel-universal-project-controller/

My current hardware is a 3.3v Arduino Mini Pro inside of the PS2 Controller connected to a Xbee XB24-Z7SIT-004 module that has been configured as a Coordinator in AT mode to communicate at 57600 baud. At the receiving end is a Arduino Uno connected to a Xbee XB24-Z7SIT-004 module via an Explorer that is configured as a Router in AT mode set to 57600 baud. Both have been programmed using the Arduino 1.0.3 software. At both ends the xbee's are connected via the hardware serial RX/TX pins. When I try to communicate between the xbee's I am not connected to the Uno via USB as I understand this would interfere with the hardware serial. When both the receiver and controller are powered up I see no activity on the Explorer in form of rx/tx led's flashing however the RSSI led does light up. A servo I have connected to pin 8 does seem to respond by just jittering around but does not seem to be affected by the joystick movement. If I press reset on the controller the servo stops jittering which leads me to believe there is some sort of connectivity between the devices. I am new to the arduino environment and am still learning the code, one thing I noticed is the serial.flush command and come to learn this no longer acts the way it previously did by clearing the receiving buffer. I tested the code by commenting out the 2 serial.flush commands with no change in the results. Since I was at a loss I then connected the xbee receiver through the usb of the explorer to my Mac using the CoolTerm terminal set to 57600 baud and would receive the following string over and over again every 100ms when in the "neutral" state on the controller without any buttons pressed:


So I guess...
0 <--Byte 1, this changes depending on L1, L2, L3, R1, R2, R3, Select, Start button being pressed (1, 2, 4, 8, 16, 32, 64, 128)
0 <--Byte 2, this will change depending on the direction pad button or Square, X, Circle, Triangle button pressed (1, 2, 4, 8, 16, 32, 64, 128)
114 <-- Byte 3, this changes depending on the Left Y stick position (0-255)
140 <-- Byte 4, this changes depending on the Left X stick position (0-255)
119 <-- Byte 5, this changes depending on the Right Y stick position (0-255)
156 <-- Byte 6, this changes depending on the Right X stick position (0-255)

So I'm thinking my comm is good between xbee devices but maybe my code is of a older version.

Code: [Select]
// This program compiles the Playstation controller button statuses into a 6 byte string.
// The first 2 bytes contain button status and the last 4 contain the thumbstick positions.
// by Adam Kemp, 2012 http://code.google.com/p/smduino/

#include <PS2X_lib.h>  //for v1.6 (Thanks to Bill Porter for a wicked library http://www.billporter.info/playstation-2-controller-arduino-library-v1-0/)

PS2X ps2x; // create PS2 Controller Class

int battLow = 801;  //Batt low value determined from 22k/100k voltage divider. Represents ~3.3V
boolean lowBattWarning = false; //flag for a low battery condition
boolean ledState = false; //used for flashing LED during a low power condition
unsigned long currentTime = 0;

void setup(){
  pinMode(13, OUTPUT);
  for (int i = 0; i < 4; i++) { //check status LED
    digitalWrite(13, HIGH);
    digitalWrite(13, LOW);
ps2x.config_gamepad(3,4,5,6);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
  digitalWrite(13, LOW);


void loop(){

  byte buttons = 0;
  byte dPads = 0;
  bitWrite(buttons, 0, ps2x.Button(PSB_SELECT)); //byte 1, bit 0
  bitWrite(buttons, 1, ps2x.Button(PSB_START)); //byte 1 , bit 1
  bitWrite(buttons, 2, ps2x.Button(PSB_L1)); //byte 1, bit 2
  bitWrite(buttons, 3, ps2x.Button(PSB_R1)); //byte 1, bit 3
  bitWrite(buttons, 4, ps2x.Button(PSB_L2)); //byte 1, bit 4
  bitWrite(buttons, 5, ps2x.Button(PSB_R2)); //byte 1, bit 5
  bitWrite(buttons, 6, ps2x.Button(PSB_L3)); //byte 1, bit 6
  bitWrite(buttons, 7, ps2x.Button(PSB_R3)); //byte 1, bit 7
  bitWrite(dPads, 0, ps2x.Button(PSB_PAD_UP)); //byte 2, bit 0
  bitWrite(dPads, 1, ps2x.Button(PSB_PAD_DOWN)); //byte 2, bit 1
  bitWrite(dPads, 2, ps2x.Button(PSB_PAD_LEFT)); //byte 2, bit 2
  bitWrite(dPads, 3, ps2x.Button(PSB_PAD_RIGHT)); //byte 2, bit 3
  bitWrite(dPads, 4, ps2x.Button(PSB_GREEN)); //byte 2, bit 4
  bitWrite(dPads, 5, ps2x.Button(PSB_BLUE)); //byte 2, bit 5
  bitWrite(dPads, 6, ps2x.Button(PSB_PINK)); //byte 2, bit 6
  bitWrite(dPads, 7, ps2x.Button(PSB_RED)); //byte 2, bit 7
  Serial.print(buttons); //prints byte 1
  Serial.print(dPads); //prints byte 2
  Serial.print(ps2x.Analog(PSS_LY)); //prints left y thumbstick value
  Serial.print(ps2x.Analog(PSS_LX)); //prints left x thumbstick value
  Serial.print(ps2x.Analog(PSS_RY)); //prints right y thumbstick value
  Serial.print(ps2x.Analog(PSS_RX)); //prints right x thumbstick value
  byte battStat = map(analogRead(0), 801, 1024, 0, 100); //reads batt voltage and calculates a percentage. 3.3v = 0%
  if (battStat <= 10) { //not tested, but checks if the battery is below 10%
    lowBattWarning = true;
  if (lowBattWarning) { //if battery is below 10% start flashing the LED
    if (millis() > currentTime + 1000) {
      currentTime = millis();
      digitalWrite(13, !ledState);
delay(100); //rinse, wash, repeat

Code: [Select]
// This program is intended as a simple test that data is being properly recieved from the controller.
// Data is recieved as a 6 byte packet. Bytes 3 & 5 are read and used to drive a 2 servo tank robot.
// by Adam Kemp, 2012 http://code.google.com/p/smduino/

#include <Servo.h>

Servo lServo; //init servos
Servo rServo;
byte lServoPos; //servo position var
byte rServoPos;
byte buttons = 0; //button byte
byte dPads = 0; //dpads byte
byte LY = 128; //neutral value for servo position (in byte form)
byte LX = 128;
byte RY = 128;
byte RX = 128;

byte LYOffset = 0; //offset is designed to account for thumbstick wiggle
byte RYOffset = 0;

void setup() {
  pinMode(13, OUTPUT);
  calibrate(); //read neutral thumbstick positions

void loop() {
  if (Serial.available() >= 6) { //waits until the 6 bytes are read into buffer
    buttons = Serial.read(); //reads byte 1
    dPads = Serial.read(); //reads byte 2
    LY = Serial.read(); //reads byte 3
    LX = Serial.read(); //reads byte 4
    RY = Serial.read(); //reads byte 5
    RX = Serial.read(); //reads byte 6
    Serial.flush(); //clears buffer
    LY = 255 - LY; //inverts LY value
    if (LY <= LYOffset) { //attaches LY offset to inverted value
      LY == LYOffset;
    lServoPos = map(LY-LYOffset, 0, 255, 0, 180); //converts the thumbstick byte value to a 0 - 180 value for the servos
    rServoPos = map(RY+RYOffset, 0, 255, 0, 180);
    if (lServoPos >= 70 && lServoPos <= 110) { //if value is within a NULL range, turn off the servo
      lServoPos = 90;
    if (rServoPos >= 70 && rServoPos <= 110) {
      rServoPos = 90;
    lServo.write(lServoPos); //drives the servos

void calibrate() {
  for (int i = 0; i < 5; i++) { //loop for 5 seconds
    digitalWrite(13, HIGH);
    if (Serial.available() >= 6) {
      buttons = Serial.read();
      dPads = Serial.read();
      LY = Serial.read();
      LX = Serial.read();
      RY = Serial.read();
      RX = Serial.read();
      LYOffset = 128 - LY; //determines the value away from 128 that the thumbsticks see as neutral
      RYOffset = 128 - RY;
      Serial.flush(); //clears serial buffer
    digitalWrite(13, LOW);

I would appreciate any help or thoughts on the project. It was really fun getting it working up to this point and have big plans for using it.

Everything works as expected now. I changed the serial.print's to serial.write on the controller code and commented out the serial.flush lines on the receiver code.

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131