Coding help for timing steppers

Hi,
I’ve been trying to hash the code out for a machine I’m building and have it almost there but can’t seem to get the timing to work properly, I’ve tried the forums but haven’t been able to get any help so if anyone wants to make some quick money let me know what you think it would cost to help me.

If you want to read the last post on this thread (https://forum.arduino.cc/index.php?topic=518445.msg3605011#msg3605011) it will give you some background on it, RobinS was helping me but he was hung up on the stepper code thinking the problem was there but they run fine without all the timing so I don’t think it is there.

Here is my last attempt but there are 2 problems with it, the first pause(called “pause” in code) while everything moves into place only works intermittently and the the second one called “interval” doesn’t seem to let everything move in equal steps( it does 2 stops then goes longer and then 2 short stops again)

#include <AccelStepper.h>

AccelStepper stapler(AccelStepper::DRIVER, 3, 4);
AccelStepper roserotate(AccelStepper::DRIVER, 12, 13);
AccelStepper gantry(AccelStepper::DRIVER, 5, 6);
AccelStepper carriage(AccelStepper::DRIVER, 7, 11);

//VALUES FOR BUTTON
const int button = 2;            // pin button is on
int val = LOW;                     // current button state
int old_val = LOW;
int buttonstate = LOW;
unsigned long previousMillis;



//VALUES FOR TURNING STAPLER 4 TURNS(using stapler hall Sensor) plus delay the start
int staplercounter = 0;
int staplercurrentState = 0;
int staplerpreviousState = 0;
int staplerSensor = 47;
unsigned long previousMillis3;
const unsigned long pause = 1000;


//VALUE FOR PAUSING ROSETTE TURN
unsigned long previousMillis2;
const unsigned long interval = 250;

//VALUE FOR GANTRY MOVE
int gantrysensor = 46;
int gantryout = 43;
int gantryfinish = 0;
int gantryhome = 0;

//VALUE FOR CARRIAGE MOVE
int carriagesensor = 45;
int carriagetop = 44;
int carriagefinish = 0;
int carriagehome = 0;

void setup() {
  pinMode(button, INPUT_PULLUP);
  pinMode(staplerSensor, INPUT_PULLUP);
  pinMode(gantrysensor, INPUT_PULLUP);
  pinMode(gantryout, INPUT_PULLUP);
  pinMode(carriagesensor, INPUT_PULLUP);
  pinMode(carriagetop, INPUT_PULLUP);


  Serial.begin(9600);

  gantry.setMaxSpeed(10000.0);
  carriage.setMaxSpeed(10000.0);
  stapler.setMaxSpeed(10000.0);
  roserotate.setMaxSpeed(1000);
  previousMillis = millis();
  previousMillis2 = millis();
  previousMillis3 = millis();

}

void loop() {
  starter();
  counter();

  gantryhome = digitalRead(gantrysensor);
  gantryfinish = digitalRead(gantryout);
  carriagehome = digitalRead(carriagesensor);
  carriagefinish = digitalRead(carriagetop);
  staplercurrentState = digitalRead(staplerSensor);   //set state for movement

  if (buttonstate == HIGH && gantryhome == HIGH && staplercounter < 3) {

    gantry.move(50);                                 //move to sensor for stapling
    gantry.setSpeed(1000);
  }


  if (buttonstate == HIGH && carriagehome == HIGH && staplercounter < 3) {

    carriage.move(-50);                         //move to sensor for stapling
    carriage.setSpeed(2000);
  }


  if (buttonstate == HIGH && staplercounter >= 1) {

    if ( (millis() - previousMillis2) >= interval) {
      roserotate.move(50);
      roserotate.setSpeed(800);
      previousMillis2 = millis();

      if (staplercounter >= 3) {
        roserotate.setSpeed(0);
      }
    }
  }

  if ((millis() - previousMillis3) >= pause) {           //short pause for slider & gantry move
    if (buttonstate == HIGH) {
      stapler.setSpeed(-5000);
    }
    previousMillis3 = millis();
  }

  ///////////////////////////////////////////////////////////////////////////////

  if (staplercounter >= 4 && gantryfinish == HIGH) {          //Slide gantry back to start position

    stapler.setSpeed(0);                      //turn motor off

    gantry.moveTo(-50);
    gantry.setSpeed(1000);

    if (staplercounter >= 4 && carriagefinish == HIGH) {          //Slide carriage back to start position

      carriage.moveTo(50);
      carriage.setSpeed(2000);


      buttonstate = LOW;                   //reset button
      staplercounter = 0;                    //reset counter for next button push
      staplercurrentState = 0;               //reset state for next button push
    }
  }
    stapler.runSpeed();
    gantry.runSpeedToPosition();
    carriage.runSpeedToPosition();
    roserotate.runSpeedToPosition();
  }

  void starter() {
    if ( (millis() - previousMillis) >= 50) {    //state machine for button & debounce
      val = digitalRead(button);
      if ((val == LOW) && (old_val == HIGH)) {
        buttonstate = HIGH;
      }
      previousMillis = millis();
      old_val = val;
      //Serial.println(buttonstate);
    }
  }
  void counter() {
    staplercurrentState = digitalRead(staplerSensor);     //used to time all events
    if (staplercurrentState != staplerpreviousState) {    //check the count and add 1
      if (staplercurrentState == 1) {
        staplercounter = staplercounter + 1;
         Serial.println(staplercounter);
      }
    }
    staplerpreviousState = staplercurrentState;
  }

Not sure how to upload a video of it working but I have one and can supply if you need it.
Thanks for any help.

There are FIVE PAGES of posts in that thread. If you want some help, why don't you give a short one-paragraph summary of what you're trying to do. Ignore any code anyone's written. Just say "I need to do X..."
Simply reading the last post is not useful in any way.

cedarlakeinstruments:
There are FIVE PAGES of posts in that thread. If you want some help, why don't you give a short one-paragraph summary of what you're trying to do. Ignore any code anyone's written. Just say "I need to do X..."
Simply reading the last post is not useful in any way.

I need it to operate like this,

Push button to start everything
Gantry and carriage to move into position
Stapler to start rotating( variable set of rotations depending on what I need)
roserotate to rotate set distance( will be variable) each time the stapler makes a rotation
Once stapler has made required rotations it will stop and gantry and carriage will move back to start position
reset all counters and wait for next button push to start movement

Like I said I can get the steppers to move with no problem but I'm trying to get them all to arrive and start working at the same time to make the amount of time to do 1 of the above sequence as fast as possible.
The last post on the mentioned thread speaks to what I'm trying to achieve.

Are you saying that you have no problem synchronizing the stapler and roserotate (whatever that is), but you need the motions at start and end of sequence to occur as fast as possible?

If so, you basically need to start them at the same time and do all the updates (if using AccelStepper) until they are all complete. The time to do a sequence is determined by the time of the slowest motion. The only real complexity arises if the motors have to run at different speeds.
e.g.,

AccelStepper m1, m2, m3;
m1.moveTo(100);
m2.moveTo(-250);
m3.moveTo(76);

bool m1Done, m2Done, m3Done = false; // etc...
while (!(m1.Done && m2.Done && m3.Done))
{
  m1.run();
  m2.run();
  m3.run();
  m1Done = !m1.isRunning();
  m2Done = !m2.isRunning();
  m3Done = !m3.isRunning();

}
delay(inertiaDelay);

Of course, if I misunderstood what the problem is, then ignore everything I said :slight_smile:

cedarlakeinstruments:
Are you saying that you have no problem synchronizing the stapler and roserotate (whatever that is), but you need the motions at start and end of sequence to occur as fast as possible?

If so, you basically need to start them at the same time and do all the updates (if using AccelStepper) until they are all complete. The time to do a sequence is determined by the time of the slowest motion. The only real complexity arises if the motors have to run at different speeds.

Of course, if I misunderstood what the problem is, then ignore everything I said :slight_smile:

LOL,
I start everything at once but before the gantry and carriage can get into place the stapler stepper hits the bottom of its travel, I have the gantry and carriage steppers running as fast as I can get them to run and can't slow down the stapler stepper or it doesn't operate properly.

I originally had the stapler stepper wait until the other 2(gantry/carriage)steppers were in place but thought if I could shave off some of the wait time by starting the stapler stepper sooner I would save quite a bit of time over the length of a days work. I tried to do it with a millis() delay but it works sometimes but not always and don't know why that is.

The roserotate stepper just turns whatever substrate I have loaded so the stapler stepper will staple in a circular pattern, I tried to make the roserotate stepper move when the hall sensor counter attached to the stapler stepper would change the count but couldn't manage to do that either so I went with the mills() delay there also and it kinda does it but not very well with an unbalanced pattern of staples.

I do have the steppers running at different speeds and they move OK but would love to get more speed out of the gantry and carriage steppers but I'm at the limit of my knowledge so getting them to run in perfect timing would be a win for me. The move out for the gantry and carriage is no big deal, just run as fast as I can to hall sensors and stop which my original code does at the top of the thread.

OK, it sounds like if you could either get the stepper up to speed faster OR start the stepper and get the gantry to move faster that would work, is that right?
If so, what speed is the gantry moving at now (steps/second)? What happens if you try to move it faster than that?

cedarlakeinstruments:
OK, it sounds like if you could either get the stepper up to speed faster OR start the stepper and get the gantry to move faster that would work, is that right?
If so, what speed is the gantry moving at now (steps/second)? What happens if you try to move it faster than that?

Per the code in my first post I have the speed at 1000, if I go any higher the motor just stalls and doesn't move. I have a nema23 100 Oz in. with a DIV268N-5A(cheap Chinese driver) using full steps with a 36V 9.7A power supply. I'm sure a new stepper would work better, I had this laying around so I used it.

I changed the Arduino from a Mega to a Due and that helped speed the motors up quite a bit with the faster clock speed on the Due but just haven't had any luck with making the motors snap quickly like you see on the internet.

I would still need to resolve the rotating of the roserotate stepper as speed isn't the issue with it.

I don't know anything about the loads attached to it, but at that voltage, a single stepper should be able to move faster than that. How steep is your acceleration ramp?

[edit]
That said, if the motor is running as fast as it can unloaded, then you need to consider gearing up.

In the spirit of cooperative collaboration, this is cedarlakeinstuments' ball to carry. If/when you pass that point, let me know.

cedarlakeinstruments:
I don't know anything about the loads attached to it, but at that voltage, a single stepper should be able to move faster than that. How steep is your acceleration ramp?

[edit]
That said, if the motor is running as fast as it can unloaded, then you need to consider gearing up.

The load is less than a pound, it's a piece of aluminum on linear slides that is moving in and out less than 2" of total movement.

I didn't use an acceleration ramp because it had such a short distance to go it just made it run even slower not being able to get up to speed and decelerate so quickly.

Not sure what you mean by gearing up. I looked into geared steppers awhile ago and ruled it out because the articles I read stated it would make them slower.

I do have a video of the machine in operation but I'm not sure how to upload it to the site so you can see it.

DKWatson:
In the spirit of cooperative collaboration, this is cedarlakeinstuments' ball to carry. If/when you pass that point, let me know.

Thanks, I will.

I uploaded a video to youtube for you to see it operate.
Video Link

Just from a visual perspective that looks slower than I would expect.

  • What's that mechanism I see periodically that's driven by the stepper?
  • Have you tried switching to half steps and doubling the motor speed?
  • I strongly suggest raising the speed and adding a very high acceleration rate. IME, sometimes you have to play with the accel rate to get a smooth motion.

I know you've spent a lot of time working with people on the other thread and I don't want to end up asking the same set of questions they did, but it strikes me that the issue is electromechanical, not software related.

cedarlakeinstruments:
Just from a visual perspective that looks slower than I would expect.

  • What's that mechanism I see periodically that's driven by the stepper?
  • Have you tried switching to half steps and doubling the motor speed?
  • I strongly suggest raising the speed and adding a very high acceleration rate. IME, sometimes you have to play with the accel rate to get a smooth motion.

I know you've spent a lot of time working with people on the other thread and I don't want to end up asking the same set of questions they did, but it strikes me that the issue is electromechanical, not software related.

Not sure what mechanism you refer too, I have a stepper sliding the table in, 1 sliding the stapler down, 1 turning the substrate I add to the table and 1 large stepper(960 oz)turning the stapler(called a wire stitcher) which is what is getting moved up and down in the video.

I haven't tried half steps, I use half steps on the carriage stepper(the one that slides the stapler down & up)because the driver I had for it doesn't do full steps(that motor runs at a speed of 2000 in my code) the stepper is a little larger than the one sliding the table in and out and I'm guessing that's why I can do extra speed with it.

I will try to figure out how to work with the accel rate and see if it changes anything.

I don't mind the questions as it helps me understand what I'm doing better, the other thread Robin2 thought my stepper code was messed up and no matter how many times I said the accelstepper group walked me through it to make it functioning code he just thought it was wrong.
I have never been able to get the motors to run very fast on any project but when I stopped using the mega/Uno for the Due there was a marked improvement in the speed so I think I'm heading in the right direction.

I plated with access rate last night and got a little more speed out of it.

The gantry table stepper I incremented up to these settings before the motor started vibrating and not moving,
set driver to 1/2 steps
setAcceleration(10000)- I didn't see much difference moving from 1000-10000 during testing
setSpeed(2500)

As I'm watching the machine operate the mills() delay that I'm using on the stapler stepper doesn't always work, I have exaggerated the delay to a full second so I can see it operate and I only get it to wait that long intermittently. The delay works maybe 2 out of 10 times, some times I get some type of delay and others the stapler stepper starts immediately which is where the problems start with other things not being in place.

I must not have done the mills() correctly but not sure where I have gone wrong.

What I would do in your situation is isolate everything. Write the shortest piece of code you can that exercises that Z axis up and down about two inches. Get that running as fast as possible in isolation from everything else. Also, what current level do you have set on your stepper drive?

[edit]
Here is a small NEMA 17 motor running smoothly at 5000 steps/sec (half-step mode) with an acceleration of 50000 steps/sec/sec at straight 15V -- no PWM or L/R resistance. At 36 volts, I should be able to get it to run even faster. I can send you this code if you want to use it to test your axis. stepper - YouTube

We just passed the one page mark :slight_smile: Do you want to move this to email and then just make a summary post when it works better? I know this is the "paid help" section, but without your actual hardware, I won't be able to help you at a level where I feel comfortable charging for anything. I just really like doing motion control :slight_smile:

Any progress?