Using Stepper motors to lift a model bridge

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Using Stepper motors to lift a model bridge

Post by adafruit_support_bill »

Yes, that should do it.

User avatar
roadshark
 
Posts: 652
Joined: Sun Nov 29, 2015 5:53 am

Re: Using Stepper motors to lift a model bridge

Post by roadshark »

I have got two motors set up using the MP6500 driver to test out the code. The code compiles but the motors just sit there and do nothing. I used this code to see if I had everything hooked up properly and it works.

Code: Select all

// MultiStepper.pde
// -*- mode: C++ -*-
// Use MultiStepper class to manage multiple steppers and make them all move to
// the same position at the same time for linear 2d (or 3d) motion.

#include <AccelStepper.h>
#include <MultiStepper.h>

// EG X-Y position bed driven by 2 steppers
// Alas its not possible to build an array of these with different pins for each :-(
AccelStepper stepper2(AccelStepper::FULL4WIRE, 23, 25, 27, 29);
AccelStepper stepper3(AccelStepper::FULL4WIRE, 31, 33, 35, 37);

// Up to 10 steppers can be handled as a group by MultiStepper
MultiStepper steppers;

void setup() {
  Serial.begin(9600);
  pinMode (29, OUTPUT);
  pinMode (37, OUTPUT);
  digitalWrite(29, LOW); //sets the voltage (MP6500)to 1.5 amps motor 1
  digitalWrite(37, LOW); // sets the voltage (MP6500)to 1.5 amps motor 2
  pinMode(22, OUTPUT);
  pinMode(24, OUTPUT);
  pinMode(26, OUTPUT);
  pinMode(28, OUTPUT);

  digitalWrite (22, LOW);// used to set the number of steps  quarter/half/full
  digitalWrite (24, LOW);
  digitalWrite (26, LOW);
  digitalWrite (28,LOW);
  // Configure each stepper
  stepper2.setMaxSpeed(1000);
  stepper3.setMaxSpeed(1000);

  // Then give them to MultiStepper to manage
  steppers.addStepper(stepper2);
  steppers.addStepper(stepper3);
}

void loop() {


  long positions[2]; // Array of desired stepper positions

  positions[0] = 1000;
  positions[1] = 1000;
  steppers.moveTo(positions);
  steppers.runSpeedToPosition(); // Blocks until all are in position
  delay(1000);

  // Move to a different coordinate
  positions[0] = -3000;
  positions[1] = -3000;
  steppers.moveTo(positions);
  steppers.runSpeedToPosition(); // Blocks until all are in position
  delay(1000);
}
However when it gets to the first part where it stops I thought it would reverse position because of this -300 but it just keeps going forwards.
So I am not sure why my bridge lifting code does not work.
A second issue is that the motors I am using for testing
Electrical parameters

General specification Electrical specification
Step angle 1.8° Rated voltage 3.3V
Number of phase 2 Rated current 1.5A
Insulation resistane 100MΩmin.(500V DC) Resistance per phase 2.2Ω±10%
Insulation class Class B Inductance per phase 5.0mH±20%
Rotor inertia 57g.cm ² Holding torque 450mN.m
Mass 0.24kg Detent torque 15mN.m

Have a rated voltage of 3.3. If I try and run them at this voltage they do not turn. If I increase the voltage to 7 volts they work fine. Is this because I have put a current limit of 1.5 amps and should I be using 7 volts. Here is the bridge lifting code

Code: Select all

#include <Wire.h> // Enable this line if using Arduino Uno, Meg

#include <AccelStepper.h>
#include <MultiStepper.h>
// AccelStepper Setup
AccelStepper stepperLH(AccelStepper::FULL4WIRE, 23, 25, 27, 29);//Left hand motor  23 step, 25 direction, 27 voltage (I1) HIGH, 29 voltage(I2) LOW
AccelStepper stepperRH(AccelStepper::FULL4WIRE, 31, 33, 35, 37);//Right hand motor 31,      33,           35,                   37
MultiStepper steppers;

// Stepper Travel Variables

