X-DC motor, Y-Bimba, Z-Stepper motor (behaving badly)

My device is behaving badly. It uses 3 axis of motion. Well, at least someday it will.
It should run a platform along the X axis from “A” the starting point and when reaching “B” the turnaround point it needs to advance a stepper 50 steps and light an LED while reversing direction. I have not inserted the LED bit into this version yet, but have had it working in another which does not have the stepper involved.

I have many questions and fear shotgunning the community with them right away.

So for now, I’ll start with this. The following code somewhat behaves, but poorly. When my platform reaches position “B” and my proximity switch goes high the platform somehow speeds (more quickly) in the same direction until the Z stepper completes its action. Only then does it reverse direction. What is causing the described behavior? Is it unrealistic to expect this much action from the “B” proximity Pin?
1 turn X motor around
2 advance the counter
3 turn on led

-The motor for the X axis is DC.
-The motor for the Z axis is a small stepper for now but will be a larger one with a controller later.
-The Y axis is an on/off pneumatic Bimba. The LED is its mock stand-in.
-I’m using an UNO.

This is my first project. I began it in February. After many versions this code is getting cluttered and confusing to me. It has leftover bits here and there. It may not look it, but I spent some effort cleaning it up to be more presentable.

This is in regards to an earlier question I asked here.

I am not sure if I should have just continued that thread, but there it is.

Tom

//copy--no bimba here -- LED stand-in
//working Ripp For., Rev. , Counter--Also has stepper dddddddddd>UP
// ledPin on 11 doesnt serve much purpose, it counts to 4 and lights the led
/* Start button is Digital Pin 7, SyRen S1 is connected to Arduino Digital Pin 1 (TX), Proximities are Digital Pins 2 and 3, Pots are Analog Pins 1 and 2 */

#include <SyRenSimplified.h>
#include <AccelStepper.h>
const int StopButton = 7;
const int ForwardButton = 10;   
const int ReverseButton = 9;
const int ForwardSpeedPin = A3;
const int ReverseSpeedPin = A2;

const int  buttonPin = 9;    // the pin that the pushbutton is attached to
const int ledPin = 11;       // the pin that the LED is attached to

int ForwardState = 0;
int ReverseState = 0;
int StopState = 0;
int ForwardSpeed = 0;
int ReverseSpeed = 0;
int CurrentState = 0;  // 0 is stopped, 1 is forward, 2 is reverse

int buttonPushCounter = 0;   // counter for the number of button presses -- COUNTER
int buttonState = 0;         // current state of the button -- COUNTER
int lastButtonState = 0;     // previous state of the button -- COUNTER

SyRenSimplified ST; // Simplified Serial Mode. Baud rate of 9600. Arduino TX->1  ->  Sabertooth S1   Arduino GND    ->  Sabertooth 0V      [ST.motor(1, X);  X of 0 is full reverse, 128 is stop, 255 full forward] <--- WRONG!  -127 full reverse, 0 stop, 127 full forward
// Define a stepper and the pins it will use
AccelStepper stepper; // Defaults to 4 pins on 2, 3, 4, 5
// this constant won't change:
const int  buttonPinCutter = 8;    // the pin that the pushbutton is attached to

// Variables will change:
int buttonPushCounterCutter = 0;   // counter for the number of button presses
int buttonStateCutter = 0;         // current state of the button
int lastButtonStateCutter = 0;     // previous state of the button

