Stepper Motors controlled by PS3 Analog sticks

I have done a search of the forums and see that several people have asked questions similar to mine, but I didn't see any satisfying answers. I figure I will ask my basic question, then lay out everything I have so that if my basic question is stupid or easily answered you don't have to waste time reading a wall of text.

Question: Is there an existing public Library that allows simultaneous, proportional, bi-directional control of 2 stepper motors using the inputs from the analog sticks of a PS3 controller? I want the left stick's Y movement only to control one motor and the X movement of the right stick to control the other motor. I understand one stick could give the right information but having 2 separate sticks would work better for my application. Any help would be awesome because I have almost no clue what I'm doing.

I have my this USB Host Shield http://tinyurl.com/ol773aq up and running on an Arduino Uno, which is hooked up to this driver http://tinyurl.com/pwd7tvp and that is driving this stepper http://tinyurl.com/lwobc2s I have gotten it to move using the AccelStepper Library AccelStepper: AccelStepper library for Arduino by uploading the Constant Speed Sketch example. Getting different RPMs by changing the step values. Thats cool.

I have gotten that same Arduino Uno with the USB Host Shield to recognize and synch with a PS3 controller using this Library http://tinyurl.com/k2262r7 using the PS3BT Example Sketch. Also cool. I understnad there is a 2.0 version of the library but I run into an issue that when I run the PS3BT example sketch for that lib I get "no matching function for call to 'PS3BT::getAnalogButton(Button)' " error and since I can get the older one to work I'm going with that.

I realize I'm not so clever that I'm the only one who has wanted to do what I am doing and I also realize that pretty much everyone else in the world could write better sketches than I could. I figure there is no reason for me to reinvent the wheel and come up with a much worse wheel if someone already has the library I am looking for built.

I did read that the step command was a blocking command so that true simultaneous control of 2 separate motors isn't possible but that interlacing the commands would make it seem simultaneous. I'm cool with that, but I do want to make these steppers move pretty fast (1500 RPM or so) I'm not sure if this is a deal breaker or not.

I originally had 2 Unos connected by 2 Xbees on the Wireless Proto Shield http://tinyurl.com/m9o6ld3 but apparently there is some pin conflicts so I had to ditch them and just use the USB and Bluetooth dongle. No biggie since the BT should give me the range I need for my project. But if anyone has any suggestions I'd love to hear them.

purple_duckk:
I did read that the step command was a blocking command so that true simultaneous control of 2 separate motors isn't possible but that interlacing the commands would make it seem simultaneous. I'm cool with that, but I do want to make these steppers move pretty fast (1500 RPM or so) I'm not sure if this is a deal breaker or not.

Writing code to control steppers is not difficult. It will be much easier if you use a proper stepper motor driver board that is suitable for your stepper motor.

Stepper motors generally do not run at high speed. I doubt if anything close to 1500 RPM will be possible.

You haven't give us any indication of what you actually want to achieve so I can't suggest any alternatives.

...R

Robin,

thanks for the reply. I would guess I don't have all of the optimum parts and pieces for what I want to accomplish because this is my first robotics project and just made guesses. I picked steppers because they move to a position and hold it. I will give you a full explanation of what I want and what I have gotten it to do so far and feel free to make any suggestions for me. I'm not married to any of the parts or pieces, I only want to make it work.

I am making, what is basically, an XY movement table. With the X being horizontal movement on a belt-drive linear actuator driven by a NEMA 17 Stepper and the Y movement being vertical based on the same actuator. X is 1500 mm and the Vertical would be somewhere between 750 to 1000 mm of movement. The Y axis actuator would be riding on the X axis gantry and the Y axis gantry would have a cardboard zombie cut out on it that could be moved left, right up and down as needed.

