how to stop stepper motor from using power when idle?

I'm using a joystick to control an Arduino nano connected to a tb6600 driver and a Nema 23 stepper motor. I modified this code slightly which works great except that the power is always on to the motor which keeps it locked but I don't need that and I don't want it to use power when idle. Does anyone know how to cut the power when the motor isn't spinning?

#include <AccelStepper.h> //accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)
//Pins
 const byte Analog_X_pin = A0; //x-axis readings
//Variables
 int Analog_X = 0; //x-axis value
 int Analog_X_AVG = 0; //x-axis value average

void setup()
{
  //SERIAL
  Serial.begin(9600);
  //----------------------------------------------------------------------------    
  //PINS
  pinMode(Analog_X_pin, INPUT);
  //----------------------------------------------------------------------------  
  InitialValues(); //averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------  
  //Stepper parameters
  //setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000); //SPEED = Steps / second  
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2    
  stepper.setSpeed(1000);
  delay(1000);
}
void loop()
{
  ReadAnalog();  
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}
void ReadAnalog()
{
  //Reading the potentiometer in the joystick: 
  Analog_X = analogRead(Analog_X_pin);  
  //if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  //This is a sort of a filter for the inaccuracy of the reading
  if(abs(Analog_X-Analog_X_AVG)>50) 
  {
  stepper.setSpeed(5*(Analog_X-Analog_X_AVG));    
  }
  else
  {
    stepper.setSpeed(0);
  }
}
void InitialValues()
{
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------  
  //read the analog 50x, then calculate an average. 
  //they will be the reference values
  for(int i = 0; i<50; i++)
  {
    tempX += analogRead(Analog_X_pin);  
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------  
  Analog_X_AVG = tempX/50; 
  //----------------------------------------------------------------------------  
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");  
}

Doesn't the TB6600 have an enable (EN) input that enables/disables the driver outputs?

The standard use of a stepper-motor is to be "under current" all the time the device is switched on.
Completely disabling power shuts off the holding-torque of the steppermotor.

Depending on your meachinc this means free-wheeling of the motor or loosing its accurate position.
If this doesn't matter you can use the enable-input. Most drivers have an option to reduce current if the stepper-motor isn't stepping.

What is the reason for you trying to switch off the current?

best regards Stefan

Thanks, I understand the holding torque, but I don't need it for this application and I'm using battery power. I did not wright the code I just modified it and it works great with a joystick except for that. and I have to connect 2 hall switches to stop travel at each end.
The link shows the connections and the code, I'm only using 2 axis and a nano instead of an uno. I not sure how to connect the ena pin and add something to the code to disconnect the power when motors are idol.

Connect E+ to 5V. Connect E- to pin 7 (or the pin of your choice). Before setup() declare a global variable enablePin :

const byte enablePin = 7;  // or the pin you choose

In setup() set enablePin to be an output with:

pinMode(enablePin, OUTPUT);

Now, in your code, you can write to enablePin when you wish to enable or disable the motor driver:

digitalWrite(enablePin, HIGH);  // or LOW

to turn the motor on or off. I could not find a definitive statement of which state (HIGH or LOW) enables the motors, just use trial and error to find out.

Well, I set the enable pin LOW and it stops power to the motor but it shuts it off completely. I only want it to shut off when not moving in either direction. So that when the joystick is in the center (off position) there's no power to the coils (no holding torque), but I need to rotate the motor in either direction.

#include <AccelStepper.h> //accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)
//Pins
 const byte Analog_X_pin = A0; //x-axis readings
 const byte enablePin = 7;
//Variables
 int Analog_X = 0; //x-axis value
 int Analog_X_AVG = 0; //x-axis value average

void setup()
{
  Serial.begin(9600); //SERIAL
  //----------------------------------------------------------------------------    
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------  
  InitialValues(); //averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------  
  //Stepper parameters
  //setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000); //SPEED = Steps / second  
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2    
  stepper.setSpeed(1000);
  delay(1000);
}
void loop()
{
  digitalWrite(enablePin, LOW); 
  ReadAnalog();  
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}
void ReadAnalog()
{
  //Reading the potentiometer in the joystick: 
  Analog_X = analogRead(Analog_X_pin);  
  //if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  //This is a sort of a filter for the inaccuracy of the reading
  if(abs(Analog_X-Analog_X_AVG)>50) 
  {
  stepper.setSpeed(5*(Analog_X-Analog_X_AVG));    
  }
  else
  {
    stepper.setSpeed(0);
  }
}
void InitialValues()
{
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------  
  //read the analog 50x, then calculate an average. 
  //they will be the reference values
  for(int i = 0; i<50; i++)
  {
    tempX += analogRead(Analog_X_pin);  
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------  
  Analog_X_AVG = tempX/50; 
  //----------------------------------------------------------------------------  
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");  
}

The way that you have it the motor is disabled all the time. The solution is to remove that and
when the motor is stopped, disable the motor and before the motor is told to run enable the motor.

Something like this:

if(abs(Analog_X-Analog_X_AVG)>50)
  {
      digitalWrite(enablePin, HIGH);  // enable the driver
      stepper.setSpeed(5*(Analog_X-Analog_X_AVG));   
  }
  else
  {
      digitalWrite(enablePin, LOW);   // disable the driver
      stepper.setSpeed(0);
  }

Thank you, I had to go out for a while but I just got back and tried it and it worked perfectly! Thank you very much. Now I just need to put the end stops in. I have some hall effect switches to put on both ends of the screw shaft so that the object on the shaft stops going in that direction when the switch is triggered. I will figure it out eventually but if you happen to know the best way to do it I'd be grateful. Thanks again.

Got it, thanks for your help

Well I guess I don't got it. I tried this modification to the code but can't get the end switches to work. Any suggestions?

//pin connections from nano to TB6600, pot and switches
//ENA- d7
//ENA+ 5v
//DIR- d9
//DIR+ 5v
//PUL- d8
//PUL+ 5v
//pot wiper A0
//pot L+
//pot R-
//end switch #1 d2
//end switch #2 d3
//----------------------------------------------------------------------------  

#include <AccelStepper.h> //accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)
//Pins
 const byte Analog_X_pin = A0; //x-axis readings
 const byte enablePin = 7;
 const byte leftSwitch = 2;
 const byte rightSwitch = 3; 
//Variables
 int Analog_X = 0; //x-axis value
 int Analog_X_AVG = 0; //x-axis value average

void setup()
{
 
  //SERIAL
  Serial.begin(9600);
  //----------------------------------------------------------------------------    
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------  
  InitialValues(); //averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------  
  //Stepper parameters
  //setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000); //SPEED = Steps / second  
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2    
  stepper.setSpeed(1000);
  delay(1000);
}
void loop()
{
  ReadAnalog();
  ReadLimits();  
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
  
  ReadAnalog();  
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}
void ReadAnalog()
{
  if(abs(Analog_X-Analog_X_AVG)>50)
  {
      digitalWrite(enablePin, HIGH);  // enable the driver
      stepper.setSpeed(5*(Analog_X-Analog_X_AVG));   
  }
  else
  {
      digitalWrite(enablePin, LOW);   // disable the driver
      stepper.setSpeed(0);
  }
  //Reading the potentiometer in the joystick: 
  Analog_X = analogRead(Analog_X_pin);  
  //if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  //This is a sort of a filter for the inaccuracy of the reading
  if(abs(Analog_X-Analog_X_AVG)>50) 
  {
  stepper.setSpeed(5*(Analog_X-Analog_X_AVG));    
  }
  else
  {
    stepper.setSpeed(0);
  }
}
void InitialValues()
{
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------  
  //read the analog 50x, then calculate an average. 
  //they will be the reference values
  for(int i = 0; i<50; i++)
  {
    tempX += analogRead(Analog_X_pin);  
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------  
  Analog_X_AVG = tempX/50; 
  //----------------------------------------------------------------------------  
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");  
}

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