Hello,
I am trying to accomplish the following:
I have a toggle switch, a stepper motor, and a hollow shaft potentiometer that sits on the motor shaft. When the state of the toggle switch changes (e.g. switched from one side to the other), I would like the stepper to move to one of two specific positions, call them "open" and "closed". To move to the open position from the closed position, the motor has to turn CCW and in order to move from the closed position to the open position, the motor has to turn CW.
Here is the picture of my setup:
I am using an Arduino Mega, an A4988 driver, and a NEMA17 stepper motor. I have not included the connections for the motor, the toggle switch, or a blue LED with a resistor that I have connected in the picture because I was afraid it would make it too difficult to see the other connections. The blue LED with a resistor is connected in parallel with the motor power supply, just to make sure I'm actually getting power. The toggle switch is connected to pin 28 and a ground pin.
Initially, I wrote code for this with delays, for example:
void setup() {
// Sets the two pins as Outputs
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
}
void loop() {
digitalWrite(dirPin, HIGH); // Enables the motor to move in a particular direction
// Makes 200 pulses for making one full cycle rotation
for(int x = 0; x < 800; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(700); // by changing this time delay between the steps we can change the rotation speed
digitalWrite(stepPin,LOW);
delayMicroseconds(700);
}
delay(1000); // One second delay
digitalWrite(dirPin,LOW); //Changes the rotations direction
// Makes 400 pulses for making two full cycle rotation
for(int x = 0; x < 1600; x++) {
digitalWrite(stepPin,HIGH);
delayMicroseconds(500);
digitalWrite(stepPin,LOW);
delayMicroseconds(500);
}
delay(1000);
}
However, my motor would stutter when the program started and I read online that using delays and while loops can sometimes cause this, since it stops the Arduino from doing anything else while those are happening. I got rid of the delays and tested it with just the motor stepping, like this:
byte stepPin = 3;
byte dirPin = 2;
bool nextStep = HIGH;
int stepDelay = 700;
unsigned long currentMicros;
unsigned long stepMicros;
void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
digitalWrite(dirPin, HIGH);
currentMicros = micros();
if (currentMicros - stepMicros >= stepDelay)
{
nextStep = !nextStep;//swap next step state
digitalWrite(stepPin, nextStep);
stepMicros = currentMicros;
}
}
This got rid of the stuttering. When I started testing with the potentiometer, I kept the while loop because I was ok with the Arduino stopping anything else during the while loop. Here is my first test code with the potentiometer:
int potPin = A3;
byte stepPin = 3;
byte dirPin = 2;
bool nextStep = LOW;
int stepDelay = 500;
unsigned long currentMicros;
unsigned long stepMicros;
void setup() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
digitalWrite(dirPin, HIGH);
while(analogRead(potPin) < 500)
{
currentMicros = micros();
if (currentMicros - stepMicros >= stepDelay)
{
nextStep = !nextStep;//swap next step state
digitalWrite(stepPin, nextStep);
stepMicros = currentMicros;
}
}
}
When I do this, the motor works perfectly, no stuttering. However, when I went in and added the toggle switch, it stutters at the beginning. After the motor is done stuttering, the toggle and the motor work fine.
Here is my code with the toggle added:
#include <DebouncedSwitch.h>
//Potentiometer Constants
const int potPin = A3;
const byte potValOpen = 0;
const byte potValClosed = 700;
const byte potTolerance = 10;
//Motor Constants
const byte dirPin = 2;
const byte stepPin = 3;
//Toggle Constant
const byte toggleShutter1Pin = 28;
//Variables
bool nextStep = LOW;
int stepDelay = 500;
unsigned long currentMicros;
unsigned long stepMicros;
DebouncedSwitch toggle1(toggleShutter1Pin);
void setup() {
//Serial.begin(9600);
pinMode(toggleShutter1Pin, INPUT_PULLUP);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
void loop() {
toggle1.update();
//IF toggle is switched from OPEN -> CLOSE or CLOSE -> OPEN
if(toggle1.isChanged())
{
//IF toggle is switched to OPEN
if(toggle1.isDown())
{
digitalWrite(dirPin, HIGH);
while(!(analogRead(potPin) <= potValOpen + potTolerance and analogRead(potPin) >= potValOpen - potTolerance))
{
stepMotor();
}
}
else
{
digitalWrite(dirPin, LOW);
while(!(analogRead(potPin) <= potValClosed + potTolerance && analogRead(potPin) >= potValClosed - potTolerance))
{
stepMotor();
}
}
}
}
void stepMotor()
{
currentMicros = micros();
if (currentMicros - stepMicros >= stepDelay)
{
nextStep = !nextStep;//swap next step state
digitalWrite(stepPin, nextStep);
stepMicros = currentMicros;
}
}
I have tried double checking the motor connections, and checking my driver, but they seem to be working and connected correctly. I'm guessing it's something with my code, since the motor works perfectly with the test program I used when I first connected the potentiometer (see above), but I'm not really sure where to go from here.
Any help would be appreciated! Thanks!