Не реагирует роботНИК мой... Что делать с ним?
- Войдите на сайт для отправки комментариев
Пт, 11/03/2016 - 20:39
И снова привет всем ГУРУ! создал я программку, и подровнял и компилируется на ура без ошибок, заливается в ардуинку без проблем. Но мой робАт не реагирует ни на что. Бездвижен. Горят зеленые лампы питания и все. Плата Leonardo, шилд L293D (с тремя проц).
Подскажите что делать. Это первый опыт. Тестовый Blink работает прекрасно. Программа ниже - никак...
#include <Adafruit_MotorShield.h>
// Подключаем нужные библиотеки
#include <Servo.h> // для работы с сервоприводом
// задаем пины, к которым мы подключили ультразвуковой дальномер
// на шилде Motor Drive Shield dual L239D оставались пустыми только аналоговые пины
// их можно свободно использовать, как цифровые
// пин A0 соответсвует 14-му цифровому пину, A1 - 15-му
#define trigPin 14 // через этот пин будем отправлять сигнал
#define echoPin 15 // здесь будем считывать ответ
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// даем Arduino знать, что подключено 2 моторчика
// это левый и правый мотор
Adafruit_DCMotor *myMotor1 = AFMS.getMotor(1);
Adafruit_DCMotor *myMotor2 = AFMS.getMotor(2);
// объект для управления сервоприводом
Servo neck;
// вспомогательные переменные, за что они отвечают написано ниже...
int d1, d2;
// для упрощения программы, устранения повторения кода и просто для удобства, будем использовать функции...
// ниже описаны функции, которые нужны для реализации того алгоритма, который мы написали в начале статьи
// с помощью данной функции мы сможем задать скорость, с которой будет двигаться наш робот
// у нее всего один параметр - speed - он должен быть в диапазоне 0-255
// соотвественно 0 - робот никуда не едет, 255 - едет на максимальной скорости (максимально сжирая батарейки :))
// для прямолинейной езды скорость всем моторам нужно установить одинаковую
// библиотека AFMotor позволяет установить моторы в 3 режима:
// 1. FORWARD - моторы будут крутиться "вперед", если можно так выразиться :)
// 2. BACKWARD - моторы будут крутиться "назад"
// 3. RELEASE - остановка, моторы крутиться не будут
// и после переключения режима, желательно дать время на переход из одного состояния в другое
// Ниже реализованы 3 функции, которые позволят переключаться между этими режимами.
void robot_forward () {
// Set the speed to start, from 0 (off) to 255 (max speed)
myMotor1->setSpeed(200);
myMotor1->run(FORWARD);
myMotor2->setSpeed(200);
myMotor2->run(FORWARD);
delay(1000);
}
void robot_backward() {
// Set the speed to start, from 0 (off) to 255 (max speed)
myMotor1->setSpeed(200);
myMotor1->run(BACKWARD);
myMotor2->setSpeed(200);
myMotor2->run(BACKWARD);
delay(1000);
}
void robot_release() {
myMotor1->run(RELEASE);
myMotor2->run(RELEASE);
delay(1000);
}
// конструкция платформы не позволяет поворачивать передние колеса для изменения направления движения
// это легко обойти, если вспомнить как поворачивает танк :)
// колеса на одной стороне мы вращаем в одну сторону, на другой стороне - в противоположную
// следующие функции это делают...
// поворот направо
void turning_to_the_right() {
myMotor1->run(FORWARD);
myMotor2->run(BACKWARD);
delay(1000);
}
// поворот налево
void turning_to_the_left() {
myMotor2->run(FORWARD);
myMotor1->run(BACKWARD);
delay(1000);
}
// такой алгоритм разворота разумеется не идеальный - этот метод я использовал для простоты
// для плавного поворота на ходу, нужно просто задавать моторам разную скорость
// и последняя функция
// она нужна для определения расстояния до препятствия
// для обеспечения большей точности, показания считываются дважды
int get_distance() {
// вспомогательные переменные
long duration;
int d_1, d_2, average = -1;
// это стандартный способ определения расстояния для дальномера
// описывать его не буду, в интернете есть куча информации по этому поводу - нам важен результат
// результат будет записан в переменную d_1, а именно будет записано количество сантиметров до препятствия
// -------------------
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
d_1 = (int) duration / 58.2;
// -------------------
// как я уже писал, повторяем процедуру для более точных показаний
// и записываем значение в переменную d_2
// -------------------
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
d_2 = (int) duration / 58.2;
// -------------------
// подсчитываем среднее арифметическое для d_1 и d_2
// это и будет считаться окончательным ответом
average = (int) (d_1 + d_2) / 2;
Serial.print("distance: ");
Serial.println(average);
return average;
}
void setup() {
Serial.begin(19200);
// устанавливаем пин A0 на вывод, A1 - на ввод
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// сервопривод подключен к 10-му пину, даем знать Arduino, что он там есть
neck.attach(10);
// и поворачиваем на нужный угол (угол подбирайте сами, нужно чтобы дальномер смотрел вперед)
neck.write(120);
// режим FORWARD, робот будет ехать вперед
robot_forward();
}
void loop() {
// вот мы и дошли до реализации самого алгоритма
// в функции setup() мы уже установили необходимые значения для движения вперед по прямой
// следующее условие будет проверять не наткнулся ли робот на препятствие
// если наткнулся - совершить маневр, и после его завершения опять ехать вперед
if (get_distance() < 20) {
// сюда попадем, если мы оказались впритык к препятствию (до него меньше 20 сантиметров)
// нам не хватает места для разворота
Serial.println("backward");
// сдаем немного назад
robot_backward();
delay(1000);
Serial.println("forward");
// потом мы опять едем вперед с надеждой, что сдалека мы обнаружим помеху :)
robot_forward();
// если ее обнаружим - то выполнится нижний участок кода
// если не обнаружим - либо опять сдадим назад, либо врежимся :)
} else if (get_distance() < 50) {
// если до препятствия остается 50 сантиметров, совершаем поворот
// останавливаем робота
robot_release();
// поворачиваем "голову" направо на 50 градусов
neck.write(70);
delay(500);
// считываем расстояние до препятствия справа от робота
d1 = get_distance();
// поворачиваем "голову" налево
neck.write(170);
delay(500);
// считываем расстояние до препятствия слева от робота
d2 = get_distance();
// выбираем оптимальный маршрут
if (d1 > d2) {
// сюда попадем, если справа от робота больше свободного места для езды
Serial.println("turning to the right");
// начинаем поворот направо
turning_to_the_right();
} else {
// сюда попадем, если слева от робота больше свободного места для езды
Serial.println("turning to the left");
// начинаем поворот налево
turning_to_the_left();
}
// вернем "голову" в исходную позицию
neck.write(120);
delay(500);
// поворачиваем до тех пор, пока препятствие не выйдет из поля зрения
while (get_distance() < 50) {
delay(500);
}
// поедем вперед, когда поворот завершится
robot_forward();
}
// небольшая задержка, чтобы дать время роботу поменять свое положение
delay(500);
}
и да. библиотека для моторшилда не ругается и в описании она подходит к леонардо и L293D.
а еще светодиод L постоянно горит не моргая....
Servo Shield for Arduino v2
Похоже я понял проблему.... Для Leonardo нужен именно этот шилд... Так?
Ищи Бидлиотеку для
шилд L293D с поддержкой ЛонардоНе будешь же ты править библиотекушилда L293D под неё сам с твоими познаниямиУ меня тоже была проблемма, при включении не двигался, пока рукой перед ним не помашеш. Оказалось изначально не задано было движение вперед, а он стоял тупо и припятствий ждал, потом нармально двигался. Мой проект