Hello, I need help modifying implementing into this code a part that enables me to use 2 limit switches MAX-MIN, the idea behind it is that when the limit switch is activated MIN or MAX the stepper motor stops rotating in that direction, and only allows rotation in the opposite direction. It is for a motorized transformer variac project.
Option2-Implementing a home procedure and then limiting the maximum steps would be an option too.
#define encoder_pin_A 8
#define encoder_pin_B 9
int
encoder_pin_A_last = LOW;
int
encoder_pos = 0;
int
n = LOW;
#define stepper_pin_step 6
#define stepper_pin_dir 5
// Enc have 24 steps per revolution
// The motor have 800 steps per revolution
// Want: 1 encoder rev = 1 stepper rev
// 800 / 24 = 33.3333333333...
float
steps_per_pulse = 33.3333333333;
AccelStepper stepper(AccelStepper::DRIVER, stepper_pin_step, stepper_pin_dir);
void
setup() {
stepper.setMaxSpeed(800.0);
stepper.setAcceleration(300.0);
pinMode(encoder_pin_A, INPUT_PULLUP);
pinMode(encoder_pin_B, INPUT_PULLUP);
}
void
loop() {
// read encoder
n = digitalRead(encoder_pin_A);
if
((encoder_pin_A_last == LOW) && (n == HIGH)) {
if
(digitalRead(encoder_pin_B) == LOW) {
encoder_pos--;
}
else
{
encoder_pos++;
}
// set stepper to the new calculated position
stepper.moveTo((
long
) round(encoder_pos*steps_per_pulse));
}
encoder_pin_A_last = n;
stepper.run();
}
Why do you want to use a stepper motor if you control it with a rotary encoder? With a DC motor it's easy to restrict the movement by limit switches, without any special code required.
And with a stepper and one limit switch to home to it is easy to count steps and limit movement. No encoder required. Unless the motor misses steps which if designed right should not happen.
Implementing a home procedure and then limiting the maximum steps would be an option too. I really don't know how to implement it into this code if you could help me it would be nice.
I have a code that works on my setup. You can change the pin numbers and try it out and modify, adjust or use the parts that you want. I changed to the Encoder library for the rotary encoder as it does debounce and seems more consistent. The Encoder library is available through the IDE library manager.
The limit switch on my setup is a normally open (pulled high) reflective opto sensor that goes LOW when the motor is at home. A normally open mechanical switch or Hall effect switch should work with no changes.
#include <AccelStepper.h>
#include <Encoder.h>
const int MIN_LIMIT = 0;
const int MAX_LIMIT = 45;
const byte encoder_pin_A = 9;
const byte encoder_pin_B = 10;
const byte stepper_pin_step = 2;
const byte stepper_pin_dir = 5;
const byte limitSwPin = 11;
// Enc have 24 steps per revolution
// The motor have 800 steps per revolution
// Want: 1 encoder rev = 1 stepper rev
// 800 / 24 = 33.3333333333...
float steps_per_pulse = 33.3333333333;
bool isHomed = false;
AccelStepper stepper(AccelStepper::DRIVER, stepper_pin_step, stepper_pin_dir);
Encoder myEnc(encoder_pin_A, encoder_pin_B);
long oldPosition = -999;
int divisor = 4; // divide by divisor to get one count/click on encoder
void setup()
{
Serial.begin(115200);
stepper.setMaxSpeed(2000.0);
stepper.setAcceleration(1000.0);
pinMode(limitSwPin, INPUT_PULLUP);
delay(10);
home();
Serial.println("homed");
}
void loop()
{
if (isHomed)
{
long newPosition = myEnc.read() / divisor; // divide by divisor to get one count/click
// bound checking
if (newPosition >= MAX_LIMIT)
{
newPosition = MAX_LIMIT;
myEnc.write(MAX_LIMIT * divisor);
}
if (newPosition < MIN_LIMIT)
{
newPosition = MIN_LIMIT;
myEnc.write(MIN_LIMIT);
}
if (newPosition != oldPosition)
{
Serial.print("pos = ");
Serial.println(newPosition);
// set stepper to the new calculated position
stepper.moveTo(newPosition * steps_per_pulse);
oldPosition = newPosition;
}
stepper.run();
}
}
void home()
{
while (digitalRead(limitSwPin))
{
stepper.move(-5);
stepper.runSpeedToPosition();
}
isHomed = true;
stepper.setCurrentPosition(0); // homed
myEnc.write(0);
}
If you have questions or concerns, don't hesitate to ask. I should be here most of the day.
Thank you very much this is simply wizardry for me, When the project progresses I would add some additional functionality. I will contact you in the future.
The code will work with any active low switch. Could be a mechanical micro switch, a reed switch, a Hall effect switch or optical switch. As long as it reads HIGH when open and LOW when closed.
I am talking about an additional switch that has a function to home the motor to MIN_LIMIT.
But I don't know how to update the (pos = to 0) after the motor is homed.
I do not see that on my setup. Once it hits 100 it just sits there as I turn the encoder knob. Try putting a 0.1uF cap each from the A terminal and the B terminal of the encoder to ground.