Содержание
Обзор Датчик линии/препятствия KY-033
Датчик линии – это оптический модуль, предназначенный для обнаружения препятствий в виде белых или чёрных линий. Основным его элементом является оптопара TCRT5000, состоящая из инфракрасного светодиода и фототранзистора. Внешний вид датчика показан на рисунке №1.
Рисунок №1 – внешний вид датчика линии/препятствия.
Согласно документации, инфракрасный диод излучает свет с длиной волны 950nm, что позволяет достоверно определять препятствия на расстоянии от 1мм до 25мм. Также в состав модуля входят компаратор, подстроечный резистор и контрольный светодиод. Подстроечным резистором выбирается порог срабатывания датчика на разный оттенок чёрного цвета. При максимальном сопротивлении датчик сработает на сером оттенке, а при минимальном сопротивлении – только на чёрном. Факт срабатывания сопровождается загоранием контрольного светодиода и подачей логического нуля на сигнальный вывод датчика. Следует отметить, что для удобства монтажа, по обе стороны оптического элемента расположены два крепёжных отверстия. Это позволяет более точно позиционировать датчик или группу датчиков на необходимом расстоянии от препятствия. Для исключения взаимного влияния светодиода и фототранзистора они конструктивно разделены небольшой перегородкой.
Что касается принципа работы, то он очень прост. При подаче питания на модуль, инфракрасный светодиод начинает излучать свет, который отражаясь от белой поверхности попадает на фототранзистор. В таком режиме на выводе OUT (SIGNAL) будет установлена логическая единица. Как только в зону видимости датчика попадает чёрный объект, световой поток, поглощаясь этим самым объектом, перестаёт доходить до фототранзистора и компаратор переключает вывод OUT (SIGNAL) в логический ноль. Более наглядно этот процесс показан на рисунке №2.
Рисунок №2 – логика работы датчика линии
При проектировании устройств с использованием датчика линии, необходимо чётко следить за границами приближения/удаления модуля от исследуемой поверхности. Если фотоэлемент будет слишком приближен, то перегородка не даст пройти световому потоку от ИК-диода к фототранзистору, даже при самой белой поверхности. Та же ситуация произойдёт и при чрезмерном удалении фотоэлемента, так как весь световой поток попросту рассеется в воздушной среде не дойдя до объекта-отражателя.
Технические характеристики
Из основных технических характеристик можно выделить следующие:
- Расстояние уверенного определения препятствия: 1-25 мм;
- Диапазон рабочего напряжения питания: 3,3 – 5 В;
- Тип используемого ИК датчика: TCRT5000;
- Длина волны излучения: 950nm;
- Тип используемого компаратора: LM393;
- Максимальная нагрузка на выход компаратора: 15 мА;
- Физические размеры модуля: 40х11х11 мм.
Подключение к Arduino
В своём составе, датчик линии имеет всего 3 выхода (VCC, GND и S/OUT). Выводы VCC и GND предназначены для подачи питания на модуль. Вывод S (OUT) служит для регистрации срабатываний. Ввиду того, что датчик способен выдавать только логические «0» и «1», вывод S (OUT) можно цеплять на любой цифровой пин Arduino. На рисунке №3 изображена схема подключения датчика у которого сигнальный выход идёт на пин D2 Arduino.
Рисунок №3 – схема подключения датчика линии к Arduino UNO
Работа с датчиком или группой датчиков на программном уровне сводится к простейшей обработке состояний цифровых входов и не должна вызывать сложностей даже у начинающего программиста. Ниже приведён скетч с комментариями, позволяющий отслеживать моменты срабатывания одного датчика согласно схемы на рисунке №3.
// Макроопределение для подключения датчика линии к пину №2 Arduino #define PIN_SENSOR 2 void setup() { // Инициализируем работу с серийным портом для вывода отладочной информации Serial.begin(9600); // Настраиваем на вход пин, к которому подключен датчик линии. // Здесь нет необходимости включать внутреннюю подтяжку пина к VCC, т.к. // модуль сам заботится о формировании логической "1" при отсутствии цели pinMode(PIN_SENSOR, INPUT); } void loop() { // Контролируем датчик с периодичностью около 200мс if(digitalRead(PIN_SENSOR)) { // Датчик не срабатывает Serial.println("LIGHT"); } else { // Датчик срабатывает Serial.println("BLACK"); } delay(200); }
В результате работы программы, при наличии чёрной линии в области видимости фотоэлемента, в окно терминала будет постоянно выводиться надпись BLACK, а при её отсутствии - LIGHT.
Пример использования
Одной из главных отраслей, где используется датчик линии является робототехника. В этой сфере есть направление, когда мобильный робот должен следовать по определённой траектории. Даже устраиваются целые соревнования на лучший алгоритм и скорость прохождения маршрута. В таких проектах, как правило, используется не один, а группа датчиков, с помощью которых робот определяет границы маршрута. Помимо роботов для соревнований, подобные датчики имеют и бытовые роботы-пылесосы. На рисунке №4 показан робот, оснащённый группой из 8 датчиков линии.
Рисунок №4 – роботизированная платформа с 8 датчиками линии
Ещё одной отраслью применения датчиков линии является всевозможные ЧПУ, где модули выступают в роли оптических концевиков, энкодеров, детекторов препятствий и т.п. В конечном итоге область применения данных модулей ограничивается лишь фантазией радиолюбителя.
Чтобы закрепить знакомство с датчиком KY-033, создадим небольшой проект станка для намотки катушек индуктивности. Идея заключается в следующем. С помощью стандартного терминала серийного порта, мы вводим нужное количество витков проектируемой катушки. Палата Arduino, обрабатывает поступившие данные и даёт команду на вращение мотора и соответственно привода с закреплённым сердечником. Датчик линии будет отсчитывать количество намотанных витков по специально нанесённой метке на вращающуюся часть привода. Если количество витков будет равно заданному в терминале – мотор остановится с выводом соответствующего сообщения. На рисунке №5 схематически отражена идея проекта.
Рисунок №5 – структурная схема проекта намоточного станка
Как видно из вышеприведенного рисунка, оптический элемент датчика линии располагается под контролируемой зоной, окрашенной в белый цвет. На эту зону в одном единственном месте нанесена чёрная метка, которая будет фиксироваться датчиком при каждом очередном обороте вала. Arduino будет следить за этим процессом и отключать двигатель по достижению конца счёта. Со структурой проекта разобрались – перейдём к схемному и аппаратному решению.
В роли центральной платы управления выберем Arduino Uno. Крутить привод с держателем сердечника будет 12-вольтовый двигатель постоянного тока со встроенным редуктором. С датчиком линии мы уже знакомы – остаётся силовая управляющая часть.
Дело в том, что питать мотор напрямую от платы Arduino мы не можем, так как у последней просто не хватит мощности, поэтому управление двигателем необходимо осуществлять либо через реле, либо через транзистор. Выбираем полевой N-канальный транзистор IRL540N, управляемый логическим уровнем, как наиболее подходящее решение для данного проекта. На рисунке №6 изображена схема подключения всех составляющих элементов проекта.
Рисунок №6 – электрическая схема намоточного станка
Диод 1N4007, используемый в схеме, защищает полевой транзистор от пробоя высоким напряжением самоиндукции, которое возникает во время размыкания индуктивной нагрузки, т.е. двигателя. Резистор 220 Ом ограничивает ток микроконтроллерного выхода, а резистор 100к разряжает затвор, гарантировано отключая двигатель при логическом нуле. Также особое внимание следует обратить на то, что двигатель питается от внешнего источника 12В, минус которого в обязательном порядке соединяется с минусом платы Arduino.
Программа будет составлена по принципу конечного автомата, т.е. в каждый момент времени будет обрабатываться конкретное событие, а именно:
- Фаза №1. При подаче питания программа определяет в каком состоянии находится вал мотора с отметкой. Последняя должна находиться точно над фотоэлементом датчика линии. Если это не так – мотор вращается и выставляет вал в начальное положение. С этого момента можно закреплять проволоку будущей катушки в начале сердечника.
- Фаза №2. В терминале выводиться сообщение с запросом о вводе требуемого количества витков. После нажатия клавиши ENTER, начинается вращение двигателя.
- Фаза №3. Программа отслеживает каждый оборот путём фиксации чёрной отметки и сравнивает с заданным до этого числом в терминале. Как только счётчик достигнет конца, пользователь получит сообщение и алгоритм повторится.
Ниже приведёт программный код с подробными комментариями.
#define PIN_LINE_SENSOR 2 // Пин для подключения датчика линии #define PIN_MOTOR 7 // Пин для подключения схемы управления мотором uint8_t globalState = 0; // Глобальное состояние всей системы uint8_t lineSensorPrevState = 0; // Предыдущее состояние датчика линии uint8_t lineSensorCurrentState = 0; // Текущее состояние датчика линии String inString = ""; // Строка для получения из порта кол-ва витков int turnsNumber = 0; // Кол-во необходимых витков для намотки int turnsCount = 0; // Счётчик намотанных витков void setup() { Serial.begin(9600); // Инициализируем последовательный порт pinMode(PIN_LINE_SENSOR, INPUT); // Настройка на вход пина датчика линии pinMode(PIN_MOTOR, OUTPUT); // Настройка на выход пина управления мотором digitalWrite(PIN_MOTOR, LOW); // Останавливаем мотор при подаче питания } void loop() { lineSensorCurrentState = digitalRead(PIN_LINE_SENSOR); // Опрашиваем состояние датчика if(globalState == 0) { // Устанавливаем двигатель в начальное положение // Если зафиксирована чёрная отметка - двигатель выставлен, двигаемся дальше. // Иначе включаем мотор и дожидаемся фиксации начального положения if(lineSensorCurrentState == 0) { lineSensorPrevState = lineSensorCurrentState; digitalWrite(PIN_MOTOR, LOW); Serial.println("Motor in start position"); Serial.print("Enter coil turns number: "); globalState = 1; } else digitalWrite(PIN_MOTOR, HIGH); } else if(globalState == 1) { // Ожидаем ввода количества витков пользователем if(Serial.available() > 0) { // Считываем из порта введённое значение char inChar = Serial.read(); // Читаем очередной байт inString += (char)inChar; // Склеиваем всё в оду строку if (inChar == '\n') { // Если зарегистрирован конец строки turnsNumber = inString.toInt(); // Переводим строку в числовой формат Serial.println(""); // Переходим на новую строку для удобства вывода inString = ""; // Очищаем строку приёмного буфера if(turnsNumber > 0) { // Если введённое пользователем число > 0 digitalWrite(PIN_MOTOR, HIGH); // Включаем мотор globalState = 2; // Переходим к фазе намотки } else globalState = 0; // Иначе возвращаемся в самое начало } } } else if(globalState == 2) { // Начало оборота if(lineSensorCurrentState == 1 && lineSensorPrevState == 0) { lineSensorPrevState = lineSensorCurrentState; globalState = 3; } } else if(globalState == 3) { // Конец оборота if(lineSensorCurrentState == 0 && lineSensorPrevState == 1) { lineSensorPrevState = lineSensorCurrentState; turnsCount++; // Суммируем обороты if(turnsCount == turnsNumber) { // Если кол-во витков равно заданному в терминале Serial.print("Turn number: "); Serial.println(turnsCount); Serial.println("Completed"); // Информируем об окончании намотки Serial.println("--------------------------------------"); // Очищаем счётчик витков и заданного в терминале количества turnsCount = 0; turnsNumber = 0; digitalWrite(PIN_MOTOR, LOW); // Останавливаем мотор globalState = 0; // Переходим в начальную фазу } else { // Иначе, если намотка ещё не окончена, выводим инфо в терминал о витках Serial.print("Turn number: "); Serial.println(turnsCount); globalState = 2; // Переходим в фазу начального оборота } } } }
Вот таким нехитрым способом можно приспособить датчик линии под свои нужды. При желании проект можно расширить, добавив дисплей, кнопки управления, дополнительный двигатель для автоматического распределения обмотки по всей поверхности сердечника и т.п. На рисунке №7 показан собранный прототип намоточного станка.
Рисунок №7 – прототип намоточного станка
Как видно из вышеприведенного рисунка, с левой стороны двигателя надето колесо с нанесённой чёрной отметкой. Фотоэлемент датчика линии направлен в сторону колеса и чётко фиксирует прохождение метки через своё поле зрения. На этом же валу справа закреплён П-образный держатель, в который вставлен предполагаемый каркас будущей катушки. Силовая часть управления мотором расположилась на макетной плате. Последовательность работы со станком следующая:
- Включаем питание;
- Дожидаемся, когда двигатель автоматически установится в начальное положение (чёрная отметка должна оказаться под фотоэлементом датчика линии);
- Вставляем сердечник в держатель и фиксируем на нём один конец провода;
- Вводим в терминале необходимое количество витков и нажимаем Enter;
- Аккуратно придерживаем провод рукой и дожидаемся окончания намотки.
На рисунке №8 показано окно терминала, как результат работы программы. Здесь отображено два цикла работы. Изначально задан запрос на намотку 7-ми витков и после отсчёта нужного количества оборотов, повторяется опыт для намотки 3-х витков. Конец каждого цикла обозначен словом Completed с разделительной полосой.
Рисунок №8 – результат работы программы намоточного станка
FAQ. Часто задаваемые вопросы
1. В продаже помимо цифровых датчиков линии существую аналоговые. В чём их отличия друг от друга?
Аналоговый датчик линии способен различать оттенки серого цвета, в то время как цифровой только 2 состояния, установленные подстроечным резистором. Аналоговый датчик линии подключается к аналоговому входу Arduino, а его состояние опрашивается функцией analogRead(). Цифровой датчик опрашивается функцией digitalRead() и может быть подключен к любому цифровому пину Arduino.2. Как использовать датчик линии в качестве энкодера?
Для этой цели необходимо на вращающейся части энкодера нанести чередующиеся чёрно-белые полосы и установить напротив них датчик линии. Проанализировав изменения с помощью Arduino, можно вычислить угловую скорость и количество сделанных оборотов.3. Какое минимальное количество датчиков линии необходимо для построения простейшего робота, следующего по линии?
Чтобы заставить робота двигаться по линии достаточно 2-х датчиков. Они устанавливаются друг от друга на расстоянии, равном ширине полосы маршрута. Программа постоянно опрашивает состояние датчиков линии и в зависимости от показаний выдаёт питание на двигатели правого или левого колеса.