Ideally I would be able to make each axis go from one side to the other in around a second. I am using 2mm GT2 belt on a 30-tooth gear, so each revloution would give 60 mm of travel so I would need to spin the pulley 25 times per second to cover 1500 mm in one second which is 1500 RPM. I have the motor running with the AccelStepper Library's Constant Speed Example SetSpeed of 8800. Much faster than that and the motor won't even start turning. But at this speed I can't stall it with my hands so it still has a boatload of torque. 8800 is the amount of steps per second, and since this is a 200 step motor and I have the driver set for 1:1 stepping I assume it is turning at 44 times per second, but I haven't been able to figure out a way to test that yet. It seems to be spinning pretty fast so I think its pretty close. I'll be able to take video and upload it when I get back home Tuesday night. But 44 RPS would be above the target I am looking for so That seems good

You mentioned using a Step Controller more suitable to my motor. The motor is rated for 3.5V and the Control board is rated to run at 3.5V and has a giant heat sink on it. I have 2 of them, one for each axis, but if you have other suggestions I would be open to them.

I am still at a loss on how to combine the analog information received from the PS3 controler with the stepper control though. I don't want it to be full speed ahead or dead stop. I'd like there to be some proportional control so that 255 on the stick is 8800 steps/sec forward and 0 on the stick is 8800 steps/sec in the opposite direction 127 and 128 would be no movement.

Post links to the specifications of your motors and your driver boards and give details (volts and amps) of the power supply for your motors.

Without that information I'm just guessing.

If you want high speeds you will need to accelerate the stepper rather than start straight at the high speed.

By the way Nema 17 just defines the size of the front face of the motor and the location of the fixing holes.

The current required by the motor is more important than the voltage. With a proper stepper driver board a high voltage can be used to give torque at high speeds.

...R

Sorry, I thought I had my motors in my first post. This is what I'm using Nema 17 Bipolar 1.8deg 65Ncm (92oz.in) 2.1A 3.36V 42x42x60mm 4 Wires - 17HS24-2104S STEPPERONLINE I actually understood the nema 17 was just a size, not power, but the actuator ends fit nema 17 size, so other recommendations would need to be similar shaft and bolt pattern. But it's a pretty safe assumption I don't fully grasp this stuff. .

I'm using this powersupply at 24V I never measured the amps though. Amazon.com

The driver didn't come with any paperwork do what I know about it comes from the printing on the board and the description on Amazon. http://tinyurl.com/pwd7tvp

Product Description
Ultra-small, the overall size: 62mm * 75mm, installation of four mechanical positioning hole size: 65mm * 55, hole size ?3mm

Product Parameters

  • Rated voltage: DC 12V-24V
  • Maximum current: 3.5A
  • Current adjustable (Current Settings): 0.5A, 1A, 1.5A, 1.8A, 2A.2.5A, 3.5A
  • Subdivision adjustable (Excitation Mode): 1,2,8,16

Attenuation adjustable (Decay Mode)

0 %---- no decay mode
--- 25% of the slow decay mode
--- 50% of the normal mode
100% - Fast Decay mode
----- Decay mode of regulation by different motors to match impedance, thereby eliminating the noise when locked stepper motor and motor movement in the shake.

Automatic half current setting (Torque Settings)

%---- No pulse when the current 20 to normal operating current of 20%
50 %---- no pulse current 50% to normal operating current
75 %---- no pulse current 75% to normal operating current
100% --- no pulse when the current 100% to normal operating current

I think those should all work fine together. I presume you know how to connect the motor to the driver and the driver to the Arduino. I didn't see any pinout information on the web page. There may be stuff on the Sainsmart website.

You said

I am still at a loss on how to combine the analog information received from the PS3 controler with the stepper control though

