Машинка-ардуинка — 2: ИК-датчики

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

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

На замену ему были заказаны Инфракрасные датчики приближения! Цена из совсем смешная (меньше доллара), правда пришлось добавить ещё около двух долларов на стоимость доставки. Приехали довольно быстро, каждый датчик был запаян в отдельный метализированный пакет. У некоторых были слегка погнуты светодиоды (как на фото), но они легко выпрямились пальцами.

Принцип действия инфракрасного датчика приближения

При подаче питания на датчик сразу включается инфракрасный светодиод (прозрачный на фото). Он работает непрерывно, всё время работы датчика. Инфракрасное свечение совершенно незаметно для человеческого глаза, однако хорошо видно через любую цифровую камеру (например, мобильного телефона).

При наличии в зоне свечения светодиода препятствия (примерно на расстоянии 5-10 сантиметров), свет отражается и принимается фотодиодом (чёрный на фото).

Дополнительно, на плате датчика я заметил два светодиода красного цвета, которые очень помогают в настройке робота:

  • первый светится всё время работы датчика, свидетельствует о наличии питания на плате и о работе инфракрасного светодиода.
  • второй светится только при наличии в зоне действия ИК-светодиода освещённого им препятствия. Очень помогает визуально без дополнительных инструментов определить, сработал датчик или нет.

Подключение и настройка

На датчике три контакта:

  • VCC (питание, +5 вольт)
  • GND (земля, минусовой провод)
  • OUT (выход, сигнал, информация о наличии препятствия).

Обратите внимание, порядок контактов на схеме подключения и на самом модуле (фото выше) отличается. При подключении внимательно читайте надписи на контактах!

При подключении модулей к контроллеру Arduino я стараюсь не пользоваться паяльником. Во-первых есть риск перегреть и сжечь дорогую электронику, во-вторых компоненты Arduino как правило многократно собираются и разбираются в различных комбинациях, а многократная пайка портит детали. Для решения этой проблемы я заказал недорогой комплект соединительных проводов трёх типов (мама-мама, мама-папа и папа-папа). Провода удобные, яркие, соединены между собой некрепко — можно оторвать нужное количество. Использовал только провода мама-мама, и столкнулся с необычайной жесткостью разьёмов. Чтобы надеть их на контакт, нужно приложить силу, достаточную для изгиба контакта, так что надевать их нужно очень осторожно. Ранее я использовал самопайные соединительные провода, сделанные из обрывков проводов со штекерами со старых компьютерных системных блоков (лампочки Power, HDD, кнопки Power, Reset, подключаемые от корпуса на материнскую плату). Вот с ними никаких проблем — надеваются и снимаются легко!

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

Итоги

При аналогичной скорости передвижения робот стал заметно умнее! Стал обнаруживать препятствия чётче, хоть и на меньшем расстоянии.

Однако был замечен глюк при очень ярком освещении (солнечный свет через окно). В этом случае датчики постоянно получали освещение и постоянно считали что препятствие перед автомобилем существует.

Фотогалерея

На деревянную «мачту» на платформе не обращайте внимания — это я пытался закрепить на высоте приёмник от инфракрасного пульта управления, но об этом — в следующей статье!

Текст программы управления:

int IN1 = 7; // Input1 моторшилда подключен к выводу 7
int IN2 = 6;
int IN3 = 5;
int IN4 = 4;
int EN1 = 8; //9
int EN2 = 3;
int i;
const int LeftIK = 0;
const int RightIK = 1;

void setup()
{
pinMode (EN1, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (EN2, OUTPUT);
pinMode (IN4, OUTPUT);
pinMode (IN3, OUTPUT);
}

unsigned int impulseTime=0;
unsigned int dist1=0;
unsigned int dist3=0;

 

void loop()
{
int dist1 = analogRead(LeftIK); // Задаем переменную analogValue для считывания показаний
if (dist1<100) // Если датчик сработал
{
analogWrite (EN1, 0); // Остановить двигатели
analogWrite (EN2, 0);

digitalWrite (IN1, HIGH); // поменять полярность на обратную
digitalWrite (IN2, LOW); // то есть задний ход
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite(EN1, 250); // правое колесо назад
// analogWrite(EN2, 180); // левое не двигаем
delay(150);
analogWrite (EN1, 0);
analogWrite (EN2, 0);
}
int dist3 = analogRead(RightIK); // Задаем переменную analogValue для считывания показаний
if (dist3<100) // Если датчик сработал
{
analogWrite (EN1, 0);
analogWrite (EN2, 0);

digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
// analogWrite(EN1, 0); // правое колесо не двигаем
analogWrite(EN2, 250); // левое колесо назад
delay(150);
analogWrite (EN1, 0);
analogWrite (EN2, 0);
}

if ((dist1>100) and (dist3>100))
{
// digitalWrite(ledPin, LOW);
digitalWrite (IN2, HIGH);
digitalWrite (IN1, LOW);
digitalWrite (IN4, HIGH);
digitalWrite (IN3, LOW);
analogWrite(EN1, 130); // Правое газ 130
analogWrite(EN2, 195); // ЛЕВОЕ газ 170
// разный газ для уравновешивания скорости колёс
}

}

Апрель 10th, 2017 by