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");
}
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?
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.
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");
}