void setup(){
  SyRenTXPinSerial.begin(9600); // 9600 is the baud rate
  ST.motor(7, 0);   
  
  ForwardState = digitalRead(ForwardButton);
  ReverseState = digitalRead(ReverseButton);
  ForwardSpeed = analogRead(ForwardSpeedPin);
  ReverseSpeed = analogRead(ReverseSpeedPin);
  ForwardSpeed = map(ForwardSpeed,-1023,0,127,1);
  ReverseSpeed = map(ReverseSpeed,0,1023,-127,-1);
  
    // initialize the button pin as a input:
  pinMode(buttonPinCutter, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
    // initialize serial communication:
  Serial.begin(9600);
  
    // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  
  
  stepper.setMaxSpeed(200.0);
  stepper.setAcceleration(100.0);
  
  // the following variables are long's because the time, measured in miliseconds,
  // will quickly become a bigger number than can be stored in an int.
  long lastDebounceTime = 0;  // the last time the output pin was toggled
  long debounceDelay = 100;    // the debounce time; increase if the output flickers
  
  
  // initialize serial communication:
  Serial.begin(9600);
  }

void loop(){
  ForwardState = digitalRead(ForwardButton);
  ReverseState = digitalRead(ReverseButton);
  StopState = digitalRead(StopButton);
  
  //SET THREE DIFFERENT STATES (FORWARD, REVERSE, STOP)
   if (ForwardState == HIGH) {      //up state  
      CurrentState = 1; 
   }
   
  if (ReverseState == HIGH) {    // down state
      CurrentState = 2;
  }
   
  if (StopState == LOW){
      CurrentState = 0;
      ST.motor(11, 0);
   }
  //FINISHED WITH "SET THREE DIFFERENT STATES (FORWARD, REVERSE, STOP)"
  
  
if (CurrentState == 0){
   ST.motor(1, 0);
   delay(2000);
  }

if (CurrentState == 1){  //Forward
   ST.motor(1,ForwardSpeed);
   ForwardSpeed = analogRead(ForwardSpeedPin);
   ForwardSpeed = map(ForwardSpeed,0,1023,-1,-127);
   }

if (CurrentState == 2){  //Reverse
   ST.motor(1, ReverseSpeed);
   ReverseSpeed = analogRead(ReverseSpeedPin);
   ReverseSpeed = map(ReverseSpeed,0,1023,1,127); 
 } 
 
   // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin); //-- COUNTER

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {  // if the state has changed, increment the counter -- COUNTER
    if (buttonState == HIGH) {           // if the current state is HIGH then the button -- COUNTER
                                         // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    }
    else {
                                         // if the current state is LOW then the button
                                         // wend from on to off:
      Serial.println("off");
    }
                                         // Delay a little bit to avoid bouncing
    delay(10);
  }
                                         // save the current state as the last state,
                                         //for next time through the loop
  lastButtonState = buttonState;


                                         // turns on the LED every four button pushes by
                                         // checking the modulo of the button push counter.
                                         // the modulo function gives you the remainder of
                                         // the division of two numbers:
  if (buttonPushCounter % 4 == 0)
  {
    digitalWrite(ledPin, HIGH);
  } 
  else
  {
    digitalWrite(ledPin, LOW);
  }
 // read the pushbutton input pin:
  buttonStateCutter = digitalRead(buttonPinCutter);

  // compare the buttonState to its previous state
  if (buttonStateCutter != lastButtonStateCutter) 
  {
    // if the state has changed, increment the counter
    if (buttonStateCutter == HIGH) 
    {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounterCutter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounterCutter);
    } 
    else 
         {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
         }
  }
  // save the current state as the last state, 
  //for next time through the loop
  //lastButtonStateCutter = buttonStateCutter;
  {
if (buttonPushCounter == 1) {stepper.runToNewPosition( 50);}
if (buttonPushCounter == 2 ){stepper.runToNewPosition(100);}
if (buttonPushCounter == 3) {stepper.runToNewPosition(150);}
if (buttonPushCounter == 4) {stepper.runToNewPosition(200);}
if (buttonPushCounter == 5) {stepper.runToNewPosition(250);}
if (buttonPushCounter == 6) {stepper.runToNewPosition(300);}
if (buttonPushCounter == 7) {stepper.runToNewPosition(350);}
if (buttonPushCounter == 8) {stepper.runToNewPosition(400);}
if (buttonPushCounter == 9) {stepper.runToNewPosition(450);}
if (buttonPushCounter == 10) {stepper.runToNewPosition(0);}

if (buttonPushCounter > 10) {buttonPushCounter = 0;}
  }
}

I think the problem is your use of stepper.runToNewPosition() which blocks the Arduino until it finishes (as stated in the AccelStepper documentation). Try using stepper.moveTo() However note that moveTo() only moves one step at a time so it needs to be called regularly. It does nothing when the motor is at its destination.

...R

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
In particularly showing how you are powering the project.

Tom.... :slight_smile:

#include <AccelStepper.h>
const int  buttonPinZaxis = 9;    // the pin that the pushbutton is attached to
AccelStepper Zaxis(1, 5, 8);      // pin 5 = step, pin 8 = direction
int buttonPushCounterZaxis = 0;
int buttonStateZaxis = 0;
int lastButtonStateZaxis = 0;  

void setup() {

  Zaxis.setMaxSpeed(2000);
  Zaxis.setSpeed(2000);
}

void loop() {
  lastButtonStateZaxis = buttonStateZaxis;
  buttonStateZaxis = digitalRead(buttonPinZaxis);
  if (buttonStateZaxis != lastButtonStateZaxis) 
  {
    if (buttonStateZaxis == HIGH) 
    {
      // if the current state is HIGH then the button turns from off to on:
      buttonPushCounterZaxis++;

 if (buttonPushCounterZaxis == 1) {  Zaxis.runToNewPosition( 50);}
 if (buttonPushCounterZaxis == 2) {  Zaxis.runToNewPosition(100);}
 if (buttonPushCounterZaxis == 3) {  Zaxis.runToNewPosition(150);}
 if (buttonPushCounterZaxis == 4) {  Zaxis.runToNewPosition(200);}
 if (buttonPushCounterZaxis == 5) {  Zaxis.runToNewPosition(250);}
 if (buttonPushCounterZaxis == 6) {  Zaxis.runToNewPosition(300);}
 if (buttonPushCounterZaxis == 7) {  Zaxis.runToNewPosition(350);}
 if (buttonPushCounterZaxis == 8) {  Zaxis.runToNewPosition(400);}
 if (buttonPushCounterZaxis == 9) {  Zaxis.runToNewPosition(450);}
 if (buttonPushCounterZaxis == 10) {  Zaxis.runToNewPosition( 0);}

 if (buttonPushCounterZaxis > 10) {buttonPushCounterZaxis = 0;}
}}}

I would like to replace runToNewPosition with runSpeedToPosition because it is not blocking but I get the following error.
“expects 0 arguments, 1 provided
no matching function for call to ‘AccelStepper::runSpeedToPosition(int)’”

Other than running very slowly, it behaves as expected.

The runSpeedToPosition() method will get the stepper to the last commanded position, at the specified speed. But, you need to set a new position, first. The runToNewPosition() sets the position, and waits for the stepper to get there.

What stepper driver board are you using?

The Easydriver and BigEasydriver both default to microstepping (1/16th ?) whereas the Pololu A4988 defaults to full steps.

...R
Stepper Motor Basics

The controller is an HY_DIV268N_5A. I'm not using a driver. Am I? The code is from the easy driver example.

I saw the blocking comments on the description a thought that was my issue.

I don't understand how to implement your suggestion though.

I would think it would look like this

if (buttonPushCounterZaxis == 1) { Zaxis. moveTo( 50);}

instead of this

if (buttonPushCounterZaxis == 1) { Zaxis.runToNewPosition( 50);}

but that doesn't work.

These changes have the stepper running at the correct speed but now it will not return to zero.

#include <AccelStepper.h>
const int  buttonPinZaxis = 9;    // the pin that the pushbutton is attached to
AccelStepper Zaxis(1, 5, 8);      // pin 5 = step, pin 8 = direction
int buttonPushCounterZaxis = 0;
int buttonStateZaxis = 0;
int lastButtonStateZaxis = 0;  

void setup() {

  Zaxis.setMaxSpeed(2000);
  Zaxis.setSpeed(2000);

}
void blockingRunSpeedToPosition(long position)
{
    Zaxis.moveTo(position);
    Zaxis.setSpeed(2000);
    while (Zaxis.distanceToGo() != 0)
      Zaxis.runSpeedToPosition();
}

void loop() {
  lastButtonStateZaxis = buttonStateZaxis;
  buttonStateZaxis = digitalRead(buttonPinZaxis);
  if (buttonStateZaxis != lastButtonStateZaxis) 
  {
    if (buttonStateZaxis == HIGH) 
    {
      // if the current state is HIGH then the button turns from off to on:
      buttonPushCounterZaxis++;

 if (buttonPushCounterZaxis == 1) {  Zaxis.runToNewPosition(400);}
 if (buttonPushCounterZaxis == 2) {  Zaxis.runToNewPosition(800);}
 if (buttonPushCounterZaxis == 3) {  Zaxis.runToNewPosition(1200);}
 if (buttonPushCounterZaxis == 4) {  Zaxis.runToNewPosition(1600);}
 if (buttonPushCounterZaxis == 5) {  Zaxis.runToNewPosition(2000);}
 if (buttonPushCounterZaxis == 6) {  Zaxis.runToNewPosition(2400);}
 if (buttonPushCounterZaxis == 7) {  Zaxis.runToNewPosition(2800);}
 if (buttonPushCounterZaxis == 8) {  Zaxis.runToNewPosition(3200);}
 if (buttonPushCounterZaxis == 9) {  Zaxis.runToNewPosition(3600);}
 if (buttonPushCounterZaxis == 10) {  Zaxis.runToNewPosition( 0);}
 if (buttonPushCounterZaxis > 9) {  Zaxis.runToNewPosition( 0);}

 
  if (buttonPushCounterZaxis == 0) {  Zaxis.runToNewPosition( 0);}

    // Zaxis.moveTo(2000);
   Zaxis.setSpeed(2000);
   // blockingRunSpeedToPosition(100);
   // delay(200);
   // blockingRunSpeedToPosition(0);
    // done, stop here
   // while (1) ;
}}}

That "controller" performs the equivalent function to the "stepper driver board" that I mentioned. Whatever you like to call it you are using it and it is essential :slight_smile:

I have just realized that in your short tenure here (9 posts as I type this) you have managed to spread yourself across THREE threads. The others are here and here. Don't cross post. How can we know all of the information about your project. (I do realize you mentioned one of them).

I am suggesting that the moderator merge them. Then I will see if I can help further.

...R

I’m not going to merge the stuff in the motors section 'cos it’s just too much effort.

wefinish:
I would think it would look like this

if (buttonPushCounterZaxis == 1) { Zaxis. moveTo( 50);}

moveTo() just sets the destination, it does not cause any moves. You also need stepper.run() in loop() where it is called everytime loop() repeats. It causes moves until the destination is reached. Look at the accellStepper examples. loop() must be able to repeat faster than the required step rate - which is not normally a problem.

...R

Hi,

Please answer post #2.

Thanks ...Tom.... :slight_smile:

power schematic-

If more details are needed, I can work on another drawing tonight.

Ignorance is NOT bliss. It is the most frustrating state,

Why doesn’t this work?

void loop() {
  lastButtonStateZaxis = buttonStateZaxis;
  buttonStateZaxis = digitalRead(buttonPinZaxis);
  if (buttonStateZaxis != lastButtonStateZaxis) 
  {
    if (buttonStateZaxis == HIGH) 
    {
      // if the current state is HIGH then the button turns from off to on:
      buttonPushCounterZaxis++;
   Zaxis.setSpeed(2000);
   Zaxis.run();
 if (buttonPushCounterZaxis == 1) {  Zaxis.moveTo(long,0);}
 if (buttonPushCounterZaxis == 2) {  Zaxis.moveTo(long,400);}
 if (buttonPushCounterZaxis == 3) {  Zaxis.moveTo(long,800);}
 if (buttonPushCounterZaxis == 4) {  Zaxis.moveTo(long,1200);}
 if (buttonPushCounterZaxis == 5) {  Zaxis.moveTo(long,1600);}
 if (buttonPushCounterZaxis == 6) {  Zaxis.moveTo(long,2000);}
 if (buttonPushCounterZaxis == 7) {  Zaxis.moveTo(long,2400);}
 if (buttonPushCounterZaxis == 8) {  Zaxis.moveTo(long,2800);}
 if (buttonPushCounterZaxis == 9) {  Zaxis.moveTo(long,3200);}
 if (buttonPushCounterZaxis == 10) {  Zaxis.moveTo(long,3600);}
 if (buttonPushCounterZaxis == 11) {  Zaxis.moveTo(long,4000);}
 if (buttonPushCounterZaxis > 9) {  Zaxis.moveTo(long, 0);}

 
  if (buttonPushCounterZaxis == 0) {  Zaxis.moveTo(long, 0);}

    // Zaxis.moveTo(2000);
   //Zaxis.setSpeed(2000);
   // blockingRunSpeedToPosition(100);
   // delay(200);
   // blockingRunSpeedToPosition(0);
    // done, stop here
   // while (1) ;
}}}

Ripp_Schematic.pdf (772 KB)

wefinish:
Why doesn't this work?

That is a useless question.

What you should have asked is
Why does this do XXXX when I want it to do YYYY.

That way we have some useful information to help understand the problem.

...R

I need the stepper motor to advance 400 steps each time the button is pressed for 10 button presses. On the 11th button press it needs to reverse to its original position. All of this without blocking and at speed.

My first example moved in this way but blocked other activities.
The second example was run separated from the other devices(to avoid the extra complications) and worked while advancing but turned very slowly while reversing to zero. I'm sure it also would block other processes.

That latest code paste where I'm attempting to use your advice and incorporate moveto() and stepper.run() advances only one step per button push. I don't know if it would ever reverse.

The boolean type thing has me confused. I don't understand how to set it up.

How would the code be set up to to attain the desired motor action using non-blocking code like moveto() and stepper.run()?

I've found a bit of example code after some searching but am not sure if it is the right path. Is it?

boolean AccelStepper::runSpeedToPosition()
{
    if (_targetPos == _currentPos)
	return false;
    if (_targetPos >_currentPos)
	_direction = DIRECTION_CW;
    else
	_direction = DIRECTION_CCW;
    return runSpeed();
}

wefinish:
That latest code paste where I'm attempting to use your advice and incorporate moveto() and stepper.run() advances only one step per button push. I don't know if it would ever reverse.

How can I help when you have not posted the latest code ?

...R

#include <AccelStepper.h>
const int  buttonPinZaxis = 9;    // the pin that the pushbutton is attached to
AccelStepper Zaxis(1, 5, 8);      // pin 5 = step, pin 8 = direction
int buttonPushCounterZaxis = 0;
int buttonStateZaxis = 0;
int lastButtonStateZaxis = 0;  

void setup() {

  Zaxis.setMaxSpeed(2000);
  Zaxis.setSpeed(2000);
}
void blockingRunSpeedToPosition(long position)
{
    Zaxis.moveTo(position);
    Zaxis.setSpeed(2000);
    while (Zaxis.distanceToGo() != 0)
      Zaxis.runSpeedToPosition();
}

void loop() {
  lastButtonStateZaxis = buttonStateZaxis;
  buttonStateZaxis = digitalRead(buttonPinZaxis);
  if (buttonStateZaxis != lastButtonStateZaxis) 
  {
    if (buttonStateZaxis == HIGH) 
    {
      // if the current state is HIGH then the button turns from off to on:
      buttonPushCounterZaxis++;
   Zaxis.setSpeed(2000);

      buttonPushCounterZaxis++;

 if (buttonPushCounterZaxis == 1) {  Zaxis.moveTo()( 50);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 2) {  Zaxis.moveto()(100);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 3) {  Zaxis.moveto()(150);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 4) {  Zaxis.moveto()(200);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 5) {  Zaxis.moveto()(250);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 6) {  Zaxis.moveto()(300);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 7) {  Zaxis.moveto()(350);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 8) {  Zaxis.moveto()(400);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 9) {  Zaxis.moveto()(450);}
 Zaxis.run()
 if (buttonPushCounterZaxis == 10) {  Zaxis.moveto()( 0);}
 Zaxis.run()
 if (buttonPushCounterZaxis > 10) {buttonPushCounterZaxis = 0;}



    // Zaxis.moveTo(2000);
   //Zaxis.setSpeed(2000);
   // blockingRunSpeedToPosition(100);
   // delay(200);
   // blockingRunSpeedToPosition(0);
    // done, stop here
   // while (1) ;
}}}

You only need a single line with Zaxis.run()
But it MUST be in loop() and NOT inside any IF statement

Put it just before the } that marks the end of loop()