I suggest you break this into two mini learning programs. One program will get data from the PS3 controller and save it to some global variables (and display it on the Serial Monitor so you can see what's happening). The other program will control the stepper motors (start with just one of them) based on data that you put into some global variables. To start with just put the values in while writing the program. Change a value, upload the sketch and try again - etc.

You can probably guess the next step - merge the two programs so that the values saved from the PS3 are the ones used to control the steppers. But don't waste time merging anything until the separate parts work as you want them to.

...R

I guess that's my problem. I have the ps3 controller printing to serial and I have been able to make AcellStepper give various speed instructions, but I don't know how to make them work in conjunction. I assumed someone else had similar goals. I have no faith in my ability to write a property sketch so I was going someone else already had a public library available.

Can you post some exaamples of typical numbers that you get from the PS3 and describe the corresponding action you want from the motors?

...R

Sure, it probably won't be until Tuesday night though. I won't be home until then.

purple_duckk:
Sure, it probably won't be until Tuesday night though. I won't be home until then.

OK, I should see your post, but if you think I have missed it send me a PM with a link to it.

...R

purple_duckk:
You mentioned using a Step Controller more suitable to my motor. The motor is rated for 3.5V and the Control board is rated to run at 3.5V and has a giant heat sink on it. I have 2 of them, one for each axis, but if you have other suggestions I would be open to them.

[\quote]

the 'controller' is the UNO,
the 'driver' is the "SainSmart CNC Router Single 1 Axis 3.5A TB6560 Stepper Stepping Motor Driver Board WL"

the controller has the smarts, the driver has the muscle.

the board has opto's so you have some limitation of the maximum speed based on those. may not have any bearing on your motor speed as they may be orders of magnitude faster then your signals or the maximum possible motor speed.

the driver board takes two signal, step and direction, so your output is only really one pulse train. makes it faster and easier on the controller side of the project.

as for the motor speed, your numbers seem pretty good. since you cannot stop the motor, your power is good.

the reason you cannot spin faster than about 8,800 is that the motor has to ramp up to speed. if you send the pulse train too fast, in never takes that first step. besides, it looks like 5,000 is your desired pulse frequency (25 revolutions, 200 steps per revolution)

smaller steppers can run faster RPM than larger steppers. but steppers deliver high power at low speed and the power falls off as speed increases. steppers need very smooth power signals in order to achieve higher speeds. you are charging the coil, then discharging it rapidly. the smoother that occurs the faster you can spin the motor. but the more electronics is needed to do that. cheap drivers cannot deliver higher speeds.

to test if you are loosing steps, just send the unit 1,000 steps. then measure the distance traveled.
if you need 5,000 steps to go from one end to the other, send 2,500 steps and you should be in the middle.
you can set that with timing to know your speed.

move the table to a point just well off the start, run it at your high speed for 'x' steps, return it slowly. repeat.
the slow return will not miss steps. if it returns the total 'out 'steps should equal the total 'return' steps, so you should always return to the exact same place. if it returns further, those account for the missed steps.

if you use a micro-switch, as a end stop, do not set it for direct contact. set it for glancing contact. this way, if the axis runs wild, it will not destroy the switch. also, if the table can move a few steps past the switch, (as it should), you can return, count steps, and stop at the switch, and display the difference.

a normal homing cycle is to return until the switch is made, reverse slowly until the switch opens, then reverse again and slowly move until the switch is made. this allows you to home your axis rapidly. but, you can see that you need to be able to go past the make point of the switch.

Robin, thanks for taking the time to go over this.

And Dave, your explanation of how everything works together put some of the pieces into place on what's happening between the controller, the driver and the motor. I read some of the explanations before, but your version was much clearer. With the stepper needing to ramp up to higher speed, do you think the mapping pulses proportionally to the output of the analog sticks will be enough of a ramp up? Since these steps are in fractions of a second would the ramp up time be in say, half a second be enough? Not that it would matter much for this project but once I get things working I would liked to extend out the X axis to maybe 3 or 4 meters. At that point the higher speeds might be handy.

ramping speed is selected by what works. make it as fast as you can until you start to miss steps. then back off.
I have built a few larger CNC machines and the ramp has to accommodate the mass of the axis. since you are just moving the axis, you can make it faster.

the hard part really is getting the motor moving up to speed without loosing steps.

if you have the homing switch set up, run your axis out fast and back slow a dozen times, home it each time, display the error.
if you allow the error to accumulate, remember to send the axis out 1,000 steps from where it is, not just out to 1,000.

probably a good idea to send it out slow, a dozen times, then return slow to make sure there are no inherent errors. : )

Ok, here is what I got out of the serial monitor screen when I turned on the PS3 controller. I then moved the Left Analog stick all the way to the left. I would want "0" to be full speed in one direction while 255(the limit in the opposite direction) to be full speed in the opposite direction. The middle values to be no movement and the speed of the motor to directly correspond to the position of the analog stick. The closer to neutral numbers, the slower the speed and the closer to 0 or 255, the faster the speed in the appropriate direction.

