Универсальный внешний накопитель для всех iOS-устройств, совместим с PC/Mac, Android
Header Banner
8 800 100 5771 | +7 495 540 4266
c 9:00 до 24:00 пн-пт | c 10:00 до 18:00 сб
0 Comments

Инфракрасный датчик расстояния [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

Код

  1. #include <Servo.h>                          // подключение библиотеки Servo

  2.  

  3. #define SERVO  9                            // вывод для подключения сигнального провода серводвигателя

  4. #define IR     0                            // аналоговый вывод для подключения сигнального провода ИК-датчика расстояния

  5. #define LED1   3                            // вывод для подключения LED1

  6. #define LED2   5                            // вывод для подключения LED2

  7. #define LED3   6                            // вывод для подключения LED3

  8. #define LED4   11                           // вывод для подключения LED4

  9.  

  10. Servo myServo;                              // создаем объект класса Servo

  11. int dist1 = 0;                              // переменная для хранения дистанции в первой позиции

  12. int dist2 = 0;                              // переменная для хранения дистанции в второй позиции

  13. int dist3 = 0;                              // переменная для хранения дистанции в третьей позиции

  14. int dist4 = 0;                              // переменная для хранения дистанции в четвертой позиции

  15.  

  16. void setup()

  17. {

  18.     myServo.attach(SERVO);                  // подключаем объект серводвигателя к контакту SERVO (т.е. 9-му)

  19.     pinMode(LED1, OUTPUT);                  // Конфигурируем вывод LED1(т.е. 3-ий) как выход

  20.     pinMode(LED2, OUTPUT);                  // Конфигурируем вывод LED2(т.е. 5-ий) как выход

  21.     pinMode(LED3, OUTPUT);                  // Конфигурируем вывод LED3(т.е. 6-ий) как выход

  22.     pinMode(LED4, OUTPUT);                  // Конфигурируем вывод LED4(т.е. 11-ий) как выход

  23. }

  24.  

  25. void loop()

  26. {

  27.     // Осуществляем перемещение вала серводвигателя по 4 позициям

  28.     dist1 = readDistance(15);               // Измеряем расстояния с помощью ИК-датчика при перемещении вала серводвигателя на 15 градусов

  29.     analogWrite(LED1, dist1);               // Регулируем яркость светодиода LED1

  30.     delay(300);                             // Задержка перед следующим измерением

  31.  

  32.     dist2 = readDistance(65);               // Измеряем расстояния с помощью ИК-датчика при перемещении вала серводвигателя на 65 градусов

  33.     analogWrite(LED2, dist2);               // Регулируем яркость светодиода LED2

  34.     delay(300);                             // Задержка перед следующим измерением

  35.  

  36.     dist3 = readDistance(115);              // Измеряем расстояния с помощью ИК-датчика при перемещении вала серводвигателя на 115 градусов

  37.     analogWrite(LED3, dist3);               // Регулируем яркость светодиода LED3

  38.     delay(300);                             // Задержка перед следующим измерением

  39.  

  40.     dist4 = readDistance(165);              // Измеряем расстояния с помощью ИК-датчика при перемещении вала серводвигателя на 165 градусов

  41.     analogWrite(LED4, dist4);               // Регулируем яркость светодиода LED4

  42.     delay(300);                             // Задержка перед следующим измерением

  43. }

  44.  

  45. int readDistance(int pos)

  46. {

  47.     myServo.write(pos);                    // перемещаем вал сервопривода на 'pos' градусов

  48.     delay(600);                            // задержка

  49.     int dist = analogRead(IR);             // чтение данных с ИК-датчика расстояния

  50.     dist = map(dist, 50, 500, 0, 255);     // преобразование к необходимому диапазону

  51.     return dist;                           // возврат значения расстояния, измеренного в текущей позиции вала серводвигателя

  52. }

wikihandbk.com

ИК датчик препятствий с определением направления

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

Схема ИК датчика с определением направления

Схема основана на 2 ИК диодах, ИК датчике 36 кГц, МК Tiny13 и нескольких светодиодах. Эти светодиоды используются для регулярной индикации состояния устройства — так что вы можете легко откалибровать его — тут есть такие возможности.

Датчик может обнаружить объект в 3-х различных положениях: ВЛЕВО, СРЕДНИЙ, ВПРАВО

Можно настроить расстояние детектирования в диапазоне от 2 см до 1,5 м потенциометром, который можно увидеть на схеме и на плате. Всякий раз, когда обнаруживается какое-либо изменение в состоянии объекта в поле зрения, сигнал INTERRUPT (IRQ) генерируется на внешние устройства. Благодаря этому процессу в процедуре обработки достаточно, чтобы прочитать состояние входов L и R и знать, что происходит. Возможные ситуации:

LR (левый/правый)

  1. 0 0 — нет объекта в поле зрения
  2. 1 0 — объект находится слева
  3. 0 1 — объект находится справа
  4. 1 1 — объект находится посередине.

Лучше всего ситуация показана на анимированном изображении.

Несмотря на то, что ИК-диоды работают на несущей частоте 36 кГц, это не мешает работе пульта (тем более этот датчик будет проверять переднюю часть, а у робота второй ИК-приемник для управления сзади).

Прерывание IRQ генерируется не только тогда, когда что-то появляется в зоне видимости датчика, но и когда оно исчезает из поля зрения. Это значительно облегчает работу процессора. Можно сказать что после чтения прерывания в такой процедуре — состояние просмотра датчика — также можно сразу ввести команды для управления двигателями ведущих колес или другими вещами.

Сама программа не сложна — она состоит из генерации несущей 36 кГц с помощью Timer0 и подачи ее попеременно к обоим ИК-диодам — после чего приём и анализ того что происходит.

Также введена буферизация нескольких показаний и только сравнение несколько из тех же самых сигналов запускают сигнал прерывания — он ведь должен быть устойчивым к различным типам помех, включая другие пульты дистанционного управления например телевизора (даже когда один синий LED быстро мигает несколько раз — красный светодиод, сигнализирующий о исходящем сигнале прерывания, срабатывает только один раз). Благодаря этому датчик не будет беспокоить главный процессор нестабильными состояниями когда объект находится на краю чувствительности.

Алгоритм работы программы

  1. Отправляем пакет, то есть несущую на короткое время на левый ИК-диод.
  2. Ждем короткий промежуток времени несколько миллисекунд.
  3. Проверка получает ли ИК-приемник какие-либо отражения.
  4. Если датчик их видит — значит на дороге слева какой-то объект.
  5. Затем делаем те же шаги, но с правым ИК-диодом.

Для суммирования и усреднения времени выполнения всего алгоритма, исправления ошибок и небольшого обобщения — пакеты отправляются в среднем каждые несколько десятков миллисекунд с каждого ИК-диода.

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

Схема ИК датчика без контроллера

А далее схема аналогичного датчика на TTL микросхемах, это для тех кто не любит микроконтроллеров и прошивок.

Еще одна приятная особенность этого датчика — возможность корректировать положение ИК-диодов, то есть если они установлены под прямым углом — будет самый широкий диапазон расстояний, если речь идет о видимости датчика по бокам — при увеличении минимального расстояния, с которого объект может быть обнаружен посередине, то есть в области нескольких сантиметров в центре перед датчиком ничего не обнаружено — объект должен быть слегка отодвинут. Но если слегка наклоним их внутрь, то сможем резко изменить условия работы и обнаружить даже тонкие объекты.

Если датчик не обнаруживает никаких отражений после ожидания — это означает что в пределах видимости препятствий нет и можно ехать вперед.

2shemi.ru

Отправить ответ

avatar
  Подписаться  
Уведомление о