Go Down

Topic: (Solved) accelstepper code for stepper with constant speed in 2 directions (Read 27149 times) previous topic - next topic

backbone

I had to take two steps back in my project.
Combining various actions led to misbehaviour.

So I first have to get all parts seperate to work before trying to combine them.

Now this one is very basic and is using the accelstepper.h lib.
I found as new bie the explanations and samples not satisfactionary and web searches for something simpel to understand I could not found.

So lets start with this basic.
run a stepper motor with 2 button control in 2 directions.

The reason for the ON/OFF function in either direction is that I need to use the stepper motor as a regular DC motor.
No need to count steps just power and rotate as long as the function tells it to do.
To know the EXACT position I will be using an encoder disk.

In the sample code:
Button one starts the stepper motor CW
Next press on the same button stops the motor.

Button two starts the stepper motor CCW
Next press on the same button stops the motor.

How can I get the motor to run CW or CCW?
I looked the .h classes and find DIRECTION mentioned but no sample how to add it.
http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html

Current code like this.

Code: [Select]

// Push On - Push Off sketch to move stepper motor in clockwise CW or counter clokcwise CCW direction.
// motor keeps turning as long as the flag1 or flag2 is high

#include <AccelStepper.h>
AccelStepper stepper(4,4,5,6,7); //bipolair stepper 4 wire on pin 4,5,6,7

boolean buttonstateUp = 0;
boolean buttonstateDown = 0;
boolean LeftTurn = 0;
boolean RightTurn = 0;
boolean flag1 = 0;
boolean flag2 = 0;


int Analog2 = 16; // Use analog port on shield for push button to control movement and direction
int Analog3 = 17; // Use analog port on shield for push button to control movement and direction

void setup()
{    
 stepper.setMaxSpeed(1000);
 stepper.setSpeed(300);
}
void loop()
{    

 LeftTurn = digitalRead(Analog3);
 RightTurn = digitalRead(Analog2);

 buttonstateUp = LeftTurn;
 buttonstateDown = RightTurn;

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

 if (buttonstateUp == 1)
 {
   flag1 = 1;
 }

 if (buttonstateUp == 1 & flag1 ==1)
 {
   flag1 = 0;
 }

 while (flag1 == 1)
 {
   stepper.runSpeed();  //run motor clockwise CW
 }

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

 if (buttonstateDown == 1)
 {
   flag2 = 1;
 }

 if (buttonstateDown == 1 & flag1 ==1)
 {
   flag2 = 0;
 }

 while (flag2 == 1)
 {
   stepper.runSpeed(); //run motor counter clockwise  CCW
 }
}
Never to old to learn and I learn every day

raschemmel

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

backbone

1] Question was imbedded......How can I get the motor to run CW or CCW?
So how to change direction using this lib at constant speed..

2] Above code start by the button press and motor runs in one direction, but second button push does not stop the motor.

Thanks, Paco
Never to old to learn and I learn every day

raschemmel

If you are using the AccelStepper library did you ever look at the code in the only example in the library ?
Code: [Select]
//This is an example of how you would control 1 stepper

#include <AccelStepper.h>

int motorSpeed = 9600; //maximum steps per second (about 3rps / at 16 microsteps)
int motorAccel = 80000; //steps/second/second to accelerate

int motorDirPin = 2; //digital pin 2     < ===THIS IS A DIRECTION PIN
int motorStepPin = 3; //digital pin 3

//set up the accelStepper intance
//the "1" tells it we are using a driver
AccelStepper stepper(1, motorStepPin, motorDirPin);



void setup(){
 stepper.setMaxSpeed(motorSpeed);
 stepper.setSpeed(motorSpeed);
 stepper.setAcceleration(motorAccel);
 
 stepper.moveTo(32000); //move 32000 steps (should be 10 rev)
}

void loop(){
 
 //if stepper is at desired location
 if (stepper.distanceToGo() == 0){
   //go the other way the same amount of steps  <= "go the other way" sounds like a direction change to me.
   //so if current position is 400 steps out, go position -400
   stepper.moveTo(-stepper.currentPosition());   <= THAT LOOKS LIKE A "-"SIGN IN FRONT OF THE  "stepper.currentPosition()"
 }
 

 
 //these must be called as often as possible to ensure smooth operation
 //any delay will cause jerky motion
 stepper.run();
}  
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

backbone

I looked at all the sample codes in the lib. that are in the top bar.
http://www.airspayce.com/mikem/arduino/AccelStepper/examples.html
There are many samples havent fond the one you describe.
Or do I mis something?

I opted for the constant speed sample as I need to use the steppermotor as an regular DC motor.
I know that sounds opposite for what a stepper is used for. :-)
The stepper steps are not accurate in my application so my steps are counted by an encoder disk.
Should I call stepper.move (10000000)  and run.steppr so it keeps moving indefenetly (almost) untill I tell the motor to stop and then tell the motor to call stepper.move(-10000000) and run.stepper so it keeps moving indefenetly (almost) untill I tell the motor to stop?