PS3 Bluetooth Library Started
Bluetooth Dongle Initialized
No response to HCI Reset
HCI Reset complete
Local Bluetooth Address: 00:1B:DC:0F:F3:8C
Wait For Incoming Connection Request
Incoming Connection Request
Remote Name: PLAYSTATION(R)3 Controller
Connected to Device: 00:1B:FB:A1:3A:AD
HID Control Incoming Connection Request
HID Control Configuration Request
HID Control Successfully Configured
HID Interrupt Incoming Connection Request
HID Interrupt Configuration Request
HID Interrupt Successfully Configured
Wait For Incoming Connection Request
Dualshock 3 Controller Enabled

LeftHatX: 116 LeftHatY: 129 RightHatX: 130 RightHatY: 126
LeftHatX: 116 LeftHatY: 129 RightHatX: 130 RightHatY: 126
LeftHatX: 116 LeftHatY: 129 RightHatX: 130 RightHatY: 126
LeftHatX: 116 LeftHatY: 129 RightHatX: 130 RightHatY: 126
LeftHatX: 116 LeftHatY: 129 RightHatX: 130 RightHatY: 126
LeftHatX: 116 LeftHatY: 129 RightHatX: 130 RightHatY: 126
LeftHatX: 116 LeftHatY: 129 RightHatX: 130 RightHatY: 126
LeftHatX: 115 LeftHatY: 130 RightHatX: 130 RightHatY: 126
LeftHatX: 111 LeftHatY: 130 RightHatX: 130 RightHatY: 126
LeftHatX: 111 LeftHatY: 130 RightHatX: 130 RightHatY: 126
LeftHatX: 111 LeftHatY: 130 RightHatX: 130 RightHatY: 126
LeftHatX: 101 LeftHatY: 133 RightHatX: 130 RightHatY: 126
LeftHatX: 101 LeftHatY: 133 RightHatX: 130 RightHatY: 126
LeftHatX: 88 LeftHatY: 135 RightHatX: 130 RightHatY: 126
LeftHatX: 88 LeftHatY: 135 RightHatX: 130 RightHatY: 126
LeftHatX: 88 LeftHatY: 135 RightHatX: 130 RightHatY: 126
LeftHatX: 75 LeftHatY: 137 RightHatX: 130 RightHatY: 125
LeftHatX: 75 LeftHatY: 137 RightHatX: 130 RightHatY: 125
LeftHatX: 63 LeftHatY: 139 RightHatX: 130 RightHatY: 126
LeftHatX: 63 LeftHatY: 139 RightHatX: 130 RightHatY: 126
LeftHatX: 50 LeftHatY: 139 RightHatX: 130 RightHatY: 126
LeftHatX: 50 LeftHatY: 139 RightHatX: 130 RightHatY: 126
LeftHatX: 37 LeftHatY: 141 RightHatX: 130 RightHatY: 125
LeftHatX: 37 LeftHatY: 141 RightHatX: 130 RightHatY: 125
LeftHatX: 37 LeftHatY: 141 RightHatX: 130 RightHatY: 125
LeftHatX: 21 LeftHatY: 141 RightHatX: 130 RightHatY: 126
LeftHatX: 21 LeftHatY: 141 RightHatX: 130 RightHatY: 126
LeftHatX: 4 LeftHatY: 141 RightHatX: 130 RightHatY: 126
LeftHatX: 4 LeftHatY: 141 RightHatX: 130 RightHatY: 126
LeftHatX: 4 LeftHatY: 141 RightHatX: 130 RightHatY: 126
LeftHatX: 0 LeftHatY: 141 RightHatX: 130 RightHatY: 125
LeftHatX: 0 LeftHatY: 141 RightHatX: 130 RightHatY: 125

Am I correct to think that the centre position is about 126, one extreme is 0 and the other extreme is 255 - you haven't shown both extremes, so I just want to be sure.

I'm not very familiar with the Accelstepper library - I know it allows you to set the max speed and the acceleration (and to change them in the program).

