Hi There,
I'm trying to make a stepper motor driven system that will run back and forth along a rail between two limit switches. Here is the current code.
The problem I am having is that the motor will run only if a limit switch is pressed. It will run in the opposite direction to the limit switch, which is good, but it will only run if the limit switch is held down.
Is there a way for changing it to do this?
Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Can you post some images of your project?
So we can see your component layout.
Limit switches are defined as buttonA (pin 6) and buttonB (pin 7).
Reading them is done through void readButtonA() and sets up the boolean variables buttonAPressed and buttonBPressed, changing them from "false" to "true" when the digitalRead from their respective pins is LOW.
The idea is that when buttonAPressed is "true" and buttonBPressed is "false" then the carriage will move away from button A, and vice versa. However, the problem is that the carriage only moves when the button is held down, while I need it to move constantly, with the buttons only changing it's direction.
Hi,
You need to detect the activation or change of state of the limit switch, not the continuous state of the switch.
This is because the limit will only be activated briefly when the carriage hits it then reverses direction.
Can I also suggest;
Instead of buttonA, buttonAPressed etc.
You use;
LimitAPin , LimitAPressed etc.
This makes reading your code self explanatory.
Tom...
PS. Going back to bed mate, 4:30am here, only awake because of hayfever.
You might consider a simple state machine handling moving either CW or CCW, and switching to the other direction based on the states of the switches.
Here's a modification of the library's example sketch to use a state variable to change directions:
/*
Stepper Motor Control - one revolution
This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.
The motor should revolve one revolution in one direction, then
one revolution in the other direction.
Created 11 Mar. 2007
Modified 30 Nov. 2009
by Tom Igoe
Modified to use a simple two-state state machine for
https://forum.arduino.cc/t/stepper-motor-not-running-continuously/1283598
*/
#include <Stepper.h>
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// for your motor
// initialize the Stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
int movingCW = true;
void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(60);
// initialize the serial port:
Serial.begin(9600);
}
void loop() {
if (movingCW) {
// step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
movingCW = false;
} else {
// step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
movingCW = true;
}
// delay(500);
}
You could adapt this to your purposes with a couple changes:
If instead of the unconditional change of the state variable movingCW at the end of each revolution, you could make the change dependent on the particular limit switch that should change directions.
It would also allow you to more rapidly respond to the activating the limit switch by turning less than a full turn between checking the switch. (e.g., myStepper.step(100);)
The stepper being crap might also explain why it gets extremely hot while running, although that might be because that AC/DC converter was designed to power something bigger. Going to try the code snippet now
The supply is somewhere in the region of 12V (I think?), and the mechanical system is not exactly optimal. At 5RPM it didn't move, just made a horrible grinding noise.
Ok, this is my absolutely awful shot at implementing it.
/*
Stepper Motor Control - one revolution
This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.
The motor should revolve one revolution in one direction, then
one revolution in the other direction.
Created 11 Mar. 2007
Modified 30 Nov. 2009
by Tom Igoe
Modified to use a simple two-state state machine for
https://forum.arduino.cc/t/stepper-motor-not-running-continuously/1283598
*/
#include <Stepper.h>
const int stepsPerRevolution = 2038; // change this to fit the number of steps per revolution
// for your motor
// initialize the Stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
byte buttonA = 6;
byte buttonB = 7;
int movingCW = true;
boolean buttonAPressed = false;
boolean buttonBPressed = false;
void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(20);
// initialize the serial port:
Serial.begin(9600);
}
void loop() {
buttonAPressed = false;
buttonBPressed = false;
if (digitalRead(buttonA) == LOW) {
buttonAPressed = true;
}
if (digitalRead(buttonB) == LOW) {
buttonBPressed = true;
}
if(buttonAPressed == true){
movingCW = false;
}
if (movingCW = true) {
// step one revolution in one direction:
Serial.println("clockwise");
myStepper.step(stepsPerRevolution);
movingCW = false;
} else if (movingCW = false){
// step one revolution in the other direction:
Serial.println("counterclockwise");
myStepper.step(-stepsPerRevolution);
movingCW = true;
}
// delay(500);
}
/*
Stepper Motor Control - Bounce Between Limit Switches
https://wokwi.com/projects/403962641012999169
This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.
The motor should revolve one revolution in one direction, then
one revolution in the other direction.
Created 11 Mar. 2007
Modified 30 Nov. 2009
by Tom Igoe
Modified to use a simple two-state state machine for
https://forum.arduino.cc/t/stepper-motor-not-running-continuously/1283598
*/
#include <Stepper.h>
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// for your motor
// initialize the Stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
int movingCW = true;
void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(60);
// initialize the serial port:
Serial.begin(9600);
pinMode(A0, INPUT_PULLUP);
pinMode(A1, INPUT_PULLUP);
}
void loop() {
if (movingCW) {
// step one revolution in one direction:
myStepper.step(stepsPerRevolution/100);
if (digitalRead(A0) == LOW) {
movingCW = false;
Serial.println("counterclockwise");
}
} else {
// step one revolution in the other direction:
myStepper.step(-stepsPerRevolution/100);
if (digitalRead(A1) == LOW) {
movingCW = true;
Serial.println("clockwise");
}
}
// delay(500);
}
DaveX the utter legend!
Thanks for all your help, here's the final code.
/*
Stepper Motor Control - Bounce Between Limit Switches
https://wokwi.com/projects/403962641012999169
This program drives a unipolar or bipolar stepper motor.
The motor is attached to digital pins 8 - 11 of the Arduino.
The motor should revolve one revolution in one direction, then
one revolution in the other direction.
Created 11 Mar. 2007
Modified 30 Nov. 2009
by Tom Igoe
Modified to use a simple two-state state machine for
https://forum.arduino.cc/t/stepper-motor-not-running-continuously/1283598
*/
#include <Stepper.h>
const int stepsPerRevolution = 2038; // change this to fit the number of steps per revolution
// for your motor
// initialize the Stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);
int movingCW = true;
void setup() {
// set the speed at 60 rpm:
myStepper.setSpeed(20);
// initialize the serial port:
Serial.begin(9600);
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
}
void loop() {
if (movingCW) {
// step one revolution in one direction:
myStepper.step(stepsPerRevolution/100);
if (digitalRead(6) == LOW) {
movingCW = false;
Serial.println("counterclockwise");
}
} else {
// step one revolution in the other direction:
myStepper.step(-stepsPerRevolution/100);
if (digitalRead(7) == LOW) {
movingCW = true;
Serial.println("clockwise");
}
}
// delay(500);
}
Thanks. It is a very simple state machine, and if one was writing it from scratch, rather than adapting the library example, one might do several things differently.
For one -- allow for more states with an enum and a switch-case. For example, if you wanted to have an STOP state, you could rename "movingCW" to "moveState" and expand the choices as needed.