I am using an Arduino 2560, NEMA23 Stepper motor with a TB6600 driver. The driver is set to 1/32 step division. The motor by default is 200 steps per revolution.
I want to input step size, number of steps and settling time. Once the loop completes the number of steps i want to return to the starting point. The plan is to take multiple images and stack them in Photoshop.
So far everything works except for the return to starting point ...some of the time. If I don't step too far, meaning a combination of step size and number of steps, the motor returns to the starting point. If I exceed "X" distance the last step continues to move forward instead of backwards. I haven't fully tested what "X" distance is.
Example: If I use 5 steps with a step size of 5000 then the code returns to the starting point. If I change the steps to 7 and keep the step size at 5000 it does not return but moves forward.
Here is the complete code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Stepper.h>
LiquidCrystal_I2C lcd(0x27,20,4);
//parameters for keypad
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] =
{
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {3,4,5,6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7,8,9,10}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
int j;
long stepSize=0;
long numSteps=0;
int settleTime=0;
int stepsPR=6400;
int DelayCamClose=10;
int DelayAfterCam=500;
int relayCam=A0; //pin to relay to trigger camera
Stepper focusStack(stepsPR, 13,12);
//get keypad entry
int GetNumber()
{
int num = 0;
char key = keypad.getKey();
while(key != '#')
{
switch (key)
{
case NO_KEY:
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
lcd.print(key);
num = num * 10 + (key - '0');
break;
case '*':
num = 0;
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
break;
}
key = keypad.getKey();
}
return num;
}
void setup()
{
lcd.init(); //initialize the lcd
lcd.backlight(); //open the backlight
pinMode(relayCam, OUTPUT);
digitalWrite (relayCam,HIGH);
}
void loop()
{
{
lcd.clear();
lcd.setCursor (0,0);
lcd.print("Set Settle Time");
lcd.setCursor (0,1);
settleTime = GetNumber();
}
{
lcd.clear();
lcd.setCursor (0,0);
lcd.print("Set Step Size");
lcd.setCursor (0,1);
stepSize = GetNumber();
}
{
lcd.clear();
lcd.setCursor (0,0);
lcd.print("Set Number Of Steps");
lcd.setCursor (0,1);
numSteps = GetNumber();
}
j=1;
while (j<=numSteps)
{
focusStack.step(stepSize);
delay(settleTime);
digitalWrite (relayCam,LOW); //opens the camera shutter
delay (DelayCamClose); //wait time to close camera shutter
digitalWrite (relayCam,HIGH); //close camera shutter
delay (DelayAfterCam);
j=j+1;
}
{
focusStack.step(-stepSize*numSteps); //returns to start
}
}
The issue is with the math in the last line bit I'm not sure what it is. I've tried setting
long stepSize=0;
long numSteps=0;
as int and float but that did not solve the problem. I also changed
focusStack.step(-stepSize*numSteps); //returns to start
to
focusStack.step(stepSize*numSteps); //returns to start
but that only reverses the problem, as expected it might.
I have also tried using the AccelStepper Library but that introduced a whole different set of issues.
Any help would be greatly appreciated. I am still fairly new to programming.
Found the problem. Since stepSize and numSteps are integers the math flips any result over 32767 (16 bit). Anything over 32767 results in an overflow and is converted to a negative.
I now just need to set the stepper microsteps to a value that will allow enough travel and stay under the 32767 limitation.