Как управлять двумя шаговыми двигателями и использовать ультразвуковой датчик вместе?
Я работаю над автономным роботом с двумя 4-контактными шаговыми двигателями, ультразвуковым датчиком HC-SR04, двумя драйверами двигателей L298N (по одному на каждый двигатель) и Arduino Uno. Моя проблема в том, что когда я использую шаговые двигатели с библиотекой Stepper, одновременно работает только один двигатель. Мое решение заключалось в том, чтобы контролировать шаг за шагом в течение короткого периода времени, что сработало, однако это создает новую проблему. Ультразвуковой датчик требует задержки для работы, но это делает движение робота довольно медленным и дерганым, поскольку он работает только по одному шагу за раз. Когда я убираю задержку с ультразвукового датчика, он начинает возвращать правильное значение, но также возвращает 0 сразу после каждого правильного значения. Мое решение состояло в том, чтобы игнорировать возвращенный 0, но это не идеально.
Как я могу одновременно использовать два шаговых двигателя и использовать ультразвуковой датчик?
Вот мой код:
#include <Stepper.h>
#include <Ultrasonic.h>
/*
* Передать в качестве параметра вывод триггера и эха соответственно,
* или только сигнальный контакт (для датчиков 3 контакта), например:
* Ультразвуковой ультразвуковой(13);
*/
Ultrasonic ultrasonic(13, 12);
int distance;
int driveSpeed = 100;
int stepsPerRevolution = 200;
int leftMotorStep = 0;
int rightMotorStep = 0;
// Интервал времени между шагами для обоих моторов
const int stepInterval = 10; // При необходимости отрегулируйте
// Время последнего шага для каждого двигателя
unsigned long leftMotorLastStepTime = 0;
unsigned long rightMotorLastStepTime = 0;
Stepper rightMotor(stepsPerRevolution, 8, 9, 10, 11);
Stepper leftMotor(stepsPerRevolution, 4, 5, 6, 7);
void setup() {
Serial.begin(9600);
rightMotor.setSpeed(driveSpeed);
leftMotor.setSpeed(driveSpeed);
}
void loop() {
distance = ultrasonic.read();
Serial.print("Distance in CM: ");
Serial.println(distance);
delay(250); //Эта задержка заставляет моторы вести себя странно
if (distance < 15) {
Serial.println("AVOIDING OBSTACLE!");
// Выполнение действий по избеганию препятствий
avoidObstacle();
} else if (distance < 30) {
Serial.println("APPROACHING OBSTACLE!");
// Выполняем медленное приближение
slowApproach();
} else {
Serial.println("DRIVING!");
// Делаем обычное поведение вождения
drive();
}
}
void avoidObstacle() {
// Остановить робота
halt();
// Поворачиваем робота, чтобы избежать препятствия
leftM();
// Задержка для завершения вращения
delay(1000);
}
void slowApproach() {
// Замедлить моторы
int slowSpeed = 50;
rightMotor.setSpeed(slowSpeed);
leftMotor.setSpeed(slowSpeed);
// Медленно двигаем робота вперед
forwardM();
// Задержка для медленного подхода
delay(1000);
}
void drive() {
// Возвращаем моторы к нормальной скорости
rightMotor.setSpeed(driveSpeed);
leftMotor.setSpeed(driveSpeed);
// Двигаем робота вперед
forwardM();
}
void forwardM() {
rightMotor.step(1);
leftMotor.step(1);
}
void leftM() {
rightMotor.step(1);
leftMotor.step(-1);
}
void rightM() {
rightMotor.step(-1);
leftMotor.step(1);
}
void reverseM() {
rightMotor.step(-1);
leftMotor.step(-1);
}
void halt() {
rightMotor.step(0);
leftMotor.step(0);
}
@Renier Jr., 👍1
Обсуждение1 ответ
Лучший ответ:
Попробуйте этот код.
Вот симуляция. https://wokwi.com/projects/366108641014000641
Нажмите на датчик, чтобы установить расстояние в моделировании
ПРИМЕЧАНИЕ: сантиметры — это cm
, а не CM
.
Не тестировалось на оборудовании.
// https://arduino.stackexchange.com/questions/93302/how-to-drive-two-stepper-motors-and-use-an-ultrasonic-sensor-together
#include <Stepper.h>
#include <Ultrasonic.h>
/*
* Передать в качестве параметра вывод триггера и эха соответственно,
* или только сигнальный контакт (для датчиков 3 контакта), например:
* Ультразвуковой ультразвуковой(13);
*/
Ultrasonic ultrasonic(13, 12);
int distance;
int slowSpeed = 100;
int driveSpeed = 1000;
int stepsPerRevolution = 100;
int leftMotorStep = 0; // текущая скорость и направление шага
int rightMotorStep = 0;
int stepSpeed = 10; // это скорость двигателя
const int stepInterval = 1; // Интервал времени между шагами для обоих моторов
unsigned long leftMotorLastStepTime = 0; // Время последнего шага для каждого двигателя
unsigned long rightMotorLastStepTime = 0;
Stepper rightMotor(stepsPerRevolution, 8, 9, 10, 11);
Stepper leftMotor (stepsPerRevolution, 4, 5, 6, 7);
void setup() {
Serial.begin(9600);
rightMotor.setSpeed(1);
leftMotor. setSpeed(1);
}
void loop() {
distance = ultrasonic.read();
Serial.print("Distance in cm: ");
Serial.print(distance); Serial.print("\t");
switch (distance) { // используется switch/case для более чистого кода
case 0 ... 14:
Serial.println("avoid");
avoidObstacle(); // Выполнение действий по избеганию препятствий
break;
case 15 ... 29:
Serial.println("approach");
slowApproach(); // Выполняем медленное приближение
break;
default:
Serial.println("drive");
drive(); // Делаем обычное поведение вождения
break;
}
rightMotor.step(rightMotorStep); // это на самом деле приводит в движение моторы
leftMotor .step(leftMotorStep);
}
void avoidObstacle() {
halt(); // Остановить робота
leftM(); // Поворачиваем робота, чтобы избежать препятствия
}
void slowApproach() {
rightMotor.setSpeed(slowSpeed); // Замедлить моторы
leftMotor. setSpeed(slowSpeed);
forwardM(); // Медленно двигаем робота вперед
}
void drive() {
rightMotor.setSpeed(driveSpeed); // Возвращаем моторы к нормальной скорости
leftMotor. setSpeed(driveSpeed);
forwardM(); // Двигаем робота вперед
}
void forwardM() {
rightMotorStep = stepSpeed; // выбираем только направление шага
leftMotorStep = stepSpeed; // не двигать двигатель
} // фактическое пошаговое выполнение выполняется в конце цикла()
void leftM() {
rightMotorStep = stepSpeed;
leftMotorStep = -stepSpeed;
}
void rightM() {
rightMotorStep = -stepSpeed;
leftMotorStep = stepSpeed;
}
void reverseM() {
rightMotorStep = -stepSpeed;
leftMotorStep = -stepSpeed;
}
void halt() {
rightMotorStep = 0;
leftMotorStep = 0;
}
Спасибо, это действительно полезно!, @Renier Jr.
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Глобальные переменные занимают много места в динамической памяти.
- Ошибка: "'lcd' does not name a type" при использовании библиотеки LiquidCrystal.
- Могу ли я запретить библиотеке Stepper удерживать двигатель?
- Программирование Arduino Uno R3 для срабатывания реле каждые 24 часа
- Попытка сохранить файлы .wav с новым именем в каждом цикле.
- Матрица и пространство состояний Реализация Arduino
- Новый код приводит к звуковому шуму
во-первых, прекратите использовать
delay()
, @jsotolaКогда я не использую delay(), ультразвуковой датчик возвращает 0 после каждого значения (как упоминалось в посте)., @Renier Jr.
прекратите использовать функцию
delay()
для введения задержки... см. скетч примера blinkWithoutDelay в Arduino IDE, @jsotolaСпасибо, это определенно помогает!, @Renier Jr.
может быть интересно... https://wokwi.com/projects/327381547863769683, @jsotola