BTW I found out the buttons need a debounce but that is an other issue I have to tackle.
Never to old to learn and I learn every day

raschemmel

#5
May 24, 2014, 04:08 pm Last Edit: May 24, 2014, 06:39 pm by raschemmel Reason: 1
Attached is the only AccelStepper Library I am aware of. I don't know why you couldn't find the example I posted. It is the only example in the library. Do you know where the Library is (the folder?) Did you look in that folder ? Did you try "File\Examples\Accelstepper\one_stepper_example" ?



Quote
In the sample code:
Button one starts the stepper motor CW
Next press on the same button stops the motor.

Button two starts the stepper motor CCW
Next press on the same button stops the motor.

How can I get the motor to run CW or CCW?  



I haven't received my stepper motor driver yet so I can't test it but I think you need to have code that executes a command statement based on which button is pressed. With a dc motor driver it would be a simple matter of reversing the direction bits but with a stepper you need some way to control the number of steps used in the command. I haven't done any stepper motor coding yet so all I can do to help you is to recommend that you google "arduino AccelStepper direction control"
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

backbone

OK,

Got it sorted out and to be honest the solution was easy as always.
You have to look through it. :-)

I used your sample and reworked it.

Here is the code that uses serialmonitor to send the button presses as this makes the button debounce for debugging obsolete. I hope someone can use it in the future as reference.
I used it with a L298 stepper board so AccelStepper stepper uses more and different pins as an Easy Driver board.

Thanks for the assistance and the pointers.

Code: [Select]
//This is an example of how you would control 1 stepper with constant speed and direction
// to be used if stepper need to act as DC motor and the steps to be taken are irrelevant

#include <AccelStepper.h>

int motorSpeed = 1000;
int motorAccel = 800;
int LeftTurnUp = 0;
int RightTurnDown = 0;
int incomingByte = 0;   // for incoming serial data
int enablePin10 = 10;  // switch off coils when not in use

AccelStepper stepper(4,4,5,6,7); // set up the stepper as 4 wire bipolair on pin 4,5,6,7

void setup()
{
  Serial.begin(9600);
 
  stepper.setMaxSpeed(motorSpeed);
  stepper.setSpeed(motorSpeed);
  stepper.setAcceleration(motorAccel);
 
  pinMode(enablePin10, INPUT);

}

void loop()
{

  if (Serial.available() > 0)
  {
    incomingByte = Serial.read();
    {
      if (incomingByte == '1')
      {
        digitalWrite(enablePin10, HIGH);
        LeftTurnUp = 1;
        RightTurnDown = 0;
      }
     
      if (incomingByte == '2')
      {
        digitalWrite(enablePin10, HIGH);
        RightTurnDown = 1;
        LeftTurnUp = 0;
      }

      if (incomingByte == '3')
      {
        LeftTurnUp = 0;
        RightTurnDown = 0;
        stepper.moveTo(0);
        digitalWrite(enablePin10, LOW);
      }
    }
  }

  if (LeftTurnUp == 1)  //left turn
  {
    stepper.moveTo(1000000); //move many steps - more then mechanical needed
  }

  if (RightTurnDown == 1)  //right turn
  {
    stepper.moveTo(-1000000); //move many steps - more then mechanical needed
  }

  stepper.run();


Never to old to learn and I learn every day

raschemmel

Your welcome. Thanks for the code. I'll try it when I get my driver in the next few days.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

morelg

Dear backbone,
I am trying to work a somehow similar project as yours but I am facing difficulties and it would be great if you could help with an advice.  I am trying to operate a valve driven by a small stepper using Uno and EasyDrive board. At the closed position the valve hits a limit switch. I am using a another switch to tell the valve to open (.i.e. motor CW)   or close (i.e. motor CCW).  I would like to implement the following logic: In case an open command is received the motor should turn 8000 steps to one side. In case a close command is received the motor should turn 8000 steps to the other side (-8000). Then, in case the limit switch is not activated I would like to turn an additional  (-1000) steps. I would like to use AccelStepper library because I plan to operate more than one valve in parallel.
Anyhow the code without the limit switch seems to work fine, but I am not able to make the limit switch to work  see below:
Code: [Select]
void loop ( )  {
  cmdVent = digitalRead (cmdPinVent); //Read the Vent Valve command to OPEN (LOW) or to CLOSE (HIGH)
   if (ventValve1.distanceToGo ( ) == 0) {
    //Check for OPEN command
    if ( cmdVent == LOW && cmdVentOld == HIGH ) {
      ventValve1.move (stepNumber);
      cmdVentOld = cmdVent;
    }
    //Check for CLOSE command
    if ( cmdVent == HIGH && cmdVentOld == LOW) {
     ventValve1.move (-stepNumber);
     cmdVentOld = cmdVent;
      switchVent1=digitalRead (switchPinVent1);
      if (switchVent1 != HIGH) {
      ventValve1.move (-1000);
      }
    }
  }
  ventValve1 .run( );
}


Base on your experience with the AccelStepper library, do you have and advice on how to sort this out?
Thank you,

Morel

Go Up