Запуск двух шаговых двигателей с двумя поворотными энкодерами
Я действительно плохо разбираюсь в этой части кодирования, используя два поворотных энкодера для управления двумя шаговыми двигателями [используя шаговый двигатель 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);
}
}
}
}
}
@Mike, 👍3
Обсуждение1 ответ
просто:
1) напишите набор процедур, которые управляют вашим сервомотором через прерывания: вам нужно будет указать время включения для каждого сервоканала.
2) напишите набор процедур, которые считывают поворотные положения.
3) напишите набор процедур, которые преобразуют положения вращения в параметр времени включения.
4) интегрируйте их все.
в вашем цикле вам просто нужно будет прочитать одну позицию поворота, преобразовать ее в время включения для этого канала и обновить параметр времени включения. Процедуры сервопривода будут выполняться в фоновом режиме прозрачно для вашего кода.
- Arduino Uno: avrdude: stk500_recv(): программатор не отвечает
- Программирование пользовательских Arduino Mega с Arduino Uno
- Arduino 1.6.4 не показывает никаких /tty/ опций в последовательных портах
- Использование библиотеки Arduino fix_fft или arduinoFFT для фильтрации определенного звука?
- Как сгенерировать файлы .a и .so для добавления в проект arduino
- Автономный ATMega328 — нужно ли прожигать загрузчик?
- Проблемы со скоростью шагового двигателя Nema 17
- Как работает Arduino IDE?
Добро пожаловать в Arduino SE. Обязательно сходите на экскурсию, чтобы посмотреть, как это работает и заработать значок: https://arduino.stackexchange.com/Tour, @SDsolar