Getting Stepper Motor to be able to allow potentiometer and change direction at same time

The potentiometer code works without the block of code underneath it to control the direction, but the reverse code does not work fully, not necessarily changing the direction jus the other way and instead when the button is released. We are using an external button on a PCB. A solution to get both pieces of code working in the loop would be helpful.

/*
  Stepper Motor Test
  stepper-test01.ino
  Uses MA860H or similar Stepper Driver Unit
  Has speed control & reverse switch
*/
 
// Defin pins
 
int reverseSwitch = 8;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Potentiometer

// Variables
int var = 0;
int pd = 500;       // Pulse Delay period
boolean setdir = LOW; // Set Direction
 
// Interrupt Handler
 
void revmotor (){

   setdir = !setdir;
 
}

void setup() {
  Serial.begin(9600);
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
//  attachInterrupt(digitalPinToInterrupt(reverseSwitch), revmotor, RISING);
}

void loop() {
         
          pd = map((analogRead(spd)),0,1023,2000,50);
          digitalWrite(driverDIR,setdir);
          digitalWrite(driverPUL,HIGH);
          delayMicroseconds(pd);
          digitalWrite(driverPUL,LOW);
          delayMicroseconds(pd);
         
    switch (var=digitalRead(reverseSwitch)) {
      case 0:
          Serial.println("Forward");
        break;
      case 1:
          Serial.println("Reserve");
          revmotor();
          var=0;
        break;
}
}

How is the switch wired? is there a pullup or pulldown resistor on the switch input so it is not floating when the switch is open?

On the output from the button we have a 10 kohm resistor pulling it to 5V high.

Shouldn't there be a revmotor() function in the case 0?

Or do you want to reverse the direction on each button press? Like press the button the motor goes forward, release the button, nothing changes, press the button again, the motor goes reverse, release nothing. So toggle the direction for each button press?

We want the button to change direction once it is pressed, but it is wired up in a way where it it on when it is not pressed and off when it is. That is why they are swapped. But even with that, the code does not work with the potentiometer code. Any possible ways to have both work?

In that code, the time that it takes to do the serial print in the cases is controlling the speed of the stepper, not the potentiometer. Comment out the serial prints and see.

Use the state change detection method to toggle the state of the setdir variable.

Here is an example showing how. Note that there are no serial prints to slow down loop execution. For your code to work right the loop() must run at full speed. This will work as long as the motor is going slow. If it is going fast it cannot reverse suddenly. Physics prevents that. You will need to rewrite the code to stop the motor and accelerate it to higher speeds.

/*
   Stepper Motor Test
   stepper-test01.ino
   Uses MA860H or similar Stepper Driver Unit
   Has speed control & reverse switch
*/

// Defin pins

const byte reverseSwitch = 8;  // Push button for reverse
const byte driverPUL = 7;    // PUL- pin
const byte driverDIR = 6;    // DIR- pin
const byte spd = A0;     // Potentiometer

// Variables
int var = 0;
int pd = 500;       // Pulse Delay period
bool setdir = LOW; // Set Direction

void setup()
{
   Serial.begin(9600);
   pinMode (driverPUL, OUTPUT);
   pinMode (driverDIR, OUTPUT);
   //  attachInterrupt(digitalPinToInterrupt(reverseSwitch), revmotor, RISING);
}

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

   static bool lastVar = HIGH;
   var = digitalRead(reverseSwitch);
   if (var != lastVar)
   {
      if (var == LOW)
      {
         setdir = !setdir;
      }
      lastVar = var;
   }
}

Code tested on real hardware.

Tutorials:
state change detection
state change detection for active low inputs
Robin2's simple stepper programs (has non-blocking example).

We tried implementing this code and the potentiometer portion works fine but the button code does not work. We tried recoding it but nothing allows it to read the button at the same time as the potentiometer. We switched the button for an On/Off switch. Is there any edits you would recommend now that we have a switch?

The code that I posted was tested successfully on real hardware. If the code does not work for you, there is something different with your setup.

My setup has one side of the switch to ground and the other to an input with a 10K resistor from the input to Vcc (a pullup resistor).

How is the switch wired? Please post a wiring diagram. Hand drawn, photographed and posted is fine. Include all pin names/numbers, components, their part numbers and/or values and power supplies.

I had not mentioned that the switch was on a PLC, I had messed up PCB and PLC in my head. We are taking the signal off of the PLC, and it has multiple other buttons and switches on it. The signal is going into an octocoupler and stepping down the voltage. We are also using a M542T microstep driver and the motor is a Stepper Motor Nema 23 Bipolar 2.8A. Here is also the layout for the wiring.

Try this mod, see if onboard LED changes with direction, speed is also much slower.

/*
  Stepper Motor Test
  stepper-test01.ino
  Uses MA860H or similar Stepper Driver Unit
  Has speed control & reverse switch
*/
 
// Defin pins
 
int reverseSwitch = 8;  // Push button for reverse
int driverPUL = 7;    // PUL- pin
int driverDIR = 6;    // DIR- pin
int spd = A0;     // Potentiometer

// Variables
int var = 0;
int pd = 5000;       // Pulse Delay period
boolean setdir = LOW; // Set Direction
 
// Interrupt Handler
 
void revmotor (){

   setdir = !setdir;
 
}

void setup() {
  Serial.begin(9600);
  pinMode (driverPUL, OUTPUT);
  pinMode (driverDIR, OUTPUT);
  pinMode(LED_BUILTIN,OUTPUT);
//  attachInterrupt(digitalPinToInterrupt(reverseSwitch), revmotor, RISING);
}

void loop() {
         
          pd = map((analogRead(spd)),0,1023,20000,2000);
          digitalWrite(driverDIR,setdir);
          digitalWrite(LED_BUILTIN,digitalRead(reverseSwitch));
          digitalWrite(driverPUL,HIGH);
          delayMicroseconds(pd);
          digitalWrite(driverPUL,LOW);
          delayMicroseconds(pd);
         
    switch (var=digitalRead(reverseSwitch)) {
      case 0:
          Serial.println("Forward");
        break;
      case 1:
          Serial.println("Reserve");
          revmotor();
          var=0;
        break;
}
}

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