Turning a stepper motor off and on

Hello guys,

I currently have a sketch to control a stepper motor with a potentiometer and a push button for rev/fwd.
The problem is when i turn the potentiometer all the way down it still moves. How can i turn off/on the motor??

// Define pins
 
int reverseSwitch = 2;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Potentiometer
 
// Variables
 
int pd = 500;       // Pulse Delay period
boolean setdir = LOW; // Set Direction
 
// Interrupt Handler
 
void revmotor (){
 
  setdir = !setdir;
  
}
 
 
void setup() {
 
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(reverseSwitch), revmotor, FALLING);
  
}
 
void loop() {
  
    pd = map((analogRead(spd)),0,1023,2000,50);
    digitalWrite(driverDIR,setdir);
    digitalWrite(driverPUL,HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL,LOW);
    delayMicroseconds(pd);
 
}

Look at how you use the map() function. What is the lowest value that it will return ?

Hi @slayxr,

you got already some hints how to get forward ...

Here is a simulation of your application on Wokwi:

/*
   Forum: https://forum.arduino.cc/t/turning-a-stepper-motor-off-and-on/1168572
   Wokwi: https://wokwi.com/projects/375869577129168897

*/

// Define pins
constexpr byte reverseSwitch = 2;  // Push button for reverse
constexpr byte  driverPUL = 7;    // PUL- pin
constexpr byte  driverDIR = 6;    // DIR- pin
constexpr byte  spd = A0;     // Potentiometer

// Variables

unsigned long pd = 500;       // Pulse Delay period in microseconds
byte setdir = LOW;            // Set Direction



void setup() {
  pinMode(reverseSwitch, INPUT_PULLUP);
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);

}

void loop() {
  checkReverseButton();
  pd = map((analogRead(spd)), 0, 1023, 2000, 50);
  if (pd < 1950) {
    digitalWrite(driverDIR, setdir);
    digitalWrite(driverPUL, HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL, LOW);
    delayMicroseconds(pd);
  }
}

void checkReverseButton() {
  static unsigned long lastChange = 0;
  static byte state = HIGH;
  static byte lastDetected = HIGH;
  byte detected = digitalRead(reverseSwitch);
  if (detected != lastDetected) {
    lastDetected = detected;
    lastChange = millis();
  }
  if (millis() - lastChange > 30 && state != lastDetected) {
    state = lastDetected;
    if (state == LOW) {
      setdir = !setdir;
    }
  }
}

See also https://wokwi.com/projects/375869577129168897

  • You map the analog input to a time delay from 2000 down to 50 . Therefore in this sketch all values equal or above 1950 will skip the routine that moves the stepper.
  • The use of an interrupt with a switch is problematic due to the bouncing of mechanical switches (means: The contacts of that switch may "bounce" between on and off very quickly several times while you press or release it. That leads to several interrupts within a short time while you think you only switched once.)
  • Therefore I replaced it by a millis() debouncing function that works quite well. Of course the pinMode of the reverseSwitch has to be set now in setup().

Study the sketch, play around and make your changes to get a better understanding ...

Good luck!
ec2021

P.S.: Just for the fun of it ... here a version that uses an interrupt:

Click here if you are interested
/*
   Forum: https://forum.arduino.cc/t/turning-a-stepper-motor-off-and-on/1168572
   Wokwi: https://wokwi.com/projects/375870418732018689

*/

// Define pins
constexpr byte reverseSwitch = 2;  // Push button for reverse
constexpr byte  driverPUL = 7;    // PUL- pin
constexpr byte  driverDIR = 6;    // DIR- pin
constexpr byte  spd = A0;     // Potentiometer

// Variables

unsigned long pd = 500;       // Pulse Delay period in microseconds
byte setdir = LOW;            // Set Direction



void setup() {
  pinMode(reverseSwitch, INPUT_PULLUP);
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(reverseSwitch),revmotor, FALLING);
}


void loop() {
  pd = map((analogRead(spd)), 0, 1023, 2000, 50);
  if (pd < 1950) {
    digitalWrite(driverDIR, setdir);
    digitalWrite(driverPUL, HIGH);
    delayMicroseconds(pd);
    digitalWrite(driverPUL, LOW);
    delayMicroseconds(pd);
  }
}

void revmotor() {
  static unsigned long lastAction;
  static boolean ISRActive = false;
  if (!ISRActive && millis() - lastAction > 500) {
    ISRActive = true;
  }
  if (ISRActive) {
     ISRActive = false;
     setdir = !setdir;
     lastAction = millis();
  }
}

Some explanation:

  • The ISR uses the time it has been called and a boolean variable.
  • It does not reverse the stepper direction within a time of (here) 500 msec after the last change.

You can try it on Wokwi: https://wokwi.com/projects/375870418732018689

To see the effect of bouncing just keep the button pressed for longer that half a second. You will see that the direction changes due to bouncing effects when you release(!) the button ...

Now stop the sketch on Wokwi and click on the button symbol. A menue appears
image

Now click on the symbol left of "Bounce" so that it becomes black:

image

Now you have switched off the bouncing simulation for this button. If you start the sketch again and repeat the press/release for more than half a second, the direction will only be reversed when you press the button.

Thank you very much! But I'm really trying to have a button control this motor when its pressed it would turn on. We are trying to retro fit a coil winding machine that makes electrical transformers. 500kva+ size. so safety is important. ideally the button would act as a "dead man switch". Any ideas?
if you would like to email me @ nmontgomery@macromagnetics.com we can talk about consulting fees?