I would like some assistant on how I could code my program to be able to count the number of steps the motor takes between two limit switches. Any help or advice would be appreciated.
Below is what I have coded so far (from various examples online). I have managed to rotate the stepper clockwise and counter clockwise when a limit switch is triggered. How do I add a function that counts the number of steps the motor takes.
#include <AccelStepper.h>
const int dirPin = 8;
const int stepPin = 9;
const int enPin = 20;
const int limit1 = A11;// left limit
const int limit2 = A12;// right limit
void setup() {
// Set up stepper motor
Serial.begin(9600);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enPin, OUTPUT);
digitalWrite(enPin, LOW);
//Set up 2 limit switch
pinMode(limit1 , INPUT_PULLUP);
pinMode(limit2 , INPUT_PULLUP);
}
void loop() {
digitalWrite(dirPin, LOW); // setup motor turn left first
do {
digitalWrite(stepPin , HIGH);
delayMicroseconds(500);
digitalWrite(stepPin , LOW);
delayMicroseconds(500);
} while (digitalRead(limit1) == HIGH); // motor turn left until touch limit 1 handle
delay(500);
digitalWrite(dirPin, HIGH);// motor turn right after limit1 powered ( touch limit1 handle).
do {
digitalWrite(stepPin , HIGH);
delayMicroseconds(500);
digitalWrite(stepPin , LOW);
delayMicroseconds(500);
} while (digitalRead(limit2) == HIGH);// motor turn right until touch limit 2 handle
delay(500);
digitalWrite(dirPin, LOW);// motor turn left after touch limit 2 handle
}
Well, since your code is stepping each step, why not add a counter in the while...do loops?
Be aware, the first direction of movement is probably starting mid-range, so you really just want to count the steps in the second direction, where it's going from limit to limit.
C
I've got it working now thank you. But my motor spins very slowly while it is counting the steps. Is this normal? i.e. going from limit switch 1 to 2 is very slow but from 2 to 1 it spins fast.
#include <AccelStepper.h>
const int dirPin = 9;
const int stepPin = 8;
const int enPin = 10;
const int motorInterfaceType = 1;
const int limit1 = A14;// left limit
const int limit2 = A15;// right limit
long int counter = 0;
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
void setup() {
Serial.begin(9600);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enPin, OUTPUT);
digitalWrite(enPin, LOW);
pinMode(limit1 , INPUT_PULLUP);
pinMode(limit2 , INPUT_PULLUP);
stepper.setMaxSpeed(1000); // set the maximum speed
stepper.setAcceleration(100000); // set acceleration
}
void loop() {
do {
stepper.moveTo(8000);
stepper.run();
}
while (digitalRead(limit1) == HIGH); // motor turn left until touch limit 1 handle
delay(500);
do {
Serial.println(counter);
counter++;
stepper.moveTo(-8000);
stepper.run();
}
especially if you use a low baudrate like 9600 sending data to the serial interface is slow.
steppermotors need a very tight timimg.
accelstepper needs to call stepper.run() at a higher frequency than each single step occurs.
If it is really important that you print the number of steps for each and every iteration of your while-loop you must increase the baudrate.
If it is sufficient to know the number of steps between the limitswitches move the serial.print behind the while-loop.
If you want to do things in parallel to the step-pulse-creation you could use the MObaTools-library which does the step-pulse-creation in the backround
without any context this posting is useless.
You can mark text in postings and then simply click on the quote-button that appears to have the context putted in quickly
Hi I tried to implement your code to my sketch but to rotate the direction of the motor I need to manually hold the limit switch closed. I am not sure why this is the case. I want it to be done automatically as soon as there is a contact on the limit switch.
#include <AccelStepper.h>
const int dirPin = 9;
const int stepPin = 8;
const int enPin = 10;
const int motorInterfaceType = 1;
const int limit1 = A1;// left limit
const int limit2 = A2;// right limit
long int counter = 0;
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
void setup() {
Serial.begin(74880);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enPin, OUTPUT);
digitalWrite(enPin, LOW);
pinMode(limit1 , INPUT_PULLUP);
pinMode(limit2 , INPUT_PULLUP);
stepper.setMaxSpeed(1000); // set the maximum speed
stepper.setAcceleration(100000); // set acceleration
}
void loop() {
stepper.moveTo(8000); // motor turn left until touch limit 1 handle
while (digitalRead(limit1) == HIGH) stepper.run();
delay(500);
stepper.moveTo(-8000); // motor turn right after limit1 powered ( touch limit1 handle).
while (digitalRead(limit1) == LOW)
{
stepper.run();
if (counter++ % 10 == 0) Serial.println(counter); // starts counting steps from limit switch 1 to 2
}
while (digitalRead(limit2) == HIGH);// motor turn right until touch limit 2 handle
delay(500);
stepper.moveTo(counter/2); // move motor to half the number of steps it calculated
}
I tired increasing the baudrate and it does help the motor rotate faster. Thank you for the tip. I implemented a new code as shown above but now the motor will only move if limit switch 1 is held closed.
I'm pretty sure that is how the code you posted prior to my example would also work. You should try to make a state machine where the switches changes the state.
while (digitalRead(limit2) == HIGH);// motor turn right until touch limit 2 handle
delay(500);
stepper.moveTo(counter/2); // move motor to half the number of steps it calculated
This will not do what you expect, it will lock until "limit2" goes LOW, wait ½ second and start a "moveTo" which is not performed due to the lack of "run()" statements..
int target = 8000, last_target = 0;
unsigned int counter = 0;
void loop()
{
if (digitalRead(limit1) == LOW)
{
delay(50); //Debounce
target = (target == 8000) ? -8000 : 8000;
}
if (digitalRead(limit2) == LOW)
{
delay(50); //Debounce
target = counter / 2;
}
if (target != last_target)
{
last_target = target;
counter = 0;
stepper.moveTo(target);
}
if (stepper.run())
{
if (++counter % 10 == 0) Serial.println(counter);
}
}
Hello. Thank you very much for your example. I have got the limit switches and motor working as intended. Sorry I am quiet new to coding so I am unsure on the code what this part does (see below). Say I want the motor to stop at the centre of the number of steps it calculated between limit switches 1 and 2 (like a homing position). I tried to do stepper.moveTo(counter/2); but it continues beyond the half way point.
From this small code-snippet it is impossible to say why it might not work
always post your complete sketch
You can post code by using this method that adds the code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps
press Ctrl-T for autoformatting your code
do a rightclick with the mouse and choose "copy for forum"
#include <AccelStepper.h>
const int dirPin = 9;
const int stepPin = 8;
const int enPin = 10;
const int motorInterfaceType = 1;
const int limit1 = A1;// left limit
const int limit2 = A2;// right limit
int target = 8000, last_target = 0;
unsigned int counter = 0;
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
void setup() {
Serial.begin(9600);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(enPin, OUTPUT);
digitalWrite(enPin, LOW);
pinMode(limit1 , INPUT_PULLUP);
pinMode(limit2 , INPUT_PULLUP);
stepper.setMaxSpeed(1000); // set the maximum speed
stepper.setAcceleration(100000); // set acceleration
}
void loop() {
do {
stepper.moveTo(8000);// motor turn left until it touches limit 1 handle
stepper.run();
} while (digitalRead(limit1) == HIGH); // limit 1 is activated
delay(500); //delay
do {
stepper.moveTo(-8000);// motor turn right
stepper.run(); // motor moves right
counter++; // starts counting number of steps from limit 1 to limit 2
} while (digitalRead(limit2) == HIGH);// touches limit 2
delay(500);
do {
target = counter; // finds value of half total count recorded
stepper.moveTo(target);// motor turn left and moves to target count
stepper.run();
} while (digitalRead(limit2) == HIGH);
}
What I mainly want to do is get a 0 position for my motor between the two limit switches.