如何让步进电机 return 到达起始位置?
How do I get a stepper motor to return to starting position?
我正在使用带 TB6600 驱动器的 Arduino 2560、NEMA23 步进电机。驱动程序设置为 1/32 步进。电机默认每转200步。
我要输入步长、步数和稳定时间。
一旦循环完成我想要 return 到起点的步数。
计划是拍摄多张图像并在 Photoshop 中堆叠它们。
到目前为止一切正常,除了 return 到起点......有时。
如果我不走得太远,这意味着步长和步数的组合,电机 returns 到起点。如果我超过“X”距离,最后一步将继续向前移动而不是向后移动。我还没有完全测试过什么是“X”距离。
示例:如果我使用步长为 5000 的 5 个步骤,则代码 returns 到起点。如果我将步长更改为 7 并将步长大小保持在 5000,它不会 return 而是向前移动。
完整代码如下:
#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
}
}
问题出在最后一行的数学运算上,我不确定它是什么。我试过设置
long stepSize=0;
long numSteps=0;
as int 和 float 但这并没有解决问题。
我也改了
focusStack.step(-stepSize*numSteps); //returns to start
到
focusStack.step(stepSize*numSteps); //returns to start
但这只会扭转问题,正如预期的那样。
我也尝试过使用 AccelStepper 库,但这引入了一系列完全不同的问题。
如有任何帮助,我们将不胜感激。我对编程还很陌生。
找到问题了。由于 stepSize 和 numSteps 是整数,因此数学会翻转超过 32767(16 位)的任何结果。任何超过 32767 的值都会导致溢出并转换为负值。
我现在只需要将步进器微步设置为允许足够行程并保持在 32767 限制以下的值。
我正在使用带 TB6600 驱动器的 Arduino 2560、NEMA23 步进电机。驱动程序设置为 1/32 步进。电机默认每转200步。
我要输入步长、步数和稳定时间。 一旦循环完成我想要 return 到起点的步数。 计划是拍摄多张图像并在 Photoshop 中堆叠它们。
到目前为止一切正常,除了 return 到起点......有时。 如果我不走得太远,这意味着步长和步数的组合,电机 returns 到起点。如果我超过“X”距离,最后一步将继续向前移动而不是向后移动。我还没有完全测试过什么是“X”距离。
示例:如果我使用步长为 5000 的 5 个步骤,则代码 returns 到起点。如果我将步长更改为 7 并将步长大小保持在 5000,它不会 return 而是向前移动。
完整代码如下:
#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
}
}
问题出在最后一行的数学运算上,我不确定它是什么。我试过设置
long stepSize=0;
long numSteps=0;
as int 和 float 但这并没有解决问题。 我也改了
focusStack.step(-stepSize*numSteps); //returns to start
到
focusStack.step(stepSize*numSteps); //returns to start
但这只会扭转问题,正如预期的那样。
我也尝试过使用 AccelStepper 库,但这引入了一系列完全不同的问题。
如有任何帮助,我们将不胜感激。我对编程还很陌生。
找到问题了。由于 stepSize 和 numSteps 是整数,因此数学会翻转超过 32767(16 位)的任何结果。任何超过 32767 的值都会导致溢出并转换为负值。
我现在只需要将步进器微步设置为允许足够行程并保持在 32767 限制以下的值。