one push stepper motor control

Hi,
I am trying to write a code which will turn a stepper motor (x) number of steps then stop. Push button once again motor turns (x) number of steps.
I am having trouble getting it to run with the buttonstate example from ide,
at the moment the code below only steps 1 step each time the pin is grounded.
I am also tying to use the acclersteeper commands to get it to turn.

Hardware
arduino uno r3
DM556t driver
nema34 stepper motor

Any help is appreciated

#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER, 6, 7);
const byte buttonPin = 5;

boolean buttonState = LOW;
boolean oldbuttonState = LOW;

void setup()
{


  pinMode(buttonPin, INPUT_PULLUP);
  stepper.setMaxSpeed(300);
  stepper.setAcceleration(300);
  Serial.begin(9600);
}

void loop()
{
  buttonState = digitalRead(buttonPin);
  if (oldbuttonState != buttonState)
  {
    if (buttonState == (LOW))
      Serial.println(buttonState);
    stepper.move(6400);
    stepper.run();
  }

  oldbuttonState = buttonState;

}

If you read the documentation for the library, stepper.run() only does one step so you need to call it multiple times to achieve the desired position. Since you have that function inside your if() statement, it only gets called once whenever the button is pressed.

Look at the examples in the AccelStepper library.

Thanks blh64 for your reply
I separated the stepper run () call from the if statement and the stepper is working as it should.
Now the switchstate code seems to be coded incorrectly.
The stepper motor runs to the correct amount of steps when the switch is grounded, but it also runs when the switch is released.

Hey. I’ve been working on a similar project, but i’m about 2 months into it now and have it somewhat figured out. There’s multiple ways to write this code, but it depends on what you wanting to do in the long run. But i think the easiest way would be something similar to this below. I changed your code a bit, but it should upload and work normally. But you really need to study this page. https://forum.arduino.cc/index.php?topic=261445.0

but one thing about this code below. you can hold down the button and it will activate whenever the stepper reaches it’s step target and keep stepping. which isn’t a problem when stepping longer distances. but if you only step short distances at higher speeds, there needs to be a delay to keep the button from prematurely activating

#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER, 6, 7);
const byte buttonPin = 5;

byte button1State;   // waiting for a change

void setup(){

  pinMode(buttonPin, INPUT_PULLUP);
  stepper.setMaxSpeed(300);
  stepper.setAcceleration(300);  
  Serial.begin(9600);
}

void loop(){   // loops between these two actions

  checkButton ();   // monitors and waits for button press
  actionOne ();     // only runs when button is pressed to low

}

void checkButton() {

  button1State = digitalRead(buttonPin);
  
}

void actionOne() {
  
  if (button1State==LOW){
    
  
    Serial.println("Stepper Moving");
    stepper.move(6400);  // or whatever action you want the stepper to do
    
  }

}

Here is a tested demo sketch to do what you want. Note pin assignments and changes to suit my setup.

#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER, 2, 5);
const byte buttonPin = 9;  // change to suit my setup
const byte stepperEnablePin = 8;  // need the enable pin

boolean buttonState = LOW;
boolean oldbuttonState = LOW;
boolean stepperMoving = false;

long stepsToMove = 1600;

void setup()
{
   pinMode(buttonPin, INPUT_PULLUP);
   pinMode(stepperEnablePin, OUTPUT);
   digitalWrite(stepperEnablePin, LOW);
   stepper.setMaxSpeed(1000);
   stepper.setAcceleration(300);
   Serial.begin(9600);
}

void loop()
{
   buttonState = digitalRead(buttonPin);
   if (oldbuttonState != buttonState)
   {
      if (buttonState == (LOW) && stepperMoving == false)
      {
         Serial.println(buttonState);
         stepper.move(stepsToMove);
         stepperMoving = true;
      }
      //stepper.run();
      oldbuttonState = buttonState;
   }
   if (stepper.run() == true)  // run returns true while moving.
   {
      stepperMoving = true;
   }
   else  // at position, stopped, run returns false
   {
      stepperMoving = false;
   }
}

wildcat99s, there will be no stepper movement unless one of the run() functions is called regularly.

Yeah. i forgot that. so perhaps it wasn't an upload and work perfectly.. but the main point was the case switch code and a different kind of loop... that's why there was a note at the very bottom saying to do whatever you want in this section.

Thanks for the replies
Need to get back home and try these out
Has been very frustrating trying to get this to work
Hopefully can move to the next step now

Thanks to everyone’s help this morning i have been able to complete my sketch for the welding half of my project.

I am building a rotary welder, which has 1 stepper motor to turn a shaft and another stepper motor moves the welding tip across as each revolution is completed.

The code attached works correctly but it is running very slowly. Especially the last to commands where the jog buttons are used to re position the tip.

