Умный ездящий робот со "зрением" на Arduino

Туша:
Решил я сделать простого робота, который бы ездил и видел препятствия объезжая их. Купил готовую платформу с кареткой для батареек AA на 1,5v.
 
Мозг крутилок:
Так же прикупил самый распространенный драйвер двигателей L293D. Чтобы крутить моторы куда захочу, вперед - назад, туда - сюда. Но минус его в том, что он сильно греется и отрыгивает в виде тепла 1,5V, хоть и защищен от перегрева.
ENABLE 1, 2, 3, 4  - Подключается к PWM (ШИМ) входу, можно и к обычному цифровому, но ток у вас будет всегда на максимуме, а на ШИМ'е вы можете регулировать его силу. От этого мотор можно крутить медленно или быстро, как хотите в общем.
INPUT 1, 2, 3, 4 - к любым цифровым входам
OUTPUT 1, 2, 3, 4 - подключают + и - моторов 
VCC1 - питание логики чипа +5V
VCC2 - питание моторов +5V - 36V
GND - к земле
Зенки:
В виде зрения я буду использовать ультразвуковой дальномер HC-SR04 (самый распространенный, стоит ~200р)
 
Особенности
Напряжение питания: 5V DC
Ток покоя: <2mA
Эффективный угол: <15°
Диапазон измерения расстояния: 2–400 cm
Разрешение: 0.3 cm
VCC - к +5V
TRIG - к любому цифровому входу
ECHO - к любому PWM входу
GND - земля
Кишки:
Вот макетная плата сборки + принципиальная схема (все делается в САПР Fritzing)
 
У L293D раздельное питание самой логики и двигателей, это очень хорошо. Двигатели я запитал от 4-х батареек типа AA на 1,5v, а саму логику буду питать от кроны. Можно было бы питать и от Arduino, но там еще у нас питается ультразвуковой дальномер. Если питать Arduino, дальномер + L293D, то батарейка очень быстро сядет ну или дальномеру не будет хватать тока, поэтому я решил питать драйвер отдельной батареи крона. Саму же Arduino + дальномер от другой батареи, тоже типа крона.
Итоговый результат умной повозки:
 
Магия:
Для управления робота я написал отдельную библиотеку, дабы не загромождать и не прописывать все скетче, а вызывать все функции которые мне нужны.
EasyRo.cpp :


#include "Arduino.h"

#include "EasyRo.h"

EasyRo::EasyRo(int MOTOR_LEFT_OUT1, int MOTOR_LEFT_OUT2, int MOTOR_LEFT_PWM,

int MOTOR_RIGHT_OUT1, int MOTOR_RIGHT_OUT2, int MOTOR_RIGHT_PWM)

{

pinMode(MOTOR_LEFT_OUT1, OUTPUT);

pinMode(MOTOR_LEFT_OUT2, OUTPUT);

pinMode(MOTOR_LEFT_PWM, OUTPUT);

pinMode(MOTOR_RIGHT_OUT1, OUTPUT);

pinMode(MOTOR_RIGHT_OUT2, OUTPUT);

pinMode(MOTOR_RIGHT_PWM, OUTPUT);


PIN_MOTOR_LEFT_OUT1 = MOTOR_LEFT_OUT1;

PIN_MOTOR_LEFT_OUT2 = MOTOR_LEFT_OUT2;

PIN_MOTOR_LEFT_PWM = MOTOR_LEFT_PWM;

PIN_MOTOR_RIGHT_OUT1 = MOTOR_RIGHT_OUT1;

PIN_MOTOR_RIGHT_OUT2 = MOTOR_RIGHT_OUT2;

PIN_MOTOR_RIGHT_PWM = MOTOR_RIGHT_PWM;

}


void EasyRo::FORWARD(int SPEED)

{

digitalWrite(PIN_MOTOR_LEFT_OUT1, HIGH);

digitalWrite(PIN_MOTOR_LEFT_OUT2, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT1, HIGH);

digitalWrite(PIN_MOTOR_RIGHT_OUT2, LOW);

for(int i = 0; i < SPEED; i++)

{

analogWrite(PIN_MOTOR_LEFT_PWM, SPEED);

analogWrite(PIN_MOTOR_RIGHT_PWM, SPEED);

}

}


void EasyRo::BACKWARD(int SPEED)

{

digitalWrite(PIN_MOTOR_LEFT_OUT1, LOW);

digitalWrite(PIN_MOTOR_LEFT_OUT2, HIGH);

digitalWrite(PIN_MOTOR_RIGHT_OUT1, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT2, HIGH);

for(int i = 0; i < SPEED; i++)

{

analogWrite(PIN_MOTOR_LEFT_PWM, SPEED);

analogWrite(PIN_MOTOR_RIGHT_PWM, SPEED);

}

}


void EasyRo::FORWARD_LEFT(int SPEED)

{

digitalWrite(PIN_MOTOR_RIGHT_OUT1, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT2, LOW);

digitalWrite(PIN_MOTOR_LEFT_OUT1, HIGH);

digitalWrite(PIN_MOTOR_LEFT_OUT2, LOW);

for(int i = 0; i < SPEED; i++)

{

analogWrite(PIN_MOTOR_LEFT_PWM, SPEED);

}

}


void EasyRo::BACKWARD_LEFT(int SPEED)

{

digitalWrite(PIN_MOTOR_RIGHT_OUT1, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT2, LOW);

digitalWrite(PIN_MOTOR_LEFT_OUT1, LOW);

digitalWrite(PIN_MOTOR_LEFT_OUT2, HIGH);

for(int i = 0; i < SPEED; i++)

{

analogWrite(PIN_MOTOR_LEFT_PWM, SPEED);

}

}


