Шаговый двигатель - концевой выключатель положения
Я следую этому руководству https://howtomechatronics.com/tutorials/arduino/diy-motorized-camera-slider-pan-tilt-head-project/
Мой вопрос касается следующего фрагмента кода, используемого для калибровки значений положения.
// Переместить ползунок в начальное положение - возвращение в исходное положение
while (digitalRead(limitSwitch) != 0) {
stepper1.setSpeed(3000);
stepper1.runSpeed();
stepper1.setCurrentPosition(0); // При нажатии концевого выключателя устанавливаем положение на 0 шагов
}
delay(20);
// Переместиться на 200 шагов назад от концевого выключателя
while (stepper1.currentPosition() != -200) {
stepper1.setSpeed(-3000);
stepper1.run();
}
}
Я понимаю, что первый цикл while нужен для получения нулевой позиции для калибровки. Но зачем отодвигать его на 200 шагов назад, а затем устанавливать скорость на -3000?[Q1] Я не понимаю эту часть.
И затем позже в цикле() есть
// Ограничение движения - Ничего не делать, если нажат концевой выключатель или пройденное расстояние в другом направлении превышает 80 см
while (digitalRead(limitSwitch) == 0 || stepper1.currentPosition() < -64800) {}
Я понимаю первое условие, но почему там второе? Это потому, что 80 см — это максимальная длина слайдера/дорожки, и вы не хотите, чтобы шаговый двигатель двигался больше этого? [Q2] И как 64800 = 80 см? [Q3]
Полный код: [Не мой - по ссылке выше]
/*
DIY Camera Slider with Pan and Tilt Head
by Dejan Nedelkovski
www.HowToMechatronics.com
Library - AccelStepper by Mike McCauley:
http://www.airspayce.com/mikem/arduino/AccelStepper/index.html
*/
#include <AccelStepper.h>
#include <MultiStepper.h>
#define JoyX A0 // Joystick X pin
#define JoyY A1 // Joystick Y pin
#define slider A2 // Slider potentiometer
#define inOutPot A3 // In and Out speed potentiometer
#define JoySwitch 10 // Joystick switch connected
#define InOutSet 12 // Set Button
#define limitSwitch 11
#define inLED 8
#define outLED 9
// Define the stepper motors and the pins the will use
AccelStepper stepper1(1, 7, 6); // (Type:driver, STEP, DIR)
AccelStepper stepper2(1, 5, 4);
AccelStepper stepper3(1, 3, 2);
MultiStepper StepperControl; // Create instance of MultiStepper
long gotoposition[3]; // An array to store the In or Out position for each stepper motor
int JoyXPos = 0;
int JoyYPos = 0;
int sliderPos = 0;
int currentSpeed = 100;
int inOutSpeed = 100;
int XInPoint = 0;
int YInPoint = 0;
int ZInPoint = 0;
int XOutPoint = 0;
int YOutPoint = 0;
int ZOutPoint = 0;
int InandOut = 0;
void setup() {
// Set initial seed values for the steppers
stepper1.setMaxSpeed(3000);
stepper1.setSpeed(200);
stepper2.setMaxSpeed(3000);
stepper2.setSpeed(200);
stepper3.setMaxSpeed(3000);
stepper3.setSpeed(200);
pinMode(JoySwitch, INPUT_PULLUP);
pinMode(InOutSet, INPUT_PULLUP);
pinMode(limitSwitch, INPUT_PULLUP);
pinMode(inLED, OUTPUT);
pinMode(outLED, OUTPUT);
// Create instances for MultiStepper - Adding the 3 steppers to the StepperControl instance for multi control
StepperControl.addStepper(stepper1);
StepperControl.addStepper(stepper2);
StepperControl.addStepper(stepper3);
// Move the slider to the initial position - homing
while (digitalRead(limitSwitch) != 0) {
stepper1.setSpeed(3000);
stepper1.runSpeed();
stepper1.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
}
delay(20);
// Move 200 steps back from the limit switch
while (stepper1.currentPosition() != -200) {
stepper1.setSpeed(-3000);
stepper1.run();
}
}
void loop() {
// Limiting the movement - Do nothing if limit switch pressed or distance traveled in other direction greater then 80cm
while (digitalRead(limitSwitch) == 0 || stepper1.currentPosition() < -64800) {}
// If Joystick pressed increase the Pan and Tilt speeds
if (digitalRead(JoySwitch) == 0) {
currentSpeed = currentSpeed + 50;
delay(200);
}
// If Set button is pressed - toggle between the switch cases
if (digitalRead(InOutSet) == 0) {
delay(500);
// If we hold set button pressed longer then half a second, reset the in and out positions
if (digitalRead(InOutSet) == 0) {
InandOut = 4;
}
switch (InandOut) {
case 0: // Set IN position
InandOut = 1;
XInPoint = stepper1.currentPosition(); // Set the IN position for steppers 1
YInPoint = stepper2.currentPosition(); // Set the IN position for steppers 2
ZInPoint = stepper3.currentPosition(); // Set the IN position for steppers 3
digitalWrite(inLED, HIGH); // Light up inLed
break;
case 1: // Set OUT position
InandOut = 2;
XOutPoint = stepper1.currentPosition(); // Set the OUT Points for both steppers
YOutPoint = stepper2.currentPosition();
ZOutPoint = stepper3.currentPosition();
digitalWrite(outLED, HIGH);
break;
case 2: // Move to IN position / go to case 3
InandOut = 3;
inOutSpeed = analogRead(inOutPot); // Auto speed potentiometer
// Place the IN position into the Array
gotoposition[0] = XInPoint;
gotoposition[1] = YInPoint;
gotoposition[2] = ZInPoint;
stepper1.setMaxSpeed(inOutSpeed);
stepper2.setMaxSpeed(inOutSpeed);
stepper3.setMaxSpeed(inOutSpeed);
StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
StepperControl.runSpeedToPosition(); // Blocks until all steppers are in position
delay(200);
break;
case 3: // Move to OUT position / go back to case 2
InandOut = 2;
inOutSpeed = analogRead(inOutPot);
// Place the OUT position into the Array
gotoposition[0] = XOutPoint;
gotoposition[1] = YOutPoint;
gotoposition[2] = ZOutPoint;
stepper1.setMaxSpeed(inOutSpeed);
stepper2.setMaxSpeed(inOutSpeed);
stepper3.setMaxSpeed(inOutSpeed);
StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
StepperControl.runSpeedToPosition(); // Blocks until all are in position
delay(200);
break;
case 4: // If Set button is held longer then half a second go back to case 0
InandOut = 0;
digitalWrite(inLED, LOW);
digitalWrite(outLED, LOW);
delay(1000);
break;
}
}
// Joystick X - Pan movement
JoyXPos = analogRead(JoyX);
// if Joystick is moved left, move stepper 2 or pan to left
if (JoyXPos > 600) {
stepper2.setSpeed(currentSpeed);
}
// if Joystick is moved right, move stepper 2 or pan to right
else if (JoyXPos < 400) {
stepper2.setSpeed(-currentSpeed);
}
// if Joystick stays in middle, no movement
else {
stepper2.setSpeed(0);
}
//Joystick Y - Tilt movement
JoyYPos = analogRead(JoyY);
if (JoyYPos > 600) {
stepper3.setSpeed(currentSpeed);
}
else if (JoyYPos < 400) {
stepper3.setSpeed(-currentSpeed);
}
else {
stepper3.setSpeed(0);
}
// Slider potentiometer
sliderPos = analogRead(slider);
// If potentiometer is turned left, move slider left
if (sliderPos > 600) {
sliderPos = map(sliderPos, 600, 1024, 0, 3000);
stepper1.setSpeed(sliderPos); // Increase speed as turning
}
// If potentiometer is turned right, move slider right
else if (sliderPos < 400 ) {
sliderPos = map(sliderPos, 400, 0, 0, 3000);
stepper1.setSpeed(-sliderPos); // Increase speed as turning
}
// If potentiometer in middle, no movement
else {
stepper1.setSpeed(0);
}
// Execute the above commands - run the stepper motors
stepper1.runSpeed();
stepper2.runSpeed();
stepper3.runSpeed();
}
@AlfroJang80, 👍0
Обсуждение1 ответ
Лучший ответ:
Q1: Обычной практикой является перемещение шагового двигателя немного в сторону от предельного выключателя после калибровки, чтобы его можно было снова активировать, если шаговый двигатель будет перемещен в этом направлении. В большинстве случаев предельный выключатель отмечает точку, очень близкую или находящуюся на физическом пределе, где шаговый двигатель не может двигаться дальше и упрется в какую-то стену. Предельный выключатель может выключить двигатель до того, как это произойдет. И ваша причинно-следственная цепочка неверна. Код не переходит к -200 и ПОТОМ не устанавливает скорость на -3000. Вместо этого он проверяет в цикле while, достигнуто ли положение -200, и если нет, устанавливает скорость и запускает двигатель. Когда положение наконец достигается из-за работы двигателя, цикл while завершается.
Q2: 80 см используются как мягкий предел, что означает, что ползунок в этой точке не упрется в физический предел или концевой выключатель, только программное обеспечение останавливает ползунок, чтобы он пошел дальше и в конце концов уперся в стену. Это часто используется, чтобы сохранить концевые выключатели в физически ограниченной ситуации, а также не упираться ни в какие физические стены, поскольку сговор в основном нежелателен (из-за возможного вреда для людей и машины). 80 см известны здесь (потому что рельс для ползунка не длиннее этого).
Q3: Шаговый двигатель не считается по длине (см), а по количеству шагов, которые он сделал. В зависимости от используемого шагового двигателя, 1 шаг соответствует определенному углу, на который будет вращаться двигатель. И механика определяет, какой угол поворота соответствует какому расстоянию на рельсе. Скорее всего, автор руководства рассчитал это для своей конкретной сборки. Вы можете рассчитать это самостоятельно, чтобы использовать правильное преобразование из шагов в расстояние:
distance for 1 step = circumfence of the driving wheel / number of steps per revolution of the driving wheel
Или короче:
d1 = C / N
Затем вы можете рассчитать шаги для определенного расстояния d
по
Nd = d / d1
- Как я могу использовать степпер для определенной степени?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Шаговый двигатель не поворачивается/не поворачивается против часовой стрелки
- Шаговый двигатель с концевыми выключателями
- Запустить два степпера одновременно
- Попытка понять постоянную скорость AccelStepper
- Могу ли я запретить библиотеке Stepper удерживать двигатель?
- Как контролировать скорость шагового двигателя 28BYJ-48 без использования библиотеки?
Q1: я предполагаю, что это просто для того, чтобы немного отодвинуть ползунок от концевого выключателя, чтобы он больше не читал LOW. Q2 Я думаю, вы правы. В исходном проекте, на который вы ссылаетесь, есть рельс длиной всего около 80 см. И нет концевого выключателя на другом конце. Поэтому он использует программное обеспечение для ограничения хода. Альтернативой было бы добавить еще один концевой выключатель или просто изменить значение, чтобы оно отражало размер используемых вами рельс., @Gerben