If i run just this code by itself it works correctly and i can adjust the setspeed to whatever i want.

From some googling the analogue read maybe slowing the code or the mathematic equation, or more than likely my code,{ curly braces} .

looking forward to the full code
IS an arduino able to run 2 stepper motor (max speed 60 rpm) with 2 analogue reads and able to update a LCD of the stepper speeds

#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER, 6, 7);
const byte buttonPin = 5;

boolean buttonState = LOW;
boolean oldbuttonState = LOW;
boolean stepperMoving = false;
int stepValue = 0;
int potPin = A0;
#define  WELDLEFT_PIN               11
#define  WELDSTOP_PIN               12
#define  WELDRIGHT_PIN              10
#define JOG_LH_PIN                  4
#define JOG_RH_PIN                  3




void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(WELDLEFT_PIN, INPUT_PULLUP);
  pinMode(WELDSTOP_PIN, INPUT_PULLUP);
  pinMode(WELDRIGHT_PIN, INPUT_PULLUP);
  pinMode(JOG_LH_PIN, INPUT_PULLUP);
  pinMode(JOG_RH_PIN, INPUT_PULLUP);
  stepper.setMaxSpeed(2000);
  stepper.setAcceleration(600);
  Serial.begin(9600);
}

void loop()
{

  static int analog_value = 0;
  static char sign = 0;

  if (digitalRead(WELDLEFT_PIN) == 0) {
    sign = -1;
  }
  else if (digitalRead(WELDRIGHT_PIN) == 0) {
    sign = 1;
  }
  else if (digitalRead(WELDSTOP_PIN) == 0) {
    sign = 0;
  }

  stepValue = analogRead(potPin);
  stepValue = map(stepValue, 0, 1023, 200, 400);
  stepValue = (stepValue * sign);
  Serial.println(stepValue);

  {

    buttonState = digitalRead(buttonPin);
    if (oldbuttonState != buttonState)
    {
      if (buttonState == (LOW) && stepperMoving == false)
      {
        stepper.move(stepValue);
        stepperMoving = true;
      }
      //stepper.run();
      oldbuttonState = buttonState;
    }
    if (stepper.run() == true)  // run returns true while moving.
    {
      stepperMoving = true;
    }
    else  // at position, stopped, run returns false
    {
      stepperMoving = false;
      {
        if (digitalRead (JOG_LH_PIN)  ==  LOW && digitalRead(WELDSTOP_PIN)  == (LOW))
        {
          stepper.setSpeed(1000);
        }
        stepper.run();
      }
      {
        if (digitalRead (JOG_RH_PIN)  ==  LOW && digitalRead(WELDSTOP_PIN)  == (LOW))
        {
          stepper.setSpeed(-1000);
        }
        stepper.run();
      }
    }
  }
}

i think here's your problem at the bottom. You have a negative speed.

        if (digitalRead (JOG_RH_PIN)  ==  LOW && digitalRead(WELDSTOP_PIN)  == (LOW))
        {
          stepper.setSpeed(-1000);
        }
        stepper.run();

I need a negative speed there, as this is how I am changing the direction of the stepper.

That was my mistake. I was in a hurry and it didn't look right off hand. but it is.

After looking at your code better on my own screen, i believe the slowness isn’t necessary caused by your analog, but that’s part of it. Your Serial.print(stepValue) is going to slow everything down because your Serial.begin(9600) is low for a refresh rate. try upping it to 115200 and see if that fixes it. I had a similar problem with step counting and the baud rate was limiting the stepper’s speed.

I had another day working on this and have some success but its probably not the right way to fix the problem.
When i load the code the stepper motors run very slow, i was able to over come this by changing the ‘setSpeed and run’ commands to a very short ‘move and run’ call with very high acceleration in setup.

This makes the steppers work at the correct speeds

Now when i add the LCD to the code the speed is very very slow.
i added an if statement to the lcd print and it made a very small change.

I am communicating over i2c to a df robot rgb lcd and using there library.

Any other clues on how to speed this up?
Or do i need an other arduino to do the lcd work?

#include <Wire.h>
#include "DFRobot_LCD.h"
AccelStepper stepper1(AccelStepper::DRIVER, 9, 8);    //Rotation stepper
AccelStepper stepper2(AccelStepper::DRIVER, 6, 7);    // Weld stepper
const byte buttonPin = 5;                             // connected to magnet reed switch to advance weld stepper
boolean buttonState = LOW;                            //switchstate for weld stepper movement
boolean oldbuttonState = LOW;
boolean stepperMoving = false;
int stepValue = 0;
int potPin = A0;                                      //analogue read for weld stepper, changes the amount of steps the motor moves when pin 5 is grounded


DFRobot_LCD lcd(16, 2);                               //dfrobot rgb 16x2 lcd libary

