Запускаю робота с двумя передними датчиками, но он тормозит
Вкратце: у меня есть небольшой робот с четырьмя серводвигателями непрерывного действия и двумя ультразвуковыми датчиками. Он управляется платой UNO с сенсорным экраном V5 сверху. Моя цель состоит в том, чтобы запрограммировать передний правый и передний левый датчики так, чтобы оба возвращали расстояние в дюймах, и заставить робота поворачиваться в направлении с наибольшим пространством, когда один из датчиков возвращает расстояние меньше некоторого минимума. Я совершенно уверен, что проблема не в двигателях и датчиках, так как их проверка сама по себе не выявила проблем. Однако, когда я запускаю приведенный ниже код, робот заикается, в основном просто двигаясь назад, но заикаясь вперед и иногда поворачиваясь на секунду или две. Есть идеи, что происходит?
#include <Servo.h>
Servo FL;
Servo FR;
Servo BL;
Servo BR;
const int FRecho = 11;
const int FRtrig = 10;
const int FLecho = 9;
const int FLtrig = 8;
long durationFL;
long durationFR;
int distanceInchR = 24;
int distanceCmR;
int distanceInchL = 24;
int distanceCmL;
const int minDistanceInch = 18;
const int minDistanceCm;
enum movementStates {
STILL,
FORWARD,
BACK,
TURNFR,
TURNFL,
NOTHING
};
enum movementStates movement;
void setup() {
FL.attach(4);
FR.attach(5);
BL.attach(6);
BR.attach(7);
pinMode(FRtrig, OUTPUT);
pinMode(FRecho, INPUT);
pinMode(FLtrig, OUTPUT);
pinMode(FLecho, INPUT);
movement = NOTHING;
forward();
}
void loop() {
updateDistanceFL();
updateDistanceFR();
updateDirection();
}
void forward () {
FL.write(180);
FR.write(0);
BL.write(180);
BR.write(0);
movement = FORWARD;
}
void turnFR () {
FL.write(180);
FR.write(180);
BL.write(180);
BR.write(180);
movement = TURNFR;
}
void turnFL () {
FL.write(0);
FR.write(0);
BL.write(0);
BR.write(0);
movement = TURNFL;
}
void backUp () {
FL.write(0);
FR.write(180);
BL.write(0);
BR.write(180);
movement = BACK;
}
void still () {
FL.write(90);
FR.write(90);
BL.write(90);
BR.write(90);
movement = STILL;
}
void updateDirection() {
if (distanceInchR < minDistanceInch && distanceInchL < minDistanceInch) {
if (movement != BACK) {
backUp();
}
else if (distanceInchR < minDistanceInch) {
if (movement != TURNFL) {
turnFL();
}
}
else if (distanceInchL < minDistanceInch) {
if (movement != TURNFR) {
turnFR();
}
}
else if (distanceInchR > minDistanceInch && distanceInchL > minDistanceInch)
if (movement != FORWARD) {
forward();
}
}
else {
if (movement != STILL) {
still();
}
}
}
void updateDistanceFR(){
digitalWrite(FRtrig, LOW);
delayMicroseconds(2);
digitalWrite(FRtrig, HIGH);
delayMicroseconds(10);
digitalWrite(FRtrig, LOW);
durationFR = pulseIn(FRecho, HIGH);
distanceCmR= durationFR*0.034/2;
distanceInchR = durationFR*0.0133/2;
}
void updateDistanceFL(){
digitalWrite(FLtrig, LOW);
delayMicroseconds(2);
digitalWrite(FLtrig, HIGH);
delayMicroseconds(10);
digitalWrite(FLtrig, LOW);
durationFL = pulseIn(FLecho, HIGH);
distanceCmL= durationFL*0.034/2;
distanceInchL = durationFL*0.0133/2;
}
@Claire Arp, 👍0
Обсуждение1 ответ
ваша логика updateDirection
работает не совсем так, как вы думаете.
после небольшого форматирования кода и комментариев он выглядит так:
void updateDirection() {
if (distanceInchR < minDistanceInch && distanceInchL < minDistanceInch) {
if (movement != BACK) {
backUp();
} else if (distanceInchR < minDistanceInch) {
//всегда вводится, если движение == НАЗАД
if (movement != TURNFL) {
turnFL();
}
} else if (distanceInchL < minDistanceInch) {
// никогда не входил
if (movement != TURNFR) {
turnFR();
}
} else if (distanceInchR > minDistanceInch && distanceInchL > minDistanceInch)
// никогда не входил
if (movement != FORWARD) {
forward();
}
//конец расстоянияInchR < minDistanceInch && расстояние, дюйм, длина < minDistanceInch
} else {
// введено, когда DistanceInchR > минРасстояниеДюймы || расстояние, дюйм, L > minDistanceInch
if (movement != STILL) {
still();
}
}
}
похоже, что у вас отсутствует закрывающая скобка вокруг первого условия. Единственными вызываемыми функциями движения являются backUp
, turnFL
и Still
.
Если мы добавим недостающие фигурные скобки, все будет выглядеть намного лучше:
void updateDirection() {
if (distanceInchR < minDistanceInch && distanceInchL < minDistanceInch) {
if (movement != BACK) {
backUp();
}
} else if (distanceInchR < minDistanceInch) {
if (movement != TURNFL) {
turnFL();
}
} else if (distanceInchL < minDistanceInch) {
if (movement != TURNFR) {
turnFR();
}
} else if (distanceInchR > minDistanceInch && distanceInchL > minDistanceInch) {
if (movement != FORWARD) {
forward();
}
} else {
if (movement != STILL) {
still();
}
}
}
- Как использовать фотодиод для arduino?
- Питание нескольких сервоприводов от одной батареи. Чего не хватает в схеме?
- Почему задержка более 64 миллисекунд останавливает вращение серводвигателя? Я не использую «Servo.h», вместо этого я просто управляю длиной импульса.
- Подключение датчика Winsen ZE11-C2H4 к Arduino
- Функция Pulsein() блокирует одновременное выполнение других задач
- LM7805 сильно нагревается с четырьмя серводвигателями
- Как запрограммировать 2 ультразвуковых датчика, один на серводвигателе и один прикрепленный на передней стороне автомобиля?
- Сделать систему с ультразвуковым датчиком и сервоприводом
функция
updateDirection()
содержит кучу избыточных логических тестов... она может делать не то, что вы ожидаете., @jsotolaДобавьте
delay()
в свойloop()
, ваш код слишком занят проверкой и постоянным обновлением направления без времени для движения двигателя в любом направлении. Добавьте переменнуюstatus
для хранения текущего статуса направления, если направление остается прежним, нет необходимости запускатьupdateDirection()
снова и снова., @hcheung