long initial_homing = -1; // Used to Home Stepper at startup

#define home_switch1 10 // Pin 10 connected to Home Switch (MicroSwitch)
#define home_switch2  9 // Pin 9 connected to Home Switch (MicroSwitch)
#define button_BridgeLiftBegin 8 // Pin 8 connected to button to begin bridge lift sequence
#define button_Bridge Lower Sequence 7 // Pin 7 connected to button to begin bride decent sequence 

void setup() {


  Serial.begin(9600);

  // Configure each stepper
  stepperLH.setMaxSpeed(100);
  stepperRH.setMaxSpeed(100);
  

 


  pinMode(10, INPUT_PULLUP); //button homing switch 1
  pinMode(9, INPUT_PULLUP); //button homing switch 2
  pinMode(8, INPUT_PULLUP); //button bridge accent
  pinMode(7, INPUT_PULLUP); //button bridge decent
  pinMode(25,OUTPUT);// Write this pin LOW to limit current to 1.5 amps
  pinMode(37,OUTPUT);//Write this pin LOW to limit current to 1.5 amps
  pinMode(22, OUTPUT);// steps
  pinMode(24,OUTPUT);//steps
  pinMode(26,OUTPUT);//steps
  pinMode(28,OUTPUT);//steps
  
  digitalWrite (25,LOW);
  digitalWrite (37, LOW);
  
  digitalWrite (22, HIGH); //designates the number of steps
  digitalWrite (24, HIGH); //
  digitalWrite (26, HIGH);//
  digitalWrite (28, HIGH);//



  // Start Homing procedure of Stepper Motor at startup

  Serial.print("Stepper is Homing . . . . . . . . . . . ");
   while (digitalRead(home_switch1)|| digitalRead(home_switch2)) 
  {  // Move motors towards home until both switches are activated
    if(digitalRead(home_switch1))
    stepperLH.moveTo(initial_homing);// homing switch on this motor should stop both motors
    if (digitalRead(home_switch2))
    stepperRH.moveTo(initial_homing);// Set the position to move to
    initial_homing--;  // Decrease by 1 for next move if needed
    steppers.run();  // Start moving the steppers
  }



  stepperLH.setCurrentPosition(0);  // Set the current position as zero for now
  stepperRH.setCurrentPosition(0);
  stepperLH.setMaxSpeed(100.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperRH.setMaxSpeed(100.0);
  
  initial_homing = 1;
  while (!digitalRead(home_switch1)|| !digitalRead(home_switch2)) 
  {  // Move motors away from home until both switches are deactivated
    if(digitalRead(home_switch1))
    stepperLH.moveTo(initial_homing);// homing switch on this motor should stop both motors
    if (digitalRead(home_switch2))
    stepperRH.moveTo(initial_homing);// Set the position to move to
    initial_homing++;  // increase by 1 for next move if needed
    steppers.run();  // Start moving the steppers

  
  }

  stepperLH.setCurrentPosition(0);
  stepperRH.setCurrentPosition(0);
  Serial.println("Homing Completed");
   // give stepperLH & stepperRH  to MultiStepper to manage
  steppers.addStepper(stepperLH);
  steppers.addStepper(stepperRH);



}



void loop() {

  if (digitalRead (8) == LOW) {//raises the bridge deck
    while (digitalRead(8) == LOW);
    long positions[2]; // Array of desired stepper positions

    positions[0] = 1000;//Maximum elevation of the liftedbridge  deck
    positions[1] = 1000;//Maximum elevationof the lifted bridge deck
    steppers.moveTo(positions);
    steppers.runSpeedToPosition(); // Blocks until all are in position


  }
  if (digitalRead (7) == LOW) {//Lowers the bridge deck
    while (digitalRead(7) == LOW);
    long positions[2]; // Array of desired stepper positions

    positions[0] = 0;//Maximum elevation of the liftedbridge  deck
    positions[1] = 0;//Maximum elevationof the lifted bridge deck
    steppers.moveTo(positions);
    steppers.moveTo(positions);
    steppers.runSpeedToPosition(); // Blocks until all are in position


  }



}

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Using Stepper motors to lift a model bridge

Post by adafruit_support_bill »

The code compiles but the motors just sit there and do nothing.
AccelStepper and MultiStepper are different from the Adafruit motor shield library. The run() function - and all of its variants is not a blocking function. You need to call it frequently and repeatedly for the motors to run.

As written, I'd expect your code to take one step forward, followed by a 1 second delay, then one step back on each iteration of the loop.
Have a rated voltage of 3.3. If I try and run them at this voltage they do not turn.
Yea, you need to read between the lines to understand voltage ratings in a stepper motor spec sheet. 3.3v is the maximum DC voltage that will not exceed the current rating. But the motor was never intended to run from a 3.3v supply. Based on the low phase resistance, it was clearly intended to be used with a current-limiting "chopper" driver. Running with a higher supply voltage and active current limiting, you can get higher performance from a small motor without it melting down. There is a detailed explanation of that here:
https://learn.adafruit.com/all-about-st ... aw-1460534

User avatar
roadshark
 
Posts: 652
Joined: Sun Nov 29, 2015 5:53 am

Re: Using Stepper motors to lift a model bridge

Post by roadshark »

Went to the article you suggested to drink from the knowledge tree. "requires a good understanding of both the motor and the controller." I think I am shot!!! Is the driver I am using a '(pololu mp6500) a 'chopper' driver? (I am sure there is a 'pun' somewhere there.) At 7 volts with current limiting at 1.5 amps the motors runs well and are not heating up so I am assuming it is ok to do this.
Now for the code so I need call the run function often Mmmmmm. I will have a go at it.
Thx.

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Using Stepper motors to lift a model bridge

Post by adafruit_support_bill »

The mp6500 is indeed a 'chopper'. Early versions of current limiting drivers would 'chop' the power when it reached the current limit. More modern chips like the mp6500 are a bit more graceful about it, but the bottom line is that they allow you to get more torque out of the motor without burning it up.

Since you are using the AccelStepper library, I'd recommend getting familiar with the acceleration/deceleration capabilities and making use of them in your model. This will give you a more realistic motion, as well as reducing wear & tear on the system. Just as you cannot accelerate your velocipede from 0 to 40kph in a single pedal stroke without snapping a chain or a tendon, you need a gentle start to get several thousand tons of steel in motion without snapping cables.

User avatar
roadshark
 
Posts: 652
Joined: Sun Nov 29, 2015 5:53 am

Re: Using Stepper motors to lift a model bridge

Post by roadshark »

On looking at videos of the bridge in action it is a very slow process lifting that steel indeed! I was hoping to use the multistepper library as I thought it would make it easier to run the two steppers simultaneously. I found that the multistepper library does not support acceleration! So would I be able to use the standard AccelStepper library instead? I have gone back and tried to just do 1 stepper motor turn until it hits the home button, then it reverses off the button stops and sets its position at 0 ready for the main loop. In this code the stepper starts moving in ccw direction. When I press the home button there is a slight hesitation then it continues in a ccw direction until I release the button which stops it. I thought it should go cw until the button is released. At the moment it would keep turning against the switch. How do I get it to reverse direction! I thought this code did this.

Code: Select all

 while (!digitalRead(home_switch)) { // Make the Stepper move CW until the switch is deactivated
    stepperLH.moveTo(initial_homing);  
    initial_homing++;
    stepperLH.run();
  }
What am I missing here?

Code: Select all

#include "AccelStepper.h" 
// Library created by Mike McCauley at http://www.airspayce.com/mikem/arduino/AccelStepper/

// AccelStepper Setup
AccelStepper stepperLH(AccelStepper::FULL4WIRE, 23, 25, 27, 29);
// Define the Pins used
#define home_switch 9 // Pin 9 connected to Home Switch (MicroSwitch)
// Stepper Travel Variables

long initial_homing=-1;  // Used to Home Stepper at startup

void setup() {
  
   pinMode(home_switch, INPUT_PULLUP);
   
//  Set Max Speed  of each Steppers at startup for homing
  stepperLH.setMaxSpeed(200.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  
 // Start Homing procedure of Stepper Motor at startup

   while (digitalRead(home_switch)) {  // Make the Stepper move CCW until the switch is activated   
    stepperLH.moveTo(initial_homing);  // Set the position to move to
    initial_homing--;  // Decrease by 1 for next move if needed
    stepperLH.run();  // Start moving the stepper
  
}

  stepperLH.setCurrentPosition(0);  // Set the current position as zero for now
  stepperLH.setMaxSpeed(200.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
 
  initial_homing=1;

  while (!digitalRead(home_switch)) { // Make the Stepper move CW until the switch is deactivated
    stepperLH.moveTo(initial_homing);  
    initial_homing++;
    stepperLH.run();
  }
  stepperLH.setCurrentPosition(0);
  stepperLH.setMaxSpeed(100.0);      // Set Max Speed of Stepper (Faster for regular movements)
  
}

void loop() {

 
  
  }

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Using Stepper motors to lift a model bridge

Post by adafruit_support_bill »

Yes, you can run multiple motors simultaneously with AccelStepper. You just need to call run() on each of the motors. See the example here: http://www.airspayce.com/mikem/arduino/ ... ample.html

In your code above, you are initializing the stepperLH as AccelStepper::FULL4WIRE. That might explain the failure to reverse. With the MP6500 you should be using AccelStepper::DRIVER.

User avatar
roadshark
 
Posts: 652
Joined: Sun Nov 29, 2015 5:53 am

Re: Using Stepper motors to lift a model bridge

Post by roadshark »

GOLD STAR BILL...That was the issue. I am using a 4 wire stepper motor. So this AccelStepper stepperLH(AccelStepper::DRIVER, 23, 25, 27, 29); Can become this AccelStepper stepperLH(AccelStepper::DRIVER, 23, 25); So I would drive I1 &I2 on the mp6500 from the mega pins to regulate the voltage? Because I had a 4 wire motor I thought I had to use the FULL4WIRE command?
Does this command stepperRH.setAcceleration(50.0); also set the deacceleration as it nears the end position?

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Using Stepper motors to lift a model bridge

Post by adafruit_support_bill »

You are using 4-wire motor, but the MP6500 driver chip is taking care of the low-level control of all the stepping phases. You just need 2 pins to give it a direction and a pulse per step.

And yes, the setAcceleration should automatically take care of deceleration as you approach the target position.

User avatar
roadshark
 
Posts: 652
Joined: Sun Nov 29, 2015 5:53 am

Re: Using Stepper motors to lift a model bridge

Post by roadshark »

thx:) Yes the motor is slowing down. Great! I am converting the 12 volts using a buck converter to 9 volts for the motors however I used jumper wires to supply the current to the motors via the capacitor. I guess the current was a bit much as the jumper wires started to heat up and were very warm and some smoke was seen:( Now lets try for 2 motors and 2 homing switches and some heavier gauge wire!

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Using Stepper motors to lift a model bridge

Post by adafruit_support_bill »

What is the purpose of the buck regulator? The MP6500 can handle up to 35v. As long as you set the current limiting appropriately, your motors are safe with the 12v supply.

User avatar
roadshark
 
Posts: 652
Joined: Sun Nov 29, 2015 5:53 am

Re: Using Stepper motors to lift a model bridge

Post by roadshark »

I was running them on 12 volts but one of the motors got really warm. Maybe I didn't have the current limit set right. My understanding would be to leave on the mp6500 pin I1 disconnected and driving I2 LOW should give me 1. 5 amps.

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Using Stepper motors to lift a model bridge

Post by adafruit_support_bill »

Current to the motor will be the same for any supply voltage above 3v or so. So 9v or 12v will make no difference in heating.

What you can do to limit heating is to use a lower current limit. Since you can control that from your Mega, you can drop the current limit down to 0.5A when the bridge is not moving.

Alternately, you can use the sleep pin to cut all power to the motor. If your bridge is well enough balanced, the natural cogging of the motor should be sufficient to prevent back-driving via the lead-screw.

User avatar
roadshark
 
Posts: 652
Joined: Sun Nov 29, 2015 5:53 am

Re: Using Stepper motors to lift a model bridge

Post by roadshark »

Have now got two home switches. When I run this code the motors do not stop until both switches have been activated. This would cause a problem because if motor LH arrived at homeswitchLH 1st it would keep rotating until turned off by homeswitchrh which would demolish or damage the switch!
On the other side after both switches have been activated the steppers actually stop when they should reverse and continue until the switch is open.

Code: Select all

 // Start Homing procedure of Stepper Motor at startup
  while (digitalRead(home_switchLH) || digitalRead(home_switchRH))
  { // Move motors towards home until both switches are activated
    if (digitalRead(home_switchLH))
      stepperLH.moveTo(initial_homing);// homing switch on this motor should stop both motors
    if (digitalRead(home_switchRH))
      stepperRH.moveTo(initial_homing);// Set the position to move to
    initial_homing--;  // Decrease by 1 for next move if needed
    stepperLH.run();  // Start moving the steppers
    stepperRH.run();
  }
The switches have been activated and now the motors should reverse until the switch is open again,

Code: Select all

while (!digitalRead(home_switchLH) || !digitalRead(home_switchRH))
  { // Move motors away from home until both switches are deactivated
    if (digitalRead(home_switchLH))
      stepperLH.moveTo(initial_homing);// homing switch on this motor should stop both motors
    if (digitalRead(home_switchRH))
      stepperRH.moveTo(initial_homing);// Set the position to move to
    initial_homing++;  // increase by 1 for next move if needed
    stepperLH.run();  // Start moving the steppers
    stepperRH.run();
 }
I like your idea of not powering the motors whilst the deck is at the bottom or at the top. I have put the sleep on a pin and will pull it LOW when the bridge is in either of those two positions. When I push the bridgeDeckUp button I would like to make sure the bridge is at the 0 position. How do I get the position checked? So code would start If (digitalRead(bridgeDeckUp)|| (Need to make sure stepperLH & stepperRH ==0)
{
//Turn on the motors
digitalWrite (30, HIGH);// Enables the sleep pin on the MP6500/stepperLH
digitalWrite (32, HIGH);// Enables the sleep pin on the MP6500/stepperRH
stepperLH.setMaxSpeed(100.0);
stepperLH.setAcceleration(50.0);
stepperLH.moveTo(400);//The height the deck moves to.
stepperLH.run();
stepperRH.setMaxSpeed(100.0);
stepperRH.setAcceleration(50.0);
stepperRH.moveTo(400);//The height the deck moves to.
stepperRH.run();
Is the moveTo a blocking code? So it will not turn the motors off until each Stepper is at position 400?
//Turn off motors
digitalWrite (30, LOW);// Disables the sleep pin on the MP6500/stepperLH
digitalWrite (32, LOW);// Disables the sleep pin on the MP6500/stepperRH

User avatar
roadshark
 
Posts: 652
Joined: Sun Nov 29, 2015 5:53 am

Re: Using Stepper motors to lift a model bridge

Post by roadshark »

I had a go.... So when I push the button to lift the deck

Code: Select all

void loop() {
  If (!digitalRead(bridgeDeckUp) || stepperLH(currentPosition == 0))
  {
    digitalWrite (30, HIGH);// Enables the sleep pin on the MP6500/stepperLH
    digitalWrite (32, HIGH);// Enables the sleep pin on the MP6500/stepperRH

    stepperLH.setMaxSpeed(100.0);
    stepperLH.setAcceleration(50.0);
    stepperLH.moveTo(400);
    stepperLH.run();
    stepperRH.setMaxSpeed(100.0);
    stepperRH.setAcceleration(50.0);
    stepperRH.moveTo(400);
    stepperRH.run();
    //Bridge deck at top so turn off motors.
    digitalWrite (30, LOW);// Enables the sleep pin on the MP6500/stepperLH
    digitalWrite (32, LOW);// Enables the sleep pin on the MP6500/stepperRH
  }

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”