пятница, 2 сентября 2016 г.

Робот с ультразвуковым дальномером

В статье рассказывается о простой платформе с ультразвуковым дальномером HC-SR04. Приводится скетч управляющий роботом. С этим кодом робот просто старается избегать столкновений с препятствиями.


В полностью собранном виде робот выглядит так:


Обычная трехколесная тележка. Моторы коллекторные с редукторами. В ранее опубликованных статьях есть детальные фотографии и подробное описание.

Мозгом робота является Arduino Uno.


Подключается все к ардуино через Sensor Shield V4.


Данные об окружающей среде робот получает от ультразвукового сенсора HC-SR04.


Драйвер двигателей на L9110S.


Левый двигатель подключаются к клеммам драйвера MOTOR A. Правый двигатель подключается к клеммам драйвера MOTOR B.

Между собой электронные компоненты соединяются согласно ниже изложенным рекомендациям.

Arduino --- Ultrasonic Sensor HC-SR04
GND --- GND
VCC --- VCC
D4 --- Trig
D5 --- Echo

Arduino --- Motor Driver L9110S
GND --- GND
VCC --- VCC
D13 --- A-IA
D12 --- A-IB
D11 --- B-IA
D10 --- B-IB

Более подробно о работе с коллекторными двигателями и их драйверами я писал в http://justforduino.blogspot.ru/2015/02/blog-post.html

Скетч:

////////////////////////
//
// Arduino UNO
//
////////////////////////
//
// Sketch: Robot
//

#include <util/delay.h>

const unsigned char A_IA = 13;
const unsigned char A_IB = 12;
const unsigned char B_IA = 11;
const unsigned char B_IB = 10;

const unsigned char TRIG = 4;
const unsigned char ECHO = 5;

unsigned int data = 0;

unsigned long int time1 = 0;
unsigned long int time2 = 0;

void forward_forward( void )
{
    digitalWrite(A_IA, HIGH);
    digitalWrite(A_IB, LOW);
    digitalWrite(B_IA, HIGH);
    digitalWrite(B_IB, LOW);
}

void backward_backward( void )
{
    digitalWrite(A_IA, LOW);
    digitalWrite(A_IB, HIGH);
    digitalWrite(B_IA, LOW);
    digitalWrite(B_IB, HIGH);
}

void forward_stop( void )
{
    digitalWrite(A_IA, HIGH);
    digitalWrite(A_IB, LOW);
    digitalWrite(B_IA, LOW);
    digitalWrite(B_IB, LOW);
}

void backward_stop( void )
{
    digitalWrite(A_IA, LOW);
    digitalWrite(A_IB, HIGH);
    digitalWrite(B_IA, LOW);
    digitalWrite(B_IB, LOW);
}

void stop_forward( void )
{
    digitalWrite(A_IA, LOW);
    digitalWrite(A_IB, LOW);
    digitalWrite(B_IA, HIGH);
    digitalWrite(B_IB, LOW);
}

void stop_backward( void )
{
    digitalWrite(A_IA, LOW);
    digitalWrite(A_IB, LOW);
    digitalWrite(B_IA, LOW);
    digitalWrite(B_IB, HIGH);
}

void forward_backward( void )
{
    digitalWrite(A_IA, HIGH);
    digitalWrite(A_IB, LOW);
    digitalWrite(B_IA, LOW);
    digitalWrite(B_IB, HIGH);
}

void backward_forward( void )
{
    digitalWrite(A_IA, LOW);
    digitalWrite(A_IB, HIGH);
    digitalWrite(B_IA, HIGH);
    digitalWrite(B_IB, LOW);
}

void stop_stop( void )
{
    digitalWrite(A_IA, LOW);
    digitalWrite(A_IB, LOW);
    digitalWrite(B_IA, LOW);
    digitalWrite(B_IB, LOW);
}

void setup()
{
    pinMode(A_IA, OUTPUT);
    pinMode(A_IB, OUTPUT);
    pinMode(B_IA, OUTPUT);
    pinMode(B_IB, OUTPUT);

    stop_stop();

    pinMode(TRIG, OUTPUT);
    digitalWrite(TRIG, LOW);

    pinMode(ECHO, INPUT);

    _delay_ms(4000);
}

void loop()
{
    digitalWrite(TRIG, HIGH);
    _delay_us(10);
    digitalWrite(TRIG, LOW);
    while( digitalRead(ECHO) == LOW ) ;
    time1 = micros();
    while( digitalRead(ECHO) == HIGH ) ;
    time2 = micros();

//    data = ((((time2 - time1) / 2.0) / 1000000.0) * 350) * 100;
    data = (time2 - time1) * 0.0175;

    if ( data < 45 ) forward_backward();
    if ( data > 55 ) forward_forward();
}

//
// End
//
////////////////////////

В показанной программе реализованы все возможные направления движения платформы. Хотя реально используется только три функции управляющие моторами.

Есть в коде пара интересных строк:

if ( data < 45 ) forward_backward();
if ( data > 55 ) forward_forward();

Можно было написать так:

if ( data < 45 ) forward_backward();
else forward_forward();

Но в этом случае робот оказавшись перед препятствием стал бы слишком часто вызывать функции forward_backward и forward_forward.

Видео:


Очевидно эта платформа плохо подходит для улицы. Едет так криво, что дальше некуда.

Одного ультразвукового сенсора явно недостаточно. Для надежного избегания столкновений с препятствиями стоит добавить инфракрасный датчик препятствий. И контактные датчики не будут лишними.

Из серьезных недостатков следует отметить питание двигателей. Оно реализовано через линейный стабилизатор ардуино. Стабилизатор очень сильно греется. Что не удивительно.

Питание двигателей лучше организовать через импульсный понижающий преобразователь.