// Define our three input button pins
#define  LEFT_PIN                   1                //rotation buttons
#define  STOP_PIN                   0
#define  RIGHT_PIN                  2
#define  WELDLEFT_PIN               11               //weld buttons
#define  WELDSTOP_PIN               12
#define  WELDRIGHT_PIN              10
#define JOG_LH_PIN                  4                //weld jog buttons
#define JOG_RH_PIN                  3



// Define our analog pot input pin
#define  SPEED_PIN A3                                //rotation stepper speed control

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 500                               //Rotation stepper max ,min speeds
#define  MIN_SPEED 0.1

void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);
  stepper2.setMaxSpeed(2000);
  stepper2.setAcceleration(200000);                   //weld stepper settings. acceleration is so high to get jog buttons to move at high enough speed


  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(WELDLEFT_PIN, INPUT_PULLUP);
  pinMode(WELDSTOP_PIN, INPUT_PULLUP);
  pinMode(WELDRIGHT_PIN, INPUT_PULLUP);
  pinMode(JOG_LH_PIN, INPUT_PULLUP);
  pinMode(JOG_RH_PIN, INPUT_PULLUP);
  lcd.init();
  lcd.setCursor(0, 0);
  lcd.print("SPEED:");
  lcd.setCursor(13, 0);
  lcd.print("RPM");
  lcd.setCursor(0, 1);
  lcd.print("TIP ADV:");
  lcd.setCursor(12, 1);
  lcd.print("  mm");

}

void loop() {
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value1 = 0;             // Holds raw analog value.
  static int analog_value = 0;
  static char sign1 = 0;
  // If a switch is pushed down (low), set the sign value appropriately
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1;
  }
  else if (digitalRead(RIGHT_PIN) == 0) {                                   // Sets direction of rotation stepper
    sign = -1;
  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0;
  }

  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop).
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value1 = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = sign * (((analog_value1 / 1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED);
    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);

    int newReading = current_speed;                                            //Only update rotation stepper speed on LCD when speed changes
    if (newReading != current_speed)
    {
      current_speed = newReading;
      lcd.setCursor(7, 0);
      lcd.print(((current_speed) * (0.0055)), 1);                                 //Calcuates rotation speed


    }

    // This will run the stepper at a constant speed
    stepper1.runSpeed();
    {

    }



    if (digitalRead(WELDLEFT_PIN) == 0) {
      sign1 = -1;
    }
    else if (digitalRead(WELDRIGHT_PIN) == 0) {                                  //Sets direction of weld stepper
      sign1 = 1;
    }
    else if (digitalRead(WELDSTOP_PIN) == 0) {
      sign1 = 0;
    }

    stepValue = analogRead(potPin);
    stepValue = map(stepValue, 0, 1023, 3200, 6400);                           // Reads pot and changes the amount of steps the weld stepper taks
    stepValue = (stepValue * sign1);

    {

      lcd.setCursor(9, 1);
      lcd.print(((stepValue * 0.056) / ( 360) * (3.2 )), 1);                      // Distance in mm that the weld tip moves as result of taking the above steps
    }


    {

      buttonState = digitalRead(buttonPin);
      if (oldbuttonState != buttonState)
      {
        if (buttonState == (LOW) && stepperMoving == false)                    // Weld stepper only moves the amount of steps once per rotation or every time pin 5
                                                                                //is grounded 

        {
          stepper2.move(stepValue);
          stepperMoving = true;
        }
        //stepper2.run();
        oldbuttonState = buttonState;
      }
      if (stepper2.run() == true)  // run returns true while moving.
      {
        stepperMoving = true;
      }
      else  // at position, stopped, run returns false
      {
        stepperMoving = false;
      }
      if (digitalRead (JOG_LH_PIN)  ==  LOW && digitalRead(WELDSTOP_PIN)  == (LOW))       //Used to move the weld tip back to starting position. Initally used
      {
        stepper2.move(-10);                                                                 // setSpeed and run commands but run very very slow. Changed to very
      }
      stepper2.run();                                                                        //short move command and very high accerlation to get it to run
    }
    {
      if (digitalRead (JOG_RH_PIN)  ==  LOW && digitalRead(WELDSTOP_PIN)  == (LOW))
      {
        stepper2.move(10);
      }
      stepper2.run();
    }
  }
}
      sign1 = 1;

Numbers in your variable names is a sign that you need to use an array or you need better names for your variables. Maybe call this one weldDirection?

You already solved the slowness problem here...

  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;

Just do the same thing for the LCD code. But...

  1. analogRead() is not disastrously slow. You can do about 10,000 reads per second on an UNO. Printing to Serial or LCD is usually much much slower, so that is the root of your problem.
  2. This becomes dependent on the loop speed, which is variable. I always use the millis() timer to get a consistent number of analog readings per second and to update the display at a slower rate of only 5-10 times per second.