However before going into that it seems it would be worth spending a bit of time thinking about what you want to do.

At the bottom of all code that drives stepper motors you get to the length of the gap between subsequent step pulses. If you think about your joystick producing values between 0 and 126 (half of the movement). When it is at 0 and you want the motor to move quickly the gap between pulses should be shortest. And the gap should get longer as the value increases. In other words there is some "automatic" acceleration/deceleration associated with using a joystick.

The reason I am sayin all this is to get you to think about how fast you will be moving the joysticks. If you move them very quickly the stepper may not be able to accelerate fast enough to keep up. And what do you want to do about that? This is a design issue, not a programming issue.

If it is the sort of joystick that does NOT self centre then you may be content to use the joystick to indicate the speed you want and leave the software to get the motor to that speed in its own good time.

I think if this was my project I would do some experimenting by first of all driving the motor without using any software acceleration. It could be that it works ust as you want with little or no complication.

If you subtract 128 from the joystick value you will get a range from -128 through 0 to + 127 which can be used to determine the motor speed and direction.

...R

Yes, the extreme values are 0 and 255. I only showed one because the log of going to both extremes was pretty long and I didn't want to get too crazy. Though the center position seems to be 116 through 136 maybe. When I start the sketch from or let the sticks return themselves to neutral centered position I tend to get between 116 and 136 for a value. These analog sticks do self center

Yes, changing the pause between steps is exactly what I want to do. I am not looking for precise coordinates for movement, I am looking for being able to adjust the movement speed of the gantry on the axis proportionally to the position of the joystick. My thought was to set the Max acceleration value at just under 8800, which is the fastest I have been able to get the stepper to turn from a dead stop. Map it so that 255 is 8800 (full speed clockwise) 0 is -8800 (full speed counter clockwise) and that 116-136 are 0 (dead stop/hold). Each intergral value on the joystick would equal a change of around 74 in the "SetSpeed" field in AccelStepper. Once I get it basically working I would experiment with higher Max speed to see if the ramp of the joystick output would be enough of a ramp to allow for faster final speeds. For this project though I think the 8800 would give me enough speed to traverse 1500mm in 1 sec.

I suggest you start by getting the motors to run at a single speed in each direction when the joystick is moved either side of centre. Then extend that so it works at two different speeds depending on how far the joystick is moved. Then maybe try a 3rd or 4th speed. I suspect that may be enough and would simplify matters - especially if there is uncertainy about the central dead zone.

I wrote the following code for another Thread where the OP wanted to control a model excavator with a joystick. It used servos rather than stepper motors but the ideas are similar - probably just change the function moveServos() that drives the servos to one that drives steppers.

In his case he did not want the servos to move back to centre when the joystick is released, but I'm guessing you want the stepper to stop when you take your hand off the stick.

#include <Servo.h>

#define mainArm 0
#define jib 1
#define bucket 2
#define slew 3

Servo servo[4];

byte angle[4] = {90, 90, 90, 90};

byte potPin[4] = {A0, A1, A2, A3};
byte servoPin[4] = {12, 11, 10, 9};

void setup() {

  Serial.begin(9600);
  Serial.println("Starting DiggerCode.ino");


  for (byte n = 0; n < 4; n++) {
    servo[n].attach(servoPin[n]);
  }
}

void loop() {
  readPotentiometers();
  moveServos();
  delay(10);
}

void readPotentiometers() {
  int potVal;
  for (byte n = 0; n < 4; n++) {
    potVal = analogRead(potPin[n]);
    
    if (potVal < 450) {
      angle[n] += 1;
      if (angle[n] > 170) {
        angle[n] = 170;
      }
    }
    
    if (potVal > 570) {
      angle[n] -= 1;
      if (angle[n] < 10) {
        angle[n] = 10;
      }
    }

  }
}

void moveServos() {
  for (byte n = 0; n < 4; n++) {
    servo[n].write(angle[n]);
  }
}

...R

Holy cow, awesome! Thanks, I'll add the stepper commands and see how it works out. I'm excited to get back home and try it out, thanks!!!!