HC-SR04 + Uno + Motor Shield

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

к m1 - двигатель, отвечающий за движение вперёд/назад, к m2 - руль, он двигатель, такой же модели как и первый

maksim
Offline
Зарегистрирован: 12.02.2012

При отключении питания рулевого двигателя передние колеса сами встают по середине?

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

да, там же пружины

maksim
Offline
Зарегистрирован: 12.02.2012

Должно быть:
Serv1,A0 - правый
Serv2,A1 - левый

У вас почему-то:
Serv1,A1 - правый
Serv2,A0 - левый

В общем если подключить все адекватно и попытаться чуть-чуть подумать, то все заработает. Так же не забывайте менять местами провода рулевого двигателя, потому как кроме вас никто не знает в какую сторону поворачиваются колеса.

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

подключил всё заново, прошил заново - едит вперёд, на сенсоры не откликается, в чём проблема, не понятно =(

maksim
Offline
Зарегистрирован: 12.02.2012

Так, давайте по порядку, проверяем работу ходового двигателя

#include <AFMotor.h>

AF_DCMotor MOTOR(1);

void setup()
{
  MOTOR.setSpeed(200); 
}

void loop()
{ 
  MOTOR.run(FORWARD);
  delay(3000); 
  MOTOR.run(BACKWARD);
  delay(1000); 
}

машинка должна ехать вперед 3 секунды, а назад 1 секунду, не наоборот! Если наоборот, то меняйте местами провода М1.

maksim
Offline
Зарегистрирован: 12.02.2012

Дальше проверяем рулевой двигатель:

#include <AFMotor.h>
#define RIGHT  FORWARD
#define LEFT  BACKWARD
#define CENTER RELEASE

AF_DCMotor RULE(2);

void setup()
{
  RULE.setSpeed(250); 
}

void loop()
{ 
  RULE.run(RIGHT);
  delay(1000); 
  RULE.run(CENTER);
  delay(1000); 
  RULE.run(RIGHT);
  delay(1000); 
  RULE.run(CENTER);
  delay(1000); 
  RULE.run(LEFT);
  delay(1000); 
  RULE.run(CENTER);
  delay(1000); 
}

машинка должна поворачивать колеса два раза вправо и один раз влево, если наоборот, то меняйте местами провода М2.

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

работает, что дальше?

maksim
Offline
Зарегистрирован: 12.02.2012

Так как вы распаяли все 6 аналоговых входов, то давайте к ним и подключим датчики, питание берете со штырьков рядом:

правый:
VCC -> +5V
GND -> GND
Trig -> A0
Echo -> A1

левый:
VCC -> +5V 
GND -> GND
Trig -> A2
Echo -> A3

#define Trig_R A0
#define Echo_R A1
#define Trig_L A2
#define Echo_L A3

void setup() 
{
  Serial.begin(9600);
  pinMode(Trig_R, OUTPUT);
  pinMode(Trig_L, OUTPUT);
}

void loop() 
{
  Serial.print("RIGHT = ");
  Serial.print(Ultrasonic(Trig_R, Echo_R));
  Serial.print("cm      LEFT = ");
  Serial.print(Ultrasonic(Trig_L, Echo_L));
  Serial.println("cm");
  delay(100);
}

int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

И смотрим в сериал-мониторе как они работают, правый должен показывать расстояние справа, левый - слева.

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

всё супер

maksim
Offline
Зарегистрирован: 12.02.2012

Теперь посмотрим как будут рулить колеса в зависимости от припятствия спра или слева

#include <AFMotor.h>

#define DIST_RULE 40  // расстояние, при котором происходит руление

#define Trig_R A0
#define Echo_R A1
#define Trig_L A2
#define Echo_L A3

#define LED 13
#define RIGHT  FORWARD
#define LEFT  BACKWARD
#define CENTER RELEASE

AF_DCMotor RULE(2);

void setup()
{
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  pinMode(Trig_R, OUTPUT);
  pinMode(Trig_L, OUTPUT);
  RULE.setSpeed(250); 
}

void loop()
{ 
  static unsigned long millis_prev;
  if(millis()-millis_prev > 100)
  {
    digitalWrite(LED, HIGH);

    int dist_R = Ultrasonic(Trig_R, Echo_R); // Измеряем расстояние справа
    int dist_L = Ultrasonic(Trig_L, Echo_L); // Измеряем расстояние слева 
    
    if(dist_R < DIST_RULE || dist_L < DIST_RULE)
      {
        if(dist_R < dist_L) RULE.run(LEFT);
        if(dist_L < dist_R) RULE.run(RIGHT);
      }
      else RULE.run(CENTER);  

    digitalWrite(LED, LOW);
    millis_prev = millis();
  }
}

int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

В начале кода задается дистанция DIST_RULE в см, при которой если в "поле зрения" одного из датчиков попадает предмет происходит руление, направление колес определяется большей дистанцией одного из датчиков. То есть если поднести руку к правому датчику ближе чем на 40 см, то колеса должны повернуться влево, если к левому датчику, то колеса повернутся вправо. 

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

класс, все идеально

maksim
Offline
Зарегистрирован: 12.02.2012

Ну и добавляем движение 

#include <AFMotor.h>

#define DIST_MAX  60  // среднее расстояние, при котором робот начнет снижать скорость движения
#define DIST_RULE 40  // расстояние, при котором происходит руление
#define DIST_BACK 20  // расстояние, при котором робот едет назад

#define Trig_R A0
#define Echo_R A1
#define Trig_L A2
#define Echo_L A3

#define LED 13
#define RIGHT  FORWARD
#define LEFT  BACKWARD
#define CENTER RELEASE

AF_DCMotor MOTOR(1);
AF_DCMotor RULE(2);

void setup()
{
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  pinMode(Trig_R, OUTPUT);
  pinMode(Trig_L, OUTPUT);
  RULE.setSpeed(250); 
}

void loop()
{ 
  static unsigned long millis_prev;
  if(millis()-millis_prev > 100)
  {
    digitalWrite(LED, HIGH);

    int dist_R = Ultrasonic(Trig_R, Echo_R); // Измеряем расстояние справа
    int dist_L = Ultrasonic(Trig_L, Echo_L); // Измеряем расстояние слева 

    if(dist_R > DIST_BACK && dist_L > DIST_BACK)
    {
      MOTOR.run(FORWARD);
      int dist = constrain((dist_R + dist_L)/2, DIST_BACK, DIST_MAX);
      int speed = map(dist, DIST_BACK, DIST_MAX, 100, 255);
      MOTOR.setSpeed(speed);

      if(dist_R < DIST_RULE || dist_L < DIST_RULE)
      {
        if(dist_R < dist_L) RULE.run(LEFT);
        if(dist_L < dist_R) RULE.run(RIGHT);
      }
      else RULE.run(CENTER); 
    }
    else
    {
      RULE.run(RELEASE);
      MOTOR.run(BACKWARD);
      MOTOR.setSpeed(200);  // скорость заднего хода
      delay(2000);          // время заднего хода
    }

    digitalWrite(LED, LOW);
    millis_prev = millis();
  }
}

int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

Если среднее расстояние на обоих датчиках становится меньше 60 см, то робот начинает снижать скорость. Если на любом из датчиков расстояние станет меньше 20 см, то робот будет ехать назад 2 секунды. 

Не растопыривайте датчики в разные стороны, они должны "смотреть" практически вперед и чуть-чуть в стороны. Также относительно горизонтали они должны "смотреть" чуть выше, что бы сигнал не отражался от пола.

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

спасибо огромнейшее! вроде работает как надо! Жаль микруха перегревается сильно =(

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

рулит, рулит, потом бац - как будто невидимая преграда =( и расстояние менял и датчики вертел - не помогает =(

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

100 раз пересмотрел - переделал - не получается ничего =(

maksim
Offline
Зарегистрирован: 12.02.2012

Tarantul_acc пишет:

рулит, рулит, потом бац - как будто невидимая преграда =( и расстояние менял и датчики вертел - не помогает =(

100 раз пересмотрел - переделал - не получается ничего =(

На такое "подробное" описание проблемы могу вам только посоветовать:
повертите что-нибудь, посмотрите куда-нибудь , переделайте как-нибудь, еще раз 100, а потом бац и все должно заработать.

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

хех =) вот именно, что такое все делалось, а проблема была изложена выше - это невидимые стены и поворот руля, но без движения назад

maksim
Offline
Зарегистрирован: 12.02.2012

Ну если с питанием, направлением даьчиков и настройками все нормально, можно предположить что ловится эхо от опроса предыдущего датчика, тогда перед опросами надо маленько подождать

#include <AFMotor.h>

#define DIST_MAX  60  // среднее расстояние, при котором робот начнет снижать скорость движения
#define DIST_RULE 40  // расстояние, при котором происходит руление
#define DIST_BACK 20  // расстояние, при котором робот едет назад

#define Trig_R A0
#define Echo_R A1
#define Trig_L A2
#define Echo_L A3

#define LED 13
#define RIGHT  FORWARD
#define LEFT  BACKWARD
#define CENTER RELEASE

AF_DCMotor MOTOR(1);
AF_DCMotor RULE(2);

void setup()
{
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  pinMode(Trig_R, OUTPUT);
  pinMode(Trig_L, OUTPUT);
  RULE.setSpeed(250); 
}

void loop()
{ 
  delay(50);
  digitalWrite(LED, HIGH);
  int dist_R = Ultrasonic(Trig_R, Echo_R); // Измеряем расстояние справа
  digitalWrite(LED, LOW);
  delay(50);
  digitalWrite(LED, HIGH);
  int dist_L = Ultrasonic(Trig_L, Echo_L); // Измеряем расстояние слева 
  digitalWrite(LED, LOW);
  
  if(dist_R > DIST_BACK && dist_L > DIST_BACK)
  {
    MOTOR.run(FORWARD);
    int dist = constrain((dist_R + dist_L)/2, DIST_BACK, DIST_MAX);
    int speed = map(dist, DIST_BACK, DIST_MAX, 100, 255);
    MOTOR.setSpeed(speed);

    if(dist_R < DIST_RULE || dist_L < DIST_RULE)
    {
      if(dist_R < dist_L) RULE.run(LEFT);
      if(dist_L < dist_R) RULE.run(RIGHT);
    }
    else RULE.run(CENTER); 
  }
  else if(dist_R > 0 && dist_L > 0)
  {
    RULE.run(RELEASE);
    MOTOR.run(BACKWARD);
    MOTOR.setSpeed(200);  // скорость заднего хода
    delay(2000);          // время заднего хода
  }
  
}

int Ultrasonic(byte Trig_pin, byte Echo_pin)
{
  digitalWrite(Trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig_pin, LOW);   
  return pulseIn(Echo_pin, HIGH, 20000)/29.0/2;
}

 

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

да, разница сильная! а как бы задать чтоб он ехал назад не просто 2 секунды, а с повёрнутым рулём?

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013
if(dist_R < dist_L) RULE.run(LEFT);
MOTOR.run(BACKWARD);
MOTOR.setSpeed(220);
delay(2000);
if(dist_L < dist_R) RULE.run(RIGHT);
MOTOR.run(BACKWARD);
MOTOR.setSpeed(220);
delay(2000);

так молжно?

 

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

не, фигня

 

Tarantul_acc
Tarantul_acc аватар
Offline
Зарегистрирован: 09.03.2013

блин отчего же он назад так туго поворачивает в тот момент когда и руль поворачивает? вроде ж скорости прибавил...

drimer
Offline
Зарегистрирован: 27.06.2015

день добрый а у меня ошибки :(

maksim
Offline
Зарегистрирован: 12.02.2012

#7 пункт 2.

drimer
Offline
Зарегистрирован: 27.06.2015

а в чем ошибки  непонимаю

 

maksim
Offline
Зарегистрирован: 12.02.2012

В том, что у вас не установлена или неправильно установлена библиотека.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Маленькар ремарка:

Лучше ставьте библиотеки не туда где ИДЕ, а туда где ваши скетчи.
Тогда удаление старой версии не приведёт к потере ваших библиотек
А лучше совсем скетчи и библиотеки хранить не в дэфалтных папках винды , а в тех где вы хотите .
Например на всяких дропбоксах и ему подобным
 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Можно чуть поподробнее про варианты размещения библиотек?

Пока не понял, по какому принципу они подключается - создается впечатление, что пытается подключить все, что смог найти, вне зависимости от того, где.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

1. Идёте в настройки и меняете папку со скетчами в удобное место.
    Желательно не в мои_документы. ( Я её просто так ненавижу....  что слов нет. И не храню там ничего)
   У меня эта папка с названием AVR \ Arduino лежит в дропбоксе.

2. В этой папке cделайте новую с названием libraries  и туда кладёте все СВОИ библиотеки.
    Про его родную папку забываете навсегда.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Спасибо. Отдельную папку для скетчей я сделал сразу, как только IDE предложила мне сохранить мой первый скетч. А после того, как она предложила мне сохранить второй скетч по старому адресу, поменял настройки среды.

Но остались непонятки с библиотеками. У меня среди скетчей нет папки libraries, но стандартные библиотеки IDE находит. Отсюда вопросы:

1. Где IDE ищет библиотеки, если в скетчах нет папки libraries?

2. Где IDE ищет библиотеки, если в скетчах есть папка libraries?

3. Есть ли какие-нибудь особенностей по указанию путей в include'ах кроме стандартных С-шных?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

1.  Ищет в двух местах с названием libraries : там где ИДЕ и там где скетчи.

2.  Ищет в двух местах с названием libraries : там где ИДЕ и там где скетчи.

.........  У меня среди скетчей нет папки libraries..........
В папке со скетчами  cделайте новую с названием libraries и кладите или накладывайте туда свои библиотеки.

3. Нет.