Toggling motor with 1 button...Do I need an interrupt?

Hello everyone,

I've done a fair amount of searching and have tried a bunch of different things but I can't seem to understand what's going on......

BACKGROUND:

So, I'm building a platform lifting mechanism with 2 lead screws connected to 2 stepper motors.
I have 1 button and would like to raise the platform with a push, and then lower the platform with a second push....a third push would raise it up again and so on.
I have the stepper motors running perfectly with 2 DRV8834 stepper controllers. I can operate them without issue using various example sketches. I'm using laurb9's library which can be found here: GitHub - laurb9/StepperDriver: Arduino library for A4988, DRV8825, DRV8834, DRV8880 and generic two-pin (DIR/STEP) stepper motor drivers

What I need to happen is the following:

Turn on system (arduino, Motors)
Poll switch state
If switch is high, Turn motors 1000 steps and stop.
Continue polling switch state
If switch is high for the second time, turn motors -1000 steps and stop.
Continue polling switch state

What I seem to be confused about is whether or not I need an interrupt to do this. I imagine that the main loop would just continuously poll the switch...and when the switch is high, interrupt and execute the motor routine, flip the state of the platform position, and then exit back to the main loop.

Am I on the right track here? Or can this be achieved in a simpler way?

Many thanks for any help you guys can give.

Tommyboy123:
Am I on the right track here? Or can this be achieved in a simpler way?

Hard to tell from the code you didn’t post.

This sketch shows how to toggle the state of an output (could just as easily be a boolean variable). It uses the state change detection method to detect transitions.

The switch is wired from the input to ground and the pinMode is set to INPUT_PULLUP.

// this constant won't change:
const int  buttonPin = 8;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
boolean buttonState = 0;         // current state of the button
boolean lastButtonState = 0;     // previous state of the button

void setup()
{
   // initialize the button pin as a input with internal pullup enabled
   pinMode(buttonPin, INPUT_PULLUP);
   // initialize the LED as an output:
   pinMode(ledPin, OUTPUT);
   // initialize serial communication:
   Serial.begin(9600);
}

void loop()
{
   // read the pushbutton input pin:
   buttonState = digitalRead(buttonPin);
   // compare the buttonState to its previous state
   if (buttonState != lastButtonState)
   {
      if (buttonState == LOW)
      {
         // if the current state is LOW then the button
         // went from off to on:
         Serial.println("button pressed");
         digitalWrite(ledPin, !digitalRead(ledPin)); // toggle the output
      }
      delay(50);
   }
   // save the current state as the last state,
   //for next time through the loop
   lastButtonState = buttonState;
}

gfvalvo:
Hard to tell from the code you didn’t post.

And before you do, read this: Read this before posting a programming question … … especially Item #6.

You might want to check out the example StateChangeDetection (File → Examples → 02.Digital ->StateChangeDetection) to see a good example of how to do this. You want to run the motors when the button has been pushed (state change) not necessarily if the button is being pushed or not (current state)

Here’s what I have so far:

[NOTES]: 1.Testing with 200 steps, not 1000 as previously mentioned. 2. This code makes the motors spin 200 steps, pause, 200 more steps, pause, and so on. If I click the button continuously, every so often it will read the button state change and change the direction of the motors.

#include <Arduino.h>
#include "BasicStepperDriver.h"


// constants won't change. They're used here to set pin numbers:
const int buttonPin = 12;     // the number of the pushbutton pin
int buttonState = 0;         // variable for reading the pushbutton status
int lastState;
int posState;



// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step
#define MOTOR_STEPS 200
#define RPM 50

// Since microstepping is set externally, make sure this matches the selected mode
// If it doesn't, the motor will move at a different RPM than chosen
// 1=full step, 2=half step etc.
#define MICROSTEPS 1

// All the wires needed for full functionality
#define DIR 7
#define STEP 6

//Uncomment line to use enable/disable functionality
//#define SLEEP 13

// 2-wire basic config, microstepping is hardwired on the driver
BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP);

//Uncomment line to use enable/disable functionality
//BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP, SLEEP);

void setup() {

   // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
  
}

void loop() {
  
    // energize coils - the motor will hold position
    stepper.enable();

    // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  if (buttonState != lastState) {
  if (buttonState == HIGH) {
    if (posState == 200) posState = -200;
    else posState = 200;
  }
  lastState = buttonState;
  }
  stepper.move(posState);
  stepper.disable();
  delay(20);
  }

You can’t do the entire move all at once. You need to take smaller steps toward your goal which will give you more time to check the button press
[untested]

#include <Arduino.h>
#include "BasicStepperDriver.h"


// constants won't change. They're used here to set pin numbers:
const int buttonPin = 12;     // the number of the pushbutton pin
int buttonState = 0;         // variable for reading the pushbutton status
int lastState;
int posState;



// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step
#define MOTOR_STEPS 200
#define RPM 50

// Since microstepping is set externally, make sure this matches the selected mode
// If it doesn't, the motor will move at a different RPM than chosen
// 1=full step, 2=half step etc.
#define MICROSTEPS 1

// All the wires needed for full functionality
#define DIR 7
#define STEP 6

//Uncomment line to use enable/disable functionality
//#define SLEEP 13

// 2-wire basic config, microstepping is hardwired on the driver
BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP);

//Uncomment line to use enable/disable functionality
//BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP, SLEEP);

void setup() {

  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);

}

int stepIncrement = -10;
bool moveDirection = 0; // arbitrary: 1 = fwd, 0 = reverse
bool moving = false;

void loop() {

  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  if (buttonState != lastState) {
    lastState = buttonState;
    if (buttonState == HIGH) {
      moving = true;
      moveDirection = !moveDirection;
      stepIncrement = -stepIncrement;
      stepper.enable();   // energize coils - the motor will hold position
    }
  }
  if ( moving ) {
    posState += stepIncrement;
    stepper.move(stepIncrement);
  }
  if ( abs(posState) >= MOTOR_STEPS ) {
    mvoing = false;
    stepper.disable();
  }
}

You can also look at the nonblocking example that comes with the library

Bump!