The idea is to call Zaxis.run() as often as possible

...R

I need the stepper motor to advance 400 steps each time the button is pressed for 10 button presses. On the 11th button press it needs to reverse to its original position. All of this without blocking and at speed.

This code advances only one step per button push. I don’t see how this behavior is coming from this code. What needs to change in this code?

I feel like I’ve tried everything(obviously haven’t).

#include <AccelStepper.h>
AccelStepper Zaxis(1, 5, 8);      // pin 5 = step, pin 8 = direction

const int  buttonPinZaxis = 9;    // the pin that the pushbutton is attached to

int buttonPushCounterZaxis = 0;
int buttonStateZaxis = 0;
int lastButtonStateZaxis = 0;  

void setup() {

    Zaxis.setMaxSpeed(2000.0);
    Zaxis.setAcceleration(100.0);
    Zaxis.moveTo(50); 
}

void loop() {
  lastButtonStateZaxis = buttonStateZaxis;
  buttonStateZaxis = digitalRead(buttonPinZaxis);
  if (buttonStateZaxis != lastButtonStateZaxis) 
  {
    if (buttonStateZaxis == HIGH) 
      buttonPushCounterZaxis++;
    if (buttonPushCounterZaxis > 10) buttonPushCounterZaxis = 0;
{
           if (buttonPushCounterZaxis == 1) 
         Zaxis.moveTo(400);
           if (buttonPushCounterZaxis == 2) 
         Zaxis.moveTo(800);
           if (buttonPushCounterZaxis == 3) 
         Zaxis.moveTo(1200);
           if (buttonPushCounterZaxis == 4) 
         Zaxis.moveTo(1600);
           if (buttonPushCounterZaxis == 5) 
         Zaxis.moveTo(2000);
           if (buttonPushCounterZaxis == 6) 
         Zaxis.moveTo(2400);
           if (buttonPushCounterZaxis == 7) 
         Zaxis.moveTo(2800);
           if (buttonPushCounterZaxis == 8) 
         Zaxis.moveTo(3200);
           if (buttonPushCounterZaxis == 9) 
         Zaxis.moveTo(3600);
           if (buttonPushCounterZaxis == 10) 
         Zaxis.moveTo(4000);
           if (buttonPushCounterZaxis == 0) 
         Zaxis.moveTo(0);

       if (Zaxis.distanceToGo() == 0)
        Zaxis.moveTo(-Zaxis.currentPosition());

   Zaxis.run();
}}}