void EasyRo::FORWARD_RIGHT(int SPEED)

{

digitalWrite(PIN_MOTOR_LEFT_OUT1, LOW);

digitalWrite(PIN_MOTOR_LEFT_OUT2, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT1, HIGH);

digitalWrite(PIN_MOTOR_RIGHT_OUT2, LOW);

for(int i = 0; i < SPEED; i++)

{

analogWrite(PIN_MOTOR_RIGHT_PWM, SPEED);

}

}


void EasyRo::BACKWARD_RIGHT(int SPEED)

{

digitalWrite(PIN_MOTOR_LEFT_OUT1, LOW);

digitalWrite(PIN_MOTOR_LEFT_OUT2, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT1, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT2, HIGH);

for(int i = 0; i < SPEED; i++)

{

analogWrite(PIN_MOTOR_RIGHT_PWM, SPEED);

}

}


void EasyRo::STOP(int SPEED)

{

for(int i = SPEED; i >=5 ; i++)

{

analogWrite(PIN_MOTOR_LEFT_PWM, SPEED);

analogWrite(PIN_MOTOR_RIGHT_PWM, SPEED);

}

digitalWrite(PIN_MOTOR_LEFT_OUT1, LOW);

digitalWrite(PIN_MOTOR_LEFT_OUT2, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT1, LOW);

digitalWrite(PIN_MOTOR_RIGHT_OUT2, LOW);

}

EasyRo.h :
#include "Arduino.h"
class EasyRo
{
public:
EasyRo(int MOTOR_LEFT_OUT1, int MOTOR_LEFT_OUT2, int MOTOR_LEFT_PWM,
int MOTOR_RIGHT_OUT1, int MOTOR_RIGHT_OUT2, int MOTOR_RIGHT_PWM);
void FORWARD(int SPEED);
void BACKWARD(int SPEED);
void FORWARD_LEFT(int SPEED);
void BACKWARD_LEFT(int SPEED);
void FORWARD_RIGHT(int SPEED);
void BACKWARD_RIGHT(int SPEED);
void STOP(int SPEED);
private:
int PIN_MOTOR_LEFT_OUT1;
int PIN_MOTOR_LEFT_OUT2;
int PIN_MOTOR_LEFT_PWM;
int PIN_MOTOR_RIGHT_OUT1;
int PIN_MOTOR_RIGHT_OUT2;
int PIN_MOTOR_RIGHT_PWM;
};

Сам скетч:

#include <EasyRo.h>

#include <math.h>

#define LEFT_MOTOR_OUT_1 13

#define LEFT_MOTOR_OUT_2 12

#define LEFT_MOTOR_PWM 11

#define RIGHT_MOTOR_OUT_1 8

#define RIGHT_MOTOR_OUT_2 7

#define RIGHT_MOTOR_PWM 6

#define TRIG 4

#define ECHO 3


int time = 0;

int dist = 0;

int left = 0;

int right = 0;


EasyRo robot(LEFT_MOTOR_OUT_1,LEFT_MOTOR_OUT_2,LEFT_MOTOR_PWM,

RIGHT_MOTOR_OUT_1,RIGHT_MOTOR_OUT_2,RIGHT_MOTOR_PWM);


void setup()

{

  pinMode(TRIG, OUTPUT);

  pinMode(ECHO, INPUT);

  Serial.begin(9600);

}


void loop()

{

  robot.FORWARD(255); 

// Движемся вперед

  if(GetDist() <= 5) // Если расстояние до объекта 5 или менее сантиметров то 

  {

    robot.BACKWARD(255); // Движемся назад

    delay(1000);//Останавливаем программу на 1000 милисекунд

    robot.BACKWARD_LEFT(255); // Движемся только левым колесом назад

    delay(500);

//Останавливаем программу на 500 милисекунд

    left = GetDist(); // Получаем расстояние до ближайшего объекта в левой стороне 

    robot.FORWARD_LEFT(255); // Движемся только левым колесом вперед

    delay(1000); //Останавливаем программу на 1000 милисекунд

    right = GetDist(); // Получаем расстояние до ближайшего объекта в правой стороне 

    if(left > right) // Если в левой стороне расстояние до объекта больше то

    {

      robot.BACKWARD_LEFT(255); // Движемся только левым колесом назад

      delay(1000); //Останавливаем программу на 1000 милисекунд

      robot.FORWARD(255); // Двигаемся вперед

    }   

  }

}


int GetDist() // Получаем дистанцию до объекта в сантиметрах

{

  reget:

  digitalWrite(TRIG,HIGH);

  delayMicroseconds(10);

  digitalWrite(TRIG, LOW);

  delayMicroseconds(100);

  time = pulseIn(ECHO,HIGH);

  dist = time/58;

  if(dist < 0)

  {

    goto reget;

  }

  Serial.println(dist);

  delay(10);

  return dist;

}

Можно было бы прицепить сервопривод а на него дальномер, чтобы он мог бошкой крутить, но серва нещадно съест всю крону :(
В общем вот так :)
nektome.blog https://nektome.blog/ +7 (927) 2893774
| Комментариев: 13
    Новых комментариев: 0
  1. Комментариев нет...
  1. nektome.blog
  2. Becks Harrington
  3. Блог
  4. Умный ездящий робот со "зрением" на Arduino
  5. Негативные комментарии
Негативные комментарии