Running a stepper motor x number of steps on button press then back, same button

Hello all

I have recently started building and programming some devices, and i came across something of which i seem to not be able to find any code about. Just to be clear, i am a total novice, but i feel like the thing i am trying to do should be simple enough, yet it seems to not work.

I have tried several approaches, but this is my latest (failure)

#include <AccelStepper.h>

#define LED 14    // D5(gpio14)
#define BUTTON 12 // D6(gpio12)

//Let's say you have your push button on pin 12
int switchState = 0; // actual read value from pin12
int oldSwitchState = 0; // last read value from pin12
int lightsOn = 0; // is the switch on = 1 or off = 0

AccelStepper Stepper(1,D1,D2,D3,D4); 

int stepCounter = 0;
int stepping = false;

void setup() {

 pinMode(BUTTON, INPUT); // push button 
 pinMode(LED, OUTPUT); // anything you want to control using a switch e.g. a Led

  Stepper.setMaxSpeed(10);       //set max speed the motor will turn (steps/second)
  Stepper.setAcceleration(10);  //set acceleration (steps/second^2)
 
 Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:

switchState = digitalRead(BUTTON); // read the pushButton State
 if (switchState != oldSwitchState) // catch change
 {
 oldSwitchState = switchState;
 if (switchState == HIGH)

 {
 // toggle
 lightsOn = !lightsOn;
 }
 delay (50);
 }
 if(lightsOn)
 {
 digitalWrite(LED, HIGH); // set the LED on
 Stepping = true;
 Stepper.runToPosition(100);
 delay (100);
 Stepping = false;
 
 } else 
 {
 digitalWrite(LED, LOW); // set the LED off
 Stepping = true;
 Stepper.runToPosition(-100);
 delay (100);
 Stepping = false;
 }

}

I am trying to move a stepper motor a certain number of steps at the push of a button, then when i push it again, it should get back to its normal position. I am using the LED to indicate a state change, and i thought i would run the number of steps at this state change, but i must be doing something wrong. Have been trying to find stuff for several days, and i keep finding the same stuff i already tried.

So, how do i make pockets of code, that activate on a state change, and then only activate once per state change? I probably didn’t even correctly tell the motor to do steps :-(.

thomas_c:
I am using the LED to indicate a state change, and i thought i would run the number of steps at this state change, but i must be doing something wrong. .

You have not told us what actually happens.

My guess is that you should be doing

Stepper.runToPosition(0);

to get back to where you started.

If you use the AutoFormat tool to indent your code you will find it much easier to make sense of it.

...R

Thank you for your answer :).

Nothing happened, not even a light blinking. Which is why i returned to the regular stepper.

#include <Stepper.h>

#define LED 14    // D5(gpio14)
#define BUTTON 12 // D6(gpio12)

Stepper myStepper(200, D1,D2,D3,D4); 

//Let's say you have your push button on pin 12
int switchState = 0; // actual read value from pin12
int oldSwitchState = 0; // last read value from pin12
int lightsOn = 0; // is the switch on = 1 or off = 0

int Distance = 0;

void setup() {

  pinMode(BUTTON, INPUT); // push button 
  pinMode(LED, OUTPUT); // anything you want to control using a switch e.g. a Led
  myStepper.setSpeed(60);
  Serial.begin(9600);
}

void loop() {

switchState = digitalRead(BUTTON); // read the pushButton State
 if (switchState != oldSwitchState) // catch change
 {
 oldSwitchState = switchState;
 if (switchState == HIGH)

 {
 // toggle
 lightsOn = !lightsOn;
 }
 delay (50);
 }
 if(lightsOn)
 {
 digitalWrite(LED, HIGH); // set the LED on
  myStepper.step(50);
  myStepper.step(-50);
  Distance = Distance + 1;
  
  if (Distance == 2) {
    // Prevent the sketch from doing anything further
    //while (true) /* Do nothing*/ ;
    while (true) myStepper.setSpeed(0);

    
 }
 
 } else 
 {
 digitalWrite(LED, LOW); // set the LED off


  }
}

With this code, (just for a try), the motor makes 2 90 degree nods when turning the lamp on, then resets (probably because there was no way out of the loop. I imagine, it can no longer take any commands from the button. I wish it still could input commands, as that would fix the reset situation too i believe.

So, with ;

Stepper.runToPosition(0);

it actually remembers. Maybe i should do that instead of this (just the regular stepper, not accelstepper, as i couldn’t get that one to run, and yes, i did install drivers).

thomas_c:
Thank you for your answer :).

Nothing happened, not even a light blinking.

The AccelStepper library is a great deal more comprehensive than the standard stepper library.

You have still not told us what the original program does, nor have you posted the revised version that "nothing happened" so I don't know how to help.

...R

Okay, i misunderstood

What i wanted with the first iteration, was to, at the press of a button, go to point 100 (so 100 steps, i believe), and when i press the same button again, it would go to point -100, or 100 backwards (either one would be good, when i know what it does i can adjust). But all this i already said in the first post.

I planned to use the change in LED. On to off, and off to on, as an indicator for the trigger.

thomas_c:
What i wanted with the first iteration, was to, at the press of a button, go to point 100 (so 100 steps, i believe), and when i press the same button again, it would go to point -100, or 100 backwards (either one would be good, when i know what it does i can adjust). But all this i already said in the first post.

That was clear enough, except that moving from 0 to 100 is (obviously) 100 steps but moving from 100 to -100 is 200 steps.

However you STILL have not posted the revised program so it's difficult to see what you might have done wrong - probably just a very minor error.

...R

The revised program

#include <Stepper.h>

#define LED 14    // D5(gpio14)
#define BUTTON 12 // D6(gpio12)

Stepper myStepper(200, D1, D2, D3, D4);

//Let's say you have your push button on pin 12
int switchState = 0; // actual read value from pin12
int oldSwitchState = 0; // last read value from pin12

int Distance = 0;

void setup() {

  pinMode(BUTTON, INPUT); // push button
  pinMode(LED, OUTPUT); // anything you want to control using a switch e.g. a Led
  myStepper.setSpeed(60);
  Serial.begin(9600);
}

void loop() {

  switchState = digitalRead(BUTTON);

  if (switchState != oldSwitchState && Distance == 0) // button check
     {
      myStepper.setSpeed(60);
      delay (100);
      myStepper.step(50);
      delay (500);
      Distance = Distance + 1;
     }
  if (switchState != oldSwitchState && Distance == 1) 
      { 
      myStepper.setSpeed(60);
      delay (100);
      myStepper.step(-50);
      delay (500);
      Distance = Distance - 1;
      }
  if (switchState != oldSwitchState && Distance != 0 || Distance != 1) 
      {
      Distance = 0;
      }
    }

Right now, it does 2 things when i press the button. go 50 steps one way and 50 steps the other way. But it doesn’t accept the second button press, only one, and does both things after the other.

I could go with timing, and hope the other tasks i have planned for it, would be in this time. But it seems something so simple, i cannot continue until this works :(.

okay

After redoing the code 2 more times. I found something that does what i want it to do.

#include <stdio.h>
#include <stdlib.h>
#include <Stepper.h>

#define LED 14    // D5(gpio14)
#define BUTTON 12 // D6(gpio12)

Stepper myStepper(200, D1, D2, D3, D4);

int ledflag=0;                   // LED status flag
int Distance = 0;

void setup() {
  pinMode(BUTTON,INPUT);         // define button as an input 
  pinMode(LED,OUTPUT);           // define LED as an output
  digitalWrite(LED, LOW);         // turn output off just in case
  myStepper.setSpeed(60);
  Serial.begin(9600);
}


void loop() {
  if (digitalRead(BUTTON)==HIGH){ // if button is pressed
    if (ledflag==0 && Distance ==0) 
    {             // and the status flag is LOW
      ledflag=1;                  // make status flag HIGH
      digitalWrite(LED,HIGH);     // and turn on the LED
      myStepper.setSpeed(60);
      delay (100);
      myStepper.step(50);
      delay (500);
      Distance = Distance + 1;
      }                           // 
    else 
    {                        // otherwise...
      ledflag=0;                  // make status flag LOW
      Distance=1;
      digitalWrite(LED,LOW);      // and turn off the LED
      myStepper.setSpeed(60);
      delay (100);
      myStepper.step(-50);
      delay (500);
      Distance = Distance - 1;
    }
  delay(100);                    // wait a sec for the 
  }                               // hardware to stabilize
}                                 // begin again

Why does this work? What is different here??

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.