Инфракрасный датчик расстояния [Robotic & Microcontroller Educational Knowledgepage
Sharp GP2Y0A21YK
Для измерения расстояния до объекта существуют оптические датчики, работающие на методе триангуляции. Самые распространенные из них – это работающие на длине волны, инфракрасные (на английском языке infra-red, сокращенно IR) датчики расстояния с выходным аналоговым напряжением, производимые фирмой Sharp. У датчиков Sharp имеется IR LED с линзой, который излучает узкий световой луч. Отраженный от объекта луч направляется через другую линзу на позиционно-чувствительный фотоэлемент (на английском языке position-sensitive detector, сокращенно PSD). От местоположения падающего на PSD луча, зависит его проводимость. Проводимость преобразуется в напряжение и, к примеру, дигитализируя его аналого-цифровым преобразователем микроконтроллера, можно вычислить расстояние. Ниже приведенный рисунок показывает путь отраженного луча на различных расстояниях.
Путь светового луча IR измерителя расстояния
Выход датчика расстояния Sharp обратно пропорциональный – с увеличением расстояния это уменьшается и растет медленно. Точный график между расстоянием и выходом приведен в спецификации датчика. У датчиков, в соответствии с типом, имеется граница измерения, в пределах которой выход датчика является надежным. Измерение максимально реального расстояния ограничивают два аспекта: уменьшение интенсивности отражающегося света и невозможность PSD регистрировать изменение местоположения отображенного маленького луча. При измерении сильно отдаленных объектов, выход датчика остается приблизительно таким же, как и при измерении максимально отдаленных расстояний. Минимально измеряемое расстояние ограничено особенностями датчика Sharp, а именно – выходное напряжение на определённом расстоянии (в зависимости от датчика: 4-20 см) начинает резко падать при уменьшении расстояния. По существу это означает, что одному значению выходного напряжения соответствует два расстояния. Для предотвращения проблемы нужно избегать слишком близкого приближения объектов к датчику.
График напряжения-расстояния типичного IR измерителя расстояния Sharp
В комплекте датчиков Домашней Лаборатории есть инфракрасный измеритель расстояния Sharp GP2Y0A21YK с границей измерения 10-80 cм. Выходное напряжение датчика до 3 V в зависимости от измеряемого расстояния. Датчик подключается на модуль «Датчики» и его выходное напряжение направляется на канал 0 аналого-цифрового преобразователя AVR. На базе предыдущего задания датчиков, можно просто сделать программу, которая измеряет выходное напряжение измерителя расстояния, но вдобавок к этому целью данного задания является так же ознакомление с процессом перевода напряжения в расстояние.
В спецификации датчика GP2Y0A21YK приведен график зависимости между выходным напряжением и измеренным расстоянием. Этот график не является линейным, однако график обратной величины выходного напряжения и расстояния почти линейный, и с помощью него довольно просто найти формулу для преобразования напряжения в расстояние. Для нахождения формулы необходимо точки этого графика ввести в какую-либо программу обработки табличных данных и из них создать новый график. В программе обработки табличных данных на основе точек графика возможно автоматически вычислить линию тренда. Далее приведен график связи исправленной обратной величины между выходным напряжением GP2Y0A21YK и расстоянием вместе с линейной линией тренда. Выходное напряжение для упрощения формулы уже переведено в 10-битное значение аналогово-дигитального преобразователя с опорным напряжением +5 V.
График линеаризации расстояния и значения ADC
Как видно на графике, линия тренда (синяя) совпадает довольно точно с точками графика (красная линия). Такое совпадение достигнуто с помощью корректирующей константы расстояния. Корректирующая константа найдена методом проб и ошибок – испробованы разные числа, пока не были найдены те, при которых график покрыт линией тренда больше всего. Корректирующая константа для данного графика это +2, т.е. ко всем реальным расстояниям в графике прибавлено 2. Так как график очень похож на линейную линию тренда, можно сделать обобщение и сказать, что взаимосвязь между расстоянием и напряжением следующая:
1 / (d + k) = a ⋅ ADC + b
где
d – расстояние в сантиметрах
k – корректирующая константа (найдена методом проб и ошибок)
ADC – это значение дигитализированного напряжения
a – линейный член (значение выходит из уравнения линии тренда)
b – свободный член (значение выходит из уравнения линии тренда)
Из формулы можно выразить расстояние d:
d = (1 / (a ⋅ ADC + B)) – k
В принципе, этим уравнением можно вычислить расстояние, но это предполагает вычисления плавающей запятой, потому что в частном образуются дробные числа. Для микроконтроллера, оперирующего целыми числами, придется упростить формулу и перевести в большие множители. Разделив частное формулы на линейный член, получим следующий вид:
d = (1 / a) / (ADC + B / a) – k
Введя в формулу значение корректирующей константы и полученный из уравнения линии тренда линейный и свободный член (полученный из рисунка), получим формулу для вычисления расстояния:
d = 5461 / (ADC – 17) – 2
Эта формула вычислена 16-битными целыми числами и полностью подходит для AVR. Перед вычислением придется убедиться, чтобы значение ADC было выше 17, иначе получится деление на ноль или отрицательное расстояние, что не логично.
Далее приведена записанная в библиотеке Домашней Лаборатории функция перевода значения ADC в сантиметры. Линейный и свободный член, а также корректирующая константа не вписаны жестко в функцию, но они задаются объектами параметра структуры IR датчика расстояния. Сохраняя параметры отдельно в константе, есть возможность позже просто добавить в программу новые модели IR датчиков расстояния.
// // Структура параметров IR датчика расстояния // typedef const struct { const signed short a; const signed short b; const signed short k; } ir_distance_sensor; // // Объект параметров датчика GP2Y0A21YK // const ir_distance_sensor GP2Y0A21YK = { 5461, -17, 2 }; // // Перевод значения ADC датчика расстояния IR в сантиметры // Возвращает -1, если преобразование не удалось // signed short ir_distance_calculate_cm(ir_distance_sensor sensor, unsigned short adc_value) { if (adc_value + sensor.b <= 0) { return -1; } return sensor.a / (adc_value + sensor.b) - sensor.k; }
Для создания перевода нужно вызвать функцию ir_distance_calculate_cm первый параметр которого – это параметр объекта IR датчика расстояния, а второй – значение ADC. Функция возвращает вычисленное расстояние в сантиметрах. При неправильном расчете (т.е. при неестественном значении ADC) возвращает функция -1. Использование IR датчика расстояния и функции преобразования демонстрирует следующая программа. Используется буквенно-цифровой LCD экран, где отображаются результаты измерения. При неестественном расстоянии отображается вопросительный знак.
// // Пример программы IR датчика расстояния Домашней Лаборатории. // На LCD экране отображается измеренное расстояние в сантиметрах. // #include <stdio.h> #include <homelab/adc.h> #include <homelab/delay.h> #include <homelab/module/sensors.h> #include <homelab/module/lcd_alpha.h> // // Основная программа // int main(void) { signed short value, distance; char text[16]; // External sensor selection pin ex_sensors = PIN(G, 0); pin_setup_output(ex_sensors); pin_set(ex_sensors); // Настройка LCD экрана lcd_alpha_init(LCD_ALPHA_DISP_ON); // Очистка LCD экрана lcd_alpha_clear(); // Название программы lcd_alpha_write_string("Датчик расстояния"); // Настройка ADC преобразователя adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // Бесконечный цикл while (true) { // Считывание значения выходного напряжения датчика, округленного в 4 раза value = adc_get_average_value(0, 4); // Пересчет значения ADC в расстояние distance = ir_distance_calculate_cm(GP2Y0A21YK, value); // Возможно ли отобразить расстояние или сообщение об ошибке? if (distance >= 0) { sprintf(text, "%d cm ", distance); } else { sprintf(text, "Ошибка "); } // Отображение текста в начале второй строки LCD lcd_alpha_goto_xy(0, 1); lcd_alpha_write_string(text); // Пауза sw_delay_ms(500); } }
home.roboticlab.eu
Arduino:Примеры/Радиальный ИК-датчик расстояния — Онлайн справочник
Черновик |
Данный пример демонстрирует построение радиального дальномера, с помощью ИК-датчика, установленного на серводвигателе и 4 светодиодов. Расстояние измеряется в каждой из 4 позиций(15, 65, 115, 165 градусов),а яркость четырех светодиодов соответствует расстоянию до объекта.
В этом примере используется стабилизатор напряжения на 5В L4940V5 для питания сервопривода. Это является лучшим решением, по нескольким причинам. Хоть и в неподвижном положении сервоприводы потребляют небольшой ток, при выполнении команд ток потребления может достигать нескольких сотен миллиампер, что может привести к скачкам напряжения. При недостаточном напряжении питания вал сервопривода будет перемещаться неустойчиво. Поэтому сервоприводам необходимо обеспечить отдельным источником питания.
Необходимое оборудование
Цепь
Соберите схему согласно монтажной схеме. Прикрепите ИК-датчик к серводвигателю.
ОСТОРОЖНО! Выход стабилизатора напряжения не нужно соединять с шиной 5V платы Arduino. Соединить необходимо только шины земли стабилизатора и платы Arduino. |
Обратите внимание на конденсаторы на входе и выходе стабилизатора напряжения, они устраняют пульсации напряжения.
Схема включения стабилизатора напряжения
Распиновка стабилизатора напряжения L4940V5Код
#include <Servo.h> // подключение библиотеки Servo
#define SERVO 9 // вывод для подключения сигнального провода серводвигателя
#define IR 0 // аналоговый вывод для подключения сигнального провода ИК-датчика расстояния
#define LED1 3 // вывод для подключения LED1
#define LED2 5 // вывод для подключения LED2
#define LED3 6 // вывод для подключения LED3
#define LED4 11 // вывод для подключения LED4
Servo myServo; // создаем объект класса Servo
int dist1 = 0; // переменная для хранения дистанции в первой позиции
int dist2 = 0; // переменная для хранения дистанции в второй позиции
int dist3 = 0; // переменная для хранения дистанции в третьей позиции
int dist4 = 0; // переменная для хранения дистанции в четвертой позиции
void setup()
{
myServo.attach(SERVO); // подключаем объект серводвигателя к контакту SERVO (т.е. 9-му)
pinMode(LED1, OUTPUT); // Конфигурируем вывод LED1(т.е. 3-ий) как выход
pinMode(LED2, OUTPUT); // Конфигурируем вывод LED2(т.е. 5-ий) как выход
pinMode(LED3, OUTPUT); // Конфигурируем вывод LED3(т.е. 6-ий) как выход
pinMode(LED4, OUTPUT); // Конфигурируем вывод LED4(т.е. 11-ий) как выход
}
void loop()
{
// Осуществляем перемещение вала серводвигателя по 4 позициям
dist1 = readDistance(15); // Измеряем расстояния с помощью ИК-датчика при перемещении вала серводвигателя на 15 градусов
analogWrite(LED1, dist1); // Регулируем яркость светодиода LED1
delay(300); // Задержка перед следующим измерением
dist2 = readDistance(65); // Измеряем расстояния с помощью ИК-датчика при перемещении вала серводвигателя на 65 градусов
analogWrite(LED2, dist2); // Регулируем яркость светодиода LED2
delay(300); // Задержка перед следующим измерением
dist3 = readDistance(115); // Измеряем расстояния с помощью ИК-датчика при перемещении вала серводвигателя на 115 градусов
analogWrite(LED3, dist3); // Регулируем яркость светодиода LED3
delay(300); // Задержка перед следующим измерением
dist4 = readDistance(165); // Измеряем расстояния с помощью ИК-датчика при перемещении вала серводвигателя на 165 градусов
analogWrite(LED4, dist4); // Регулируем яркость светодиода LED4
delay(300); // Задержка перед следующим измерением
}
int readDistance(int pos)
{
myServo.write(pos); // перемещаем вал сервопривода на ‘pos’ градусов
delay(600); // задержка
int dist = analogRead(IR); // чтение данных с ИК-датчика расстояния
dist = map(dist, 50, 500, 0, 255); // преобразование к необходимому диапазону
return dist; // возврат значения расстояния, измеренного в текущей позиции вала серводвигателя
}
wikihandbk.com
ИК датчик препятствий с определением направления
Недавно начал заниматься сборкой самоходного робота, контролируемого ИК пультом и был вынужден самостоятельно разработать зональный инфракрасный датчик, который может распознавать положение объектов или их движение перед датчиком, происходящее слева направо или наоборот.
Схема ИК датчика с определением направления
Схема основана на 2 ИК диодах, ИК датчике 36 кГц, МК Tiny13 и нескольких светодиодах. Эти светодиоды используются для регулярной индикации состояния устройства — так что вы можете легко откалибровать его — тут есть такие возможности.
Датчик может обнаружить объект в 3-х различных положениях: ВЛЕВО, СРЕДНИЙ, ВПРАВО
Можно настроить расстояние детектирования в диапазоне от 2 см до 1,5 м потенциометром, который можно увидеть на схеме и на плате. Всякий раз, когда обнаруживается какое-либо изменение в состоянии объекта в поле зрения, сигнал INTERRUPT (IRQ) генерируется на внешние устройства. Благодаря этому процессу в процедуре обработки достаточно, чтобы прочитать состояние входов L и R и знать, что происходит. Возможные ситуации:
LR (левый/правый)
- 0 0 — нет объекта в поле зрения
- 1 0 — объект находится слева
- 0 1 — объект находится справа
- 1 1 — объект находится посередине.
Лучше всего ситуация показана на анимированном изображении.
Несмотря на то, что ИК-диоды работают на несущей частоте 36 кГц, это не мешает работе пульта (тем более этот датчик будет проверять переднюю часть, а у робота второй ИК-приемник для управления сзади).
Прерывание IRQ генерируется не только тогда, когда что-то появляется в зоне видимости датчика, но и когда оно исчезает из поля зрения. Это значительно облегчает работу процессора. Можно сказать что после чтения прерывания в такой процедуре — состояние просмотра датчика — также можно сразу ввести команды для управления двигателями ведущих колес или другими вещами.
Сама программа не сложна — она состоит из генерации несущей 36 кГц с помощью Timer0 и подачи ее попеременно к обоим ИК-диодам — после чего приём и анализ того что происходит.
Также введена буферизация нескольких показаний и только сравнение несколько из тех же самых сигналов запускают сигнал прерывания — он ведь должен быть устойчивым к различным типам помех, включая другие пульты дистанционного управления например телевизора (даже когда один синий LED быстро мигает несколько раз — красный светодиод, сигнализирующий о исходящем сигнале прерывания, срабатывает только один раз). Благодаря этому датчик не будет беспокоить главный процессор нестабильными состояниями когда объект находится на краю чувствительности.
Алгоритм работы программы
- Отправляем пакет, то есть несущую на короткое время на левый ИК-диод.
- Ждем короткий промежуток времени несколько миллисекунд.
- Проверка получает ли ИК-приемник какие-либо отражения.
- Если датчик их видит — значит на дороге слева какой-то объект.
- Затем делаем те же шаги, но с правым ИК-диодом.
Для суммирования и усреднения времени выполнения всего алгоритма, исправления ошибок и небольшого обобщения — пакеты отправляются в среднем каждые несколько десятков миллисекунд с каждого ИК-диода.
Помехи вообще не проявляются, когда речь идет о каком-либо искусственном освещении, конечно если не приблизить датчик ближе 20 см к люминесцентной лампе, тогда фактически светодиоды иногда будут мигать — хотя прерывание включится только один или два раза. Основной целью создания этого датчика было свести к минимуму влияние таких факторов, и это удалось.
Схема ИК датчика без контроллера
А далее схема аналогичного датчика на TTL микросхемах, это для тех кто не любит микроконтроллеров и прошивок.
Еще одна приятная особенность этого датчика — возможность корректировать положение ИК-диодов, то есть если они установлены под прямым углом — будет самый широкий диапазон расстояний, если речь идет о видимости датчика по бокам — при увеличении минимального расстояния, с которого объект может быть обнаружен посередине, то есть в области нескольких сантиметров в центре перед датчиком ничего не обнаружено — объект должен быть слегка отодвинут. Но если слегка наклоним их внутрь, то сможем резко изменить условия работы и обнаружить даже тонкие объекты.
Если датчик не обнаруживает никаких отражений после ожидания — это означает что в пределах видимости препятствий нет и можно ехать вперед.
2shemi.ru