Шаговый двигатель - концевой выключатель положения

Я следую этому руководству 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();
}

, 👍0

Обсуждение

Q1: я предполагаю, что это просто для того, чтобы немного отодвинуть ползунок от концевого выключателя, чтобы он больше не читал LOW. Q2 Я думаю, вы правы. В исходном проекте, на который вы ссылаетесь, есть рельс длиной всего около 80 см. И нет концевого выключателя на другом конце. Поэтому он использует программное обеспечение для ограничения хода. Альтернативой было бы добавить еще один концевой выключатель или просто изменить значение, чтобы оно отражало размер используемых вами рельс., @Gerben


1 ответ


Лучший ответ:

0

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
,