SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
#200119
Hello,

I am new to electronics and I am currently working on configuring a rig that has a platform travelling along the Y axis. I am using buttons to control the travel.

Here is my hardware:

Nema 17 17HS19-1684S stepper http://www.osmtec.com/nema_17_step_motor_17_hs.htm
Arduino UNO Rev3
Big Easy Driver http://www.hobbytronics.co.uk/big-easy-stepper-driver
DC Power supply HY3003D set to 8V and it draws approx 1A while running the motor.

I am also using parts from other old rigs I didn't build, like a remote control with 10 buttons. For my program, I am trying to use one button (red, pin 2) to stop the stepper, one button (green, pin 3) to make the platform travel up and down until the stop button is pressed, one button (yellow, pin 4) to go down while the button is pressed and one button (orange, pin 5) to move down while the button is pressed.

I got the basic code working from Easy Driver examples patched together (http://www.schmalzhaus.com/EasyDriver/E ... mples.html).

Please see code below.
Code: Select all
//from example 1.7 Easy Driver examples
int RPMS=500; //rotations per minute, should be just RPM
int STEPS_PER_REV=200; //what your motor is rated as
int MICROSTEPS_PER_STEP=16; //how the driver drives it, Big Easy Driver default is 1/16
int MICROSECS_PER_MICROSTEP= (1000000/(STEPS_PER_REV*MICROSTEPS_PER_STEP)/(RPMS/60));

unsigned int LastStepTime=0; //changed from uint32_t because only Due does unsigned integer 32 bits standard size across all platforms?
unsigned long CurrentTime=0; //a tutorial says to always use unsigned long, not int, for timers

int DISTANCE=6000; //how much I want stepper to move 
int REFERENCE=0; //reference for going up and down

int StepCounter = 0;
int Stepping = false; //when program starts, the stepper is not moving


//defining pins on Arduino
const int red=2; //stop
const int green=3; //up and down
const int yellow=4; //down
const int orange=5; //up
const int DIRECTION=8;
const int STEP=9;

/*#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER, STEP, DIRECTION); //for Big Easy Driver*/

void setup() {
  pinMode(DIRECTION, OUTPUT);
  pinMode(STEP, OUTPUT);
  digitalWrite(DIRECTION, HIGH);
  digitalWrite(STEP, LOW);

  pinMode(red, INPUT);//stop
  pinMode(green, INPUT);//up and down
  pinMode(yellow,INPUT);//down
  pinMode(orange,INPUT);//up

  /*stepper.setMaxSpeed(3000);
  stepper.setSpeed(500);
  stepper.setAcceleration(1000); //for example 5 from Easy Driver examples */
}

void loop() {
  if (digitalRead(green)==LOW&&Stepping==false) //if green button is pressed and the stepper's not moving
  {  Stepping=true;} //make the stepper move

//FOR PRESSING GREEN
 if (Stepping==true) //tells the stepper how to move
   
   /*//For using AccelStepper, pressing button only works once, osicllating doesn't
 {if (stepper.distanceToGo() == 0)
      stepper.moveTo(4000); //because it reaches the position? add increment somehow?

    stepper.run();
  }*/ 
   {  
      CurrentTime=micros();
      if ((CurrentTime - LastStepTime) > MICROSECS_PER_MICROSTEP) //what does this do?
        {
        LastStepTime=CurrentTime;
        digitalWrite(STEP,HIGH);
        delayMicroseconds ((MICROSECS_PER_MICROSTEP*1.8)/2); //I think 0.9 is deg per step, so changed to 1.8 for this stepper
        digitalWrite(STEP,LOW);
        delayMicroseconds ((MICROSECS_PER_MICROSTEP*1.8)/2);
        REFERENCE=REFERENCE+1;
        Stepping=true;

        if(REFERENCE==DISTANCE)
          {
            if (digitalRead(DIRECTION)==LOW)
            {digitalWrite(DIRECTION,HIGH);}
          
            else
            {digitalWrite(DIRECTION,LOW);}
            REFERENCE=0;
            delay(1000);
         }
      }
     }

  if(digitalRead(red)==LOW&&Stepping==true) //pressing the red button makes the stepper stop, but only if it's not pressed while stepper is delayed
      {Stepping=false;
      digitalWrite(DIRECTION,LOW);
      REFERENCE=0; //resets the travel
      }


  if (digitalRead(yellow)==LOW)
  {
    CurrentTime=micros();
    if ((CurrentTime - LastStepTime) > MICROSECS_PER_MICROSTEP)
    {
      LastStepTime=CurrentTime;
      digitalWrite(DIRECTION,LOW); //makes it go down
      digitalWrite(STEP,HIGH);
      delayMicroseconds ((MICROSECS_PER_MICROSTEP*0.9)/2); //have yet to find what the 0.9 multiplier is
      digitalWrite(STEP,LOW);
      delayMicroseconds ((MICROSECS_PER_MICROSTEP*0.9)/2);
    }
    //digitalWrite(DIRECTION,LOW); 
    }

   
  if (digitalRead(orange)==LOW)
  {
    CurrentTime=micros();
    if ((CurrentTime - LastStepTime) > MICROSECS_PER_MICROSTEP)
    {
      LastStepTime=CurrentTime;
      digitalWrite(DIRECTION,HIGH); //makes it go up
      digitalWrite(STEP,HIGH);
      delayMicroseconds ((MICROSECS_PER_MICROSTEP*0.9)/2);
      digitalWrite(STEP,LOW);
      delayMicroseconds ((MICROSECS_PER_MICROSTEP*0.9)/2);
    /*//Tried to use AccelStepper to move, problem
        //stepper.runToNewPosition(DISTANCE);
        stepper.runToNewPosition(-DISTANCE); //this only runs it once after the program is started
        //because it is at that position already I think*/
    }
    digitalWrite(DIRECTION,LOW); //to reset the direction to go down after button is released, seems to only need it after the 'down' is pressed
    }
  }

I have commented out the AccelStepper in the above example, and this works and lets me do what I want for now. However, I would like to change to using AccelStepper to be able to ramp hold. Even the most basic sections I am trying do not work as I would like them to. I realise it's a coding issue, because right now I am telling it to move to a certain position on pressing green, then it reaches it, then when I press it again I should re-initialise it but I don't really know how. I would like it to oscillate until I press the red button.

Please see code below.
Code: Select all
//from example 1.7 Easy Driver examples
int RPMS=500; //rotations per minute, should be just RPM
int STEPS_PER_REV=200; //what your motor is rated as
int MICROSTEPS_PER_STEP=16; //how the driver drives it, Big Easy Driver default is 1/16
int MICROSECS_PER_MICROSTEP= (1000000/(STEPS_PER_REV*MICROSTEPS_PER_STEP)/(RPMS/60));

unsigned int LastStepTime=0; //changed from uint32_t because only Due does unsigned integer 32 bits standard size across all platforms?
unsigned long CurrentTime=0; //a tutorial says to always use unsigned long, not int, for timers

int DISTANCE=6000; //how much I want stepper to move 
int REFERENCE=0; //reference for going up and down

int StepCounter = 0;
int Stepping = false; //when program starts, the stepper is not moving


//defining pins on Arduino
const int red=2; //stop
const int green=3; //up and down
const int yellow=4; //down
const int orange=5; //up
const int DIRECTION=8;
const int STEP=9;

#include <AccelStepper.h>
AccelStepper stepper(AccelStepper::DRIVER, STEP, DIRECTION); //for Big Easy Driver

void setup() {
  pinMode(DIRECTION, OUTPUT);
  pinMode(STEP, OUTPUT);
  digitalWrite(DIRECTION, HIGH);
  digitalWrite(STEP, LOW);

  pinMode(red, INPUT);//stop
  pinMode(green, INPUT);//up and down
  pinMode(yellow,INPUT);//down
  pinMode(orange,INPUT);//up

  stepper.setMaxSpeed(3000);
  stepper.setSpeed(500);
  stepper.setAcceleration(1000); //for example 5 from Easy Driver examples 
}

void loop() {
  if (digitalRead(green)==LOW&&Stepping==false) //if green button is pressed and the stepper's not moving
  {  Stepping=true;} //make the stepper move

//FOR PRESSING GREEN
 if (Stepping==true) //tells the stepper how to move
   
   //For using AccelStepper, pressing button only works once, osicllating doesn't
 {if (stepper.distanceToGo() == 0)
      stepper.moveTo(4000); //because it reaches the position? add increment somehow?

    stepper.run(); //am I supposed to use a while stepping is true?
  } 
   /*
     //code that works{  
      CurrentTime=micros();
      if ((CurrentTime - LastStepTime) > MICROSECS_PER_MICROSTEP) //what does this do?
        {
        LastStepTime=CurrentTime;
        digitalWrite(STEP,HIGH);
        delayMicroseconds ((MICROSECS_PER_MICROSTEP*1.8)/2); //I think 0.9 is deg per step, so changed to 1.8 for this stepper
        digitalWrite(STEP,LOW);
        delayMicroseconds ((MICROSECS_PER_MICROSTEP*1.8)/2);
        REFERENCE=REFERENCE+1;
        Stepping=true;

        if(REFERENCE==DISTANCE)
          {
            if (digitalRead(DIRECTION)==LOW)
            {digitalWrite(DIRECTION,HIGH);}
          
            else
            {digitalWrite(DIRECTION,LOW);}
            REFERENCE=0;
            delay(1000);
         }
      }
     }*/

  if(digitalRead(red)==LOW&&Stepping==true) //pressing the red button makes the stepper stop, but only if it's not pressed while stepper is delayed
      {Stepping=false;
      digitalWrite(DIRECTION,LOW);
      REFERENCE=0; //resets the travel
      }


  if (digitalRead(yellow)==LOW)
  {
    CurrentTime=micros();
    if ((CurrentTime - LastStepTime) > MICROSECS_PER_MICROSTEP)
    {
      LastStepTime=CurrentTime;
      digitalWrite(DIRECTION,LOW); //makes it go down
      digitalWrite(STEP,HIGH);
      delayMicroseconds ((MICROSECS_PER_MICROSTEP*0.9)/2); //have yet to find what the 0.9 multiplier is
      digitalWrite(STEP,LOW);
      delayMicroseconds ((MICROSECS_PER_MICROSTEP*0.9)/2);
    }
    //digitalWrite(DIRECTION,LOW); 
    }

   
  if (digitalRead(orange)==LOW)
  {
    CurrentTime=micros();
    if ((CurrentTime - LastStepTime) > MICROSECS_PER_MICROSTEP)
    {
      LastStepTime=CurrentTime;
      digitalWrite(DIRECTION,HIGH); //makes it go up
      digitalWrite(STEP,HIGH);
      delayMicroseconds ((MICROSECS_PER_MICROSTEP*0.9)/2);
      digitalWrite(STEP,LOW);
      delayMicroseconds ((MICROSECS_PER_MICROSTEP*0.9)/2);
    /*//Tried to use AccelStepper to move, problem
        //stepper.runToNewPosition(DISTANCE);
        stepper.runToNewPosition(-DISTANCE); //this only runs it once after the program is started
        //because it is at that position already I think*/
    }
    digitalWrite(DIRECTION,LOW); //to reset the direction to go down after button is released, seems to only need it after the 'down' is pressed
    }
  }

To be more clear, I want my platform to move up while I hold a button, down when I hold another button. I want it to oscillate on the press of another button until I stop it by pressing another (alternatively on a second press, to stop it from oscillating). Four buttons in total. I always want it to move downwards first when the green is being pressed, and to start the movement from scratch.

On the final rig, I want it all automatically timed, so I can tell it to oscillate by travelling a certain distance up and down for a fixed amount of time. I also want it to run 2 steppers on each side of the platform with exactly the same settings for symmetry, so a group command would be helpful. Including a switch will be how I am planning to initialise the platform (so I can tell it to go down till it hits the switch, then run the oscillating part), but I am clearly out of my depth here.


Best regards,
A.