Запуск двух шаговых двигателей с двумя поворотными энкодерами

Я действительно плохо разбираюсь в этой части кодирования, используя два поворотных энкодера для управления двумя шаговыми двигателями [используя шаговый двигатель 28BYJ-48 с платой ULN2003]. Этот код отлично работает с помощью одного поворотного энкодера для одного шагового двигателя с помощью этого выключенного brainy-bits.com:

https://brainy-bits.com/blogs/tutorials/stepper-motor-rotary-encoder-p1

Когда я немного изменяю код для двух энкодеров и двух шаговых двигателей, я использую это: Однако я не получаю ожидаемых результатов. Два мотора просто не реагируют.

#include "Stepper.h"
#define STEPS 32   // Number of steps for one revolution of Internal shaft
// 2048 steps for one revolution of External shaft

volatile boolean TurnDetected; // need volatile for Interrupts
volatile boolean rotationdirection; // Вращение CW или CCW

const int PinCLK = 2; // Генерация прерываний с использованием сигнала CLK
const int PinDT = 3; // Чтение сигнала DT
const int PinSW = 4; // Чтение кнопочного переключателя
const int PinCLK2 = 46;
const int PinDT2 = 47;
const int PinSW2 = 48;

int RotaryPosition = 0;  // Для хранения Положения шагового двигателя
int RotaryPosition2 = 0;

int PrevPosition;     // Предыдущее значение положения вращения для проверки точности
int PrevPosition2;
int StepsToTake;      // Сколько нужно переместить Stepper
int StepsToTake2;

// Настройка правильной последовательности выводов драйвера двигателя
// In1, In2, In3, In4 в последовательности 1-3-2-4
Stepper small_stepper(STEPS, 8, 10, 9, 11);
Stepper small_stepper2(STEPS, 40, 41, 42, 43);


// Процедура прерывания выполняется, если CLK переходит от ВЫСОКОГО к НИЗКОМУ
void isr () {
  delay(4);  // delay for Debouncing
  if (digitalRead(PinCLK))
    rotationdirection = digitalRead(PinDT);
  else
    rotationdirection = !digitalRead(PinDT);
  TurnDetected = true;
  /////I added this
  delay(4);  // delay for Debouncing
  if (digitalRead(PinCLK2))
    rotationdirection = digitalRead(PinDT2);
  else
    rotationdirection = !digitalRead(PinDT2);
  TurnDetected = true;
}
/////up to here


void setup () {
  pinMode(PinCLK, INPUT);
  pinMode(PinDT, INPUT);
  pinMode(PinSW, INPUT);
  digitalWrite(PinSW, HIGH); // Подтягивающий резистор для переключателя
  attachInterrupt (0, isr, FALLING); / прерывание 0 всегда подключено к контакту 2 на Arduino UNO
  pinMode(PinCLK2, INPUT);
  pinMode(PinDT2, INPUT);
  pinMode(PinSW2, INPUT);
  digitalWrite(PinSW2, HIGH); // Подтягивающий резистор для переключателя
  attachInterrupt (0, isr, FALLING); // прерывание 0 всегда подключено к контакту 2 на Arduino UNO
}

void loop () {
  small_stepper.setSpeed(600); //Max seems to be 700
  if (!(digitalRead(PinSW))) {   // проверьте, нажата ли кнопка
    if (RotaryPosition == 0) {  // check if button was already pressed
    } else {
      small_stepper.step(-(RotaryPosition * 50));
      RotaryPosition = 0; // Сброс положения в НОЛЬ
    }
  }

  // Runs if rotation was detected
  if (TurnDetected) {
    PrevPosition = RotaryPosition; // Сохранить предыдущую позицию в переменной
    if (rotationdirection) {
      RotaryPosition = RotaryPosition - 1;
    } // decrase Position by 1
    else {
      RotaryPosition = RotaryPosition + 1;
    } // increase Position by 1

    TurnDetected = false;   // не повторяйте цикл IF до тех пор, пока не будет обнаружено новое вращение

    // Which direction to move Stepper motor
    if ((PrevPosition + 1) == RotaryPosition) { // Move motor CW
      StepsToTake = 50;
      small_stepper.step(StepsToTake);
    }

    if ((RotaryPosition + 1) == PrevPosition) { // Move motor CCW
      StepsToTake = -50;
      small_stepper.step(StepsToTake);
      small_stepper2.setSpeed(600); //Max seems to be 700
      if (!(digitalRead(PinSW2))) {   // check if button is pressed
        if (RotaryPosition2 == 0) {  // check if button was already pressed
        } else {
          small_stepper2.step(-(RotaryPosition * 50));
          RotaryPosition2 = 0; // Reset position to ZERO
        }
      }

      // Runs if rotation was detected
      if (TurnDetected)
      {
        PrevPosition2 = RotaryPosition2; // Save previous position in variable
        if (rotationdirection) {
          RotaryPosition2 = RotaryPosition2 - 1;
        } // decrase Position by 1
        else {
          RotaryPosition2 = RotaryPosition2 + 1;
        } // increase Position by 1

        TurnDetected = false;  // do NOT repeat IF loop until new rotation detected

        // Which direction to move Stepper motor
        if ((PrevPosition2 + 1) == RotaryPosition2) { // Move motor CW
          StepsToTake = 50;
          small_stepper2.step(StepsToTake);
        }

        if ((RotaryPosition2 + 1) == PrevPosition2) { // Move motor CCW
          StepsToTake = -50;
          small_stepper2.step(StepsToTake);
        }
      }
    }
  }
}

, 👍3

Обсуждение

Добро пожаловать в Arduino SE. Обязательно сходите на экскурсию, чтобы посмотреть, как это работает и заработать значок: https://arduino.stackexchange.com/Tour, @SDsolar


1 ответ


-1

просто:

1) напишите набор процедур, которые управляют вашим сервомотором через прерывания: вам нужно будет указать время включения для каждого сервоканала.

2) напишите набор процедур, которые считывают поворотные положения.

3) напишите набор процедур, которые преобразуют положения вращения в параметр времени включения.

4) интегрируйте их все.

в вашем цикле вам просто нужно будет прочитать одну позицию поворота, преобразовать ее в время включения для этого канала и обновить параметр времени включения. Процедуры сервопривода будут выполняться в фоновом режиме прозрачно для вашего кода.

,