PS2 Control of Brushless Motor and ESC via Arduino

Control Boards, Controllers, Tethers, Ect.
User avatar
KR2_Diving
Posts: 391
Joined: Aug 30th, 2012, 11:43 am
Location: Currently: NW Suburbs of Chicago. Originally: NE Wisconsin

PS2 Control of Brushless Motor and ESC via Arduino

Post by KR2_Diving »

Right... been struggling to post the code the way i was hoping, so here is a COPY / PASTE job... Hope this works better. (if anyone knows how i can post as an attachment (.txt for example... let me know!)

Code: Select all


/*
Code by: KR2_DIVING (Ryan)

          )    O
         (   o . O
          )   () .
          /  O   o
       _.|._ o .()
      / _:_ \
     |.(_ _).|
     _\. : ./_
    / |..:..| \
   /_/ `---' \_\ 
   \_)        \_)
     \   T   /   
     _)__|__(_   
    /....|....\  
    """"" """""  
  ---KR2_DIVING---

I don't mind if you use this code for your own use.  I have made it freely available online.
However, please be sure to credit my work, and the work of Bill Porter when using or passing
this code on.

Please direct any questions to: kr 2 diving (at) gmail (dot) com

Version History
Version  Date      Notes  
-------  --------  -----
  1.0    23/09/12  First sucessful control of Motor (w/ Reverse) via Playstation2 Controller
  1.1    28/09/12  Clean up of code. No changes to functionality.  Added comments for posting to forum.
*/

#include <PS2X_lib.h>  //Library for interfacing with PS2 Controller. 
                       //Developed by: Bill Porter
                       //http://www.billporter.info/playstation-2-controller-arduino-library-v1-0/
                       
#include <Servo.h>     //include servo library

PS2X ps2x;             // create PS2 Controller Class
Servo myservo;         // create servo object to control servo
                       // maximum of eight servo objects can be created

/*#########################################
#####     VARIABLE DECLALARATIONS     #####
#########################################*/     
int servoPos = 0;      // variable to store the servo position                
int LY = 0;            // Variable for fixed values based on Left Stick Y-axis
int spd = 0;           // variable to define speed sent to motor/servo
int R1state = 0;       // used to determine state of R1
int R2state = 0;       // used to determine state of R2
int neutral = 96;      // neutral position for ESC. Will vary depending on ESC.

/*
right now, the PS2X library does NOT support hot pluggable controllers, meaning 
you must always either restart your Arduino after you conect the controller, 
or call config_gamepad(pins) again after connecting the controller.
*/


int error = 0;           // used by PS2X.lib 
byte type = 0;           // used by PS2X.lib
byte vibrate = 0;        // used by PS2X.lib

// Following are used in system just to indicate state.  
//If spare I/O is available, will include as visual display in final control setup.
int GRNled = 3;        // Green LED FULL speed
int YLWled = 4;        // Yellow LED half speed
int REDled = 5;        // Red LED Neutral
int PNKled = 6;        // Pink LED reverse

/*#########################################
#####     END OF SECTION              #####
#########################################*/     


void setup(){
 Serial.begin(57600);    // open serial communications. 
                         // baudrate selected based on reccomendation for PS2X.lib

/*####################################################
#####     DEFINE PINS OF PS2 CONTROLLER HERE     #####
#####################################################*/     
  
 error = ps2x.config_gamepad(8,11,10,12, true, false);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
 
 //Error checking from PS2X example code.
 if(error == 0){
   Serial.println("Found Controller, configured successful");
   Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
  Serial.println("holding L1 or R1 will print out the analog stick values.");
  Serial.println("Go to www.billporter.info for updates and to report bugs.");
 }
   
  else if(error == 1)
   Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
   
  else if(error == 2)
   Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
   
  else if(error == 3)
   Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
   
   //Serial.print(ps2x.Analog(1), HEX);  //Used only to debug PS2X code.
   
   type = ps2x.readType(); 
     switch(type) {
       case 0:
        Serial.println("Unknown Controller type");
       break;
       case 1:
        Serial.println("DualShock Controller Found");
       break;
       case 2:
         Serial.println("GuitarHero Controller Found");
       break;
     }
     
/*############################################
#####     DEFINE remaining pins here     #####
##############################################*/     

  myservo.attach(2);           //attach servo on pin 2 to the servo object
  pinMode(GRNled, OUTPUT);     // LED for visual confirmation of High speed mode
  pinMode(YLWled, OUTPUT);     // LED for visual confrimation of low speed mode
  pinMode(REDled, OUTPUT);     // LED for visual confirmation of Neutral state of motor
  pinMode(PNKled, OUTPUT);     // LED for visual confirmation of FWD direction of rotation
}
/*#####################################
#####     END OF void setup()     #####
######################################*/     


void loop(){
   /* You must Read Gamepad to get new values
   Read GamePad and set vibration values
   ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
   if you don't enable the rumble, use ps2x.read_gamepad(); with no values
   
   you should call this at least once a second
   */
   
   
   
 if(error == 1)                 // skip loop if no controller found
  return;
  
  ps2x.read_gamepad();          // read controller and set large motor to spin at 'vibrate' speed
  
    //set current position of Left Stick Y Axis to the variable LY
    LY = ps2x.Analog(PSS_LY);
    
    //limit value of LY to the range of 0 to 255
    //value should automatically be constrained by controller, but this is just incase!
    constrain(LY,0,255);                  
    
   //determine state of "deadman" triggers
   R1state = ps2x.Button(PSB_R1);
   R2state = ps2x.Button(PSB_R2);

/*
For this program, I only use the Y-Axis (up down) of the LEFT joystick.  The joystick has a range from 0 to 255.
0 = Full Up, 255 = Full down.  This seemed counter intuitive to me...

After testing my ESC with a Potentiometer (code available upon request),
I discovered the following ranges for controlling the ESC

0 to 63   No rotation. Maxed out?
64        MAX "reverse"
92        MIN "reverse"
93 - 100  Neutral
101       MIN "forward"
135       MAX "forward"
136 - 255 No rotation. Maxed out?

Using the map() function, I was able to convert the 0-255 input of the controller
to a 63-135 output for the ESC.

The motor will only spin when 1 of 2 "deadman" switches are held. (R1 or R2)
R1 = Full Speed mode
R2 = 50% Speed mode

50% speed mode maintains 0-255 on the input, but limits output to 78-118.

*/
 
   
    //##### Full speed mode #####
    if((R1state ==1) && (R2state==0)) {
      digitalWrite(GRNled, HIGH);            // !! There must be a better way to code these LED lights. Suggestions?
      digitalWrite(YLWled, LOW);
      digitalWrite(REDled, LOW);
            
    //set spd (speed) based on value of LY
    if((LY >= 0) && (LY <=112)){
      spd = map(LY, 0, 112, 64, 92);        //this command maps or "converts" the Joystick input to ESC output range
      digitalWrite(PNKled, HIGH);
      //Clockwise rotation
    }
    
    if((LY >=113) && (LY <=133)){
      spd = map(LY, 113, 133, 93, 100);
      digitalWrite(PNKled, LOW);
      //Neutral
    }
    
    if((LY >=134) && (LY <=255)) {
      spd = map(LY, 134, 255, 101, 135);
      digitalWrite(PNKled, LOW);
      //Counter Clockwise
    }
    
    }
    //##### Half speed mode #####
    if((R1state ==0) && (R2state==1)) {
      digitalWrite(GRNled, LOW);
      digitalWrite(YLWled, HIGH);
      digitalWrite(REDled, LOW);
     
    //set spd (speed) based on value of LY
    if((LY >= 0) && (LY <=112)){
      spd = map(LY, 0, 112, 78, 92);
      digitalWrite(PNKled, HIGH);
      //Clockwise rotation
    }
    
    if((LY >=113) && (LY <=133)){
      spd = map(LY, 113, 133, 93, 100);
      digitalWrite(PNKled, LOW);
      //Neutral
    }
    
    if((LY >=134) && (LY <=255)) {
      spd = map(LY, 134, 255, 101, 118);
      digitalWrite(PNKled, LOW);
      //Counter Clockwise
    }
    }
    
    
    //print values for debuging
    Serial.print(LY); //ps2x.Analog(PSS_LY));
    Serial.print(" ");
    Serial.print(spd);
    Serial.print(" ");
    Serial.print(ps2x.Button(PSB_R1));
    Serial.print(" ");
    Serial.println(ps2x.Button(PSB_R2));
    
    //send value to servo/motor
    if((R1state == 1) || (R2state ==1)) {
      myservo.write(spd);                    //if either "deadman" switch is held, send the correct 'mapped' speed value to the ESC.
    }
    if((R1state==0) && (R2state==0)) {
      myservo.write(neutral);                //if neither "deadman" switch is held, send 'neutral' to the Servo.
      digitalWrite(GRNled, LOW);
      digitalWrite(YLWled, LOW);
      digitalWrite(REDled, HIGH);
      digitalWrite(PNKled, LOW);
    }
    
    //allow servo/motor to achieve target speed
    delay(50);
     
}
/* I am by no means a pro at Arduino programming. If you notice any bugs, please let me know! */

You will need to download the PS2X library from the site listed in the code, as well as follow HIS guide for wiring. The trickiest part is getting the correct wires from the controller. I ended up having to open my controller and check each wire with a meter as I got a cheap third party one... my analog arrow keys do not even work as analog...

Best of luck!
DavidF
Posts: 101
Joined: Aug 27th, 2012, 1:15 pm
Location: Delaware

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by DavidF »

Perfect timing, just got my ps2 controllers in the mail 10 min ago.
DavidF
Posts: 101
Joined: Aug 27th, 2012, 1:15 pm
Location: Delaware

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by DavidF »

OK I have to admit im not much of a electronics or programming kinda guy, been staring at this code for a few hours and I have to admit im a bit lost. Is this code just for configuring the controller? then I would have to write more code once I have configured the controller to controll different out puts?
User avatar
KR2_Diving
Posts: 391
Joined: Aug 30th, 2012, 11:43 am
Location: Currently: NW Suburbs of Chicago. Originally: NE Wisconsin

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by KR2_Diving »

This code is enough to run ONE motor with the controller.


All configured and ready to go.
In theory!
DavidF
Posts: 101
Joined: Aug 27th, 2012, 1:15 pm
Location: Delaware

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by DavidF »

I guess my problem is this....
Serial.println("Found Controller, configured successful");
Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
Serial.println("holding L1 or R1 will print out the analog stick values.");
Serial.println("Go to http://www.billporter.info for updates and to report bugs.");

This seems like it is telling the computer to display the "found controller" as text on the screen, but when you go to try and talk from one arduino to another then wont the Serial.println become an issue as you would need to serial.print to the rx arduino?

Hope i make sense, like i said I suck at programming, but im a killer at the mechanical stuff :D

Edit Never mind, it dawned on me at 3am that the mega has more one rx and tx ports.....
derelicte
Posts: 292
Joined: Aug 1st, 2011, 3:08 pm

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by derelicte »

the way that code is written is for the messages to come out the main serial port. if you have a mega and want two arduinos to talk to each other, then you can send their messages out serial1, 2, etc.

you can also use the software serial library to add another uart one any two other pins.
DavidF
Posts: 101
Joined: Aug 27th, 2012, 1:15 pm
Location: Delaware

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by DavidF »

I have the arduino duemilanove, on it I think the tx and rx 0,1 are on the same line as the usb so you can use only one or the other??
Like I said, Im no electronics programer an I am probably wrong about this. But on a brighter note, I printed out the code and stared at it for a couple of hours last night and I pretty much understand it now. I just need to sit down and give it a go, I feel pretty comfortable I can get it to work, and may even add some more outputs. What I would like to see is one stick controll 2 thrusters so you can move forward and steer off of one stick. I think the map function would come in handy to do this. What do you guys think?
User avatar
KR2_Diving
Posts: 391
Joined: Aug 30th, 2012, 11:43 am
Location: Currently: NW Suburbs of Chicago. Originally: NE Wisconsin

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by KR2_Diving »

DavidF wrote: What I would like to see is one stick controll 2 thrusters so you can move forward and steer off of one stick. I think the map function would come in handy to do this.
Hey David,
My ultimate goal is one stick, 4 thrusters... I started playing with this over the weekend myself... as you correctly stated, I think the map function, along with some messy nested if statements might be the way to go... I'm not quite sure how i am going to tackle that myself.

I will keep you posted!

As for commenting on some of your other remarks: The print statements have been kept in for the moment for trouble shooting. Once I am confident with the functionality of the code, they will be removed to save on the processor.

Good Luck!
DavidF
Posts: 101
Joined: Aug 27th, 2012, 1:15 pm
Location: Delaware

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by DavidF »

Im going to run the code by my boss and see what his thoughts are, he is an old fart... oops LOL " edit" He knows a bit about programming things like this and might have a better idea :D
derelicte
Posts: 292
Joined: Aug 1st, 2011, 3:08 pm

Re: PS2 Control of Brushless Motor and ESC via Arduino

Post by derelicte »

yeah, on the non mega arduinos the single serial port is shared with the usb connection. that is why I suggested using the softwareserial library for extra serial ports for inter-arduino communications. you don't need to send a whole lot of data, so 9600 baud is fine. when I use the softwareserial ports, I try to run them slower than the hw ones.

If you look at my code, I have all the math to drive two thrusters from a single stick. It is actually pretty simple.
Post Reply