Приветствую всех. Попытался повторить робота-уборщика представленного здесь. Сразу скажу не хочет РОБОТяга работать как у автора. Естественно это моя первая попытка разобраться в программировании Ардуино и пару месяцев изучения темы не смогли внести ясность в понимании того что я делаю не так. Питание силовой части организовал отдельно от Ардуинки.
Немного изменил компоненты робота:
1. Вместо LMotorShield подключил движки к драйверу на L298N
2. Вместо ИК дальномера SHARP GP2D120 использовал SHARP GP2Y0A41SK аналогичный по техническим характеристикам (дальность от 4 до 30 сантиметров).
3. Подключал всё к Ардуино UNO для удобства через Arduino Sensor Shield v 5.0
Вот данные подключения:
Analog 0 - ИК радар Sharp
Analog 1 - 1-й ИК датчик поверхности
Analog 2 - 2-й ИК датчик поверхности
Digital 2 и 7 - мотор А вращение
Digital 3 - ШИМ мотора А
Digital 2 и 7 - мотор В вращение
Digital 3 - ШИМ мотора В
Digital 6 - серва головы
Digital 10 - серва левой лапки
Digital 9 - серва правой лапки
Теперь о грустном, о проблемах с которыми я столкнулся: Если отключить двигатели и двигать робота руками, то всё работает отлично. Он вертит головой, как увидит препятствие перестаёт "оглядываться", далее поворачиваешь его к нему и продвигаешь вперёд. Далее он отворачивает голову, захватывает лапами предмет и после дальнейшего его продвижения вперёд отпускает предмет у края стола.
Но если подключаешь двигатели, то робот начинает жить своей жизнью. После того как он увидит препятствие, он замирает (останавливается) вместо того, чтобы повернуться к предмету и подъехать к нему. Двигатели конечно продолжают работать, но как-то в полсилы и ему не хватает мощи для поворота.
Чаще всего просто не замечает никаких предметов, а проносится мимо до края стола (грешу на дальность ИК дальномера Sharp (от 4 до 30 сантиметров)), срабатывают датчики поверхности, он резко рвёт немного назад разворачивается. При повторном подъезде к краю он уже не останавливается а падает в пропасть....Добавлено (15.08.2016, 23:41)
---------------------------------------------
Вот скетч от автора, немного неумело переделанный мной под мою распиновку:
#include <Servo.h>
Servo rightHand;
Servo leftHand;
Servo head;
int IN1 = 7; // Input1 подключен к выводу 7 мотор А вращение
int IN2 = 2; // Input2 подключен к выводу 2 мотор А вращение
int IN3 = 8; // Input3 подключен к выводу 8 мотор B вращение
int IN4 = 4; // Input4 подключен к выводу 4 мотор B вращение
int ENB = 3; // ШИМ вторго мотора (левого)
int ENA = 11; // ШИМ первого мотора (правого)
int ledPin = 13; // Кнопка включения мп3
int ledPin1 = 12; // кнопка перемотки мп3
int i;
int j;
int p[18]; // массив, здесь будем записывать данные с ИК дальномера в разных его положениях
int gp,gp1,gp2,g;
int b;
void setup() {
{
Serial.begin(9600);
}
rightHand.attach(9); // подключение правой лапки
leftHand.attach(10); // подключение левой лапки
head.attach(6); // подключение сервы головы
pinMode(ledPin,OUTPUT);
pinMode(ledPin1,OUTPUT);
pinMode (ENA, OUTPUT); // мотор А скорость
pinMode (IN1, OUTPUT); // мотор А вращение
pinMode (IN2, OUTPUT); // мотор А вращение
pinMode (ENB, OUTPUT); // мотор В скорость
pinMode (IN3, OUTPUT); // мотор В вращение
pinMode (IN4, OUTPUT); // мотор В вращение
}
void Forward() { // Подпрограмма движения робота вперед
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite(ENA,170); // подаем на вывод ENА и ENВ управляюший ШИМ сигнал
analogWrite(ENB,170);
}
void Backward(){ // Подпрограмма движения робота назад
digitalWrite (IN1, LOW); // вращаем мотор в обратную сторону
digitalWrite (IN2, HIGH);
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite(ENA,170); // подаем на вывод ENА и ENВ управляюший ШИМ сигнал
analogWrite(ENB,170);
}
void motorStop(){ // Подпрограмма остановки мотора
analogWrite(ENA,0); // подаем на вывод ENА и ENВ управляюший ШИМ сигнал равный нулю
analogWrite(ENB,0);
}
void motorRun(){ // Подпрограмма запуска мотора
analogWrite(ENA,170); // подаем на вывод ENА и ENВ управляюший ШИМ сигнал
analogWrite(ENB,170);
}
void Spin_Left(){ // Поворот влево
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
}
void Spin_Right(){ // Поворот вправо
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
}
void loop()
{
rightHand.write(15); // раскрываем правую лапку
delay(100);
leftHand.write(160); // раскрываем левую лапку
delay(100);
head.write(90); // голова смотрит вперёд
delay(200);
j=0;
for (j = 0; j < 18; j++){ // для j от 0 до 18
head.write(j*10); // вращение сервы по 10 градусов (умножаем полученное значение на 10)
gp=analogRead(0); // считываем данные с ИК радара
delay(50);
p[j]=gp; // записываем это значение в массив
Serial.println(p[j]); // выводим на экран
gp2=(analogRead(2)); // считываем значение датчиков плоскости
gp1=(analogRead(1));
g=min(gp1,gp2); // выбираем минимальное значение из двух
if (g>900){ // Если значение больше 900 (датчик сработал), то отходим назад и разворачиваемся
motorRun();
Backward();
delay(500);
Spin_Left();
delay(600);
motorStop();
}
if (p[j]<160){ // если значение с дальномера меньше 150, (примерно 25 см.), то шаг вперед
motorRun();
Forward();
delay (50);
motorStop();}
else { // Иначе
head.write(90); // поворачиваем голову вперед
delay(200);
gp=analogRead(0); // считываем данные с ИК радара
Serial.println(gp);
while(gp<160){ // поворачиваемся, пока не заметим предмет
motorRun();
if (j>9){ // если предмет с лева, то
Spin_Left(); // поворот в сторону объекта
}
else { // иначе поворот вправо
Spin_Right();
}
delay (10);
motorStop();
gp=analogRead(0); // считываем данные с ИК радара
delay(50);
}
gp=analogRead(0); // считываем данные с ИК радара
delay(50);
while(gp<400){ //Двигаемся вперед пока предмет не будет на расстоянии 10 см.
motorRun();
Forward(); // движение до объекта
delay (50); // время движения
motorStop();
gp=analogRead(0); // считываем данные с ИК радара
delay(50);
}
head.write(175); // убираем голову в сторону, чтобы она не мешала захвату предмета и транспортировке
delay(100);
motorRun();
Forward(); // движение до объекта
delay (70); // время движения
motorStop();
rightHand.write(80); // захват первой лапой
delay(500);
leftHand.write(80); // захват второй лапой
delay(100);
gp2=(analogRead(2)); // считываем значение датчиков плоскости
gp1=(analogRead(1));
g=min(gp1,gp2); // выбираем минимальное значение из двух
while(g<100) // движение после захвата до конца плоскости.
{
gp2=(analogRead(2)); // считываем значение датчиков плоскости
gp1=(analogRead(1));
Serial.println(gp2);
g=min(gp1,gp2); // выбираем минимальное значение из двух
motorRun();
Forward();
delay(5);
motorStop();}
rightHand.write(15); // раскрываем правую лапку
delay(100);
leftHand.write(160); // раскрываем левую лапку
delay(100);
motorRun();
Backward();
delay(100);
Spin_Right();
delay(600);
}
}
}