Электрификация

Справочник домашнего мастера

Лазерный дальномер на ардуино

Дальномер — это устройство для измерения расстояния до некоторого предмета. Дальномер помогает роботам в разных ситуациях. Простой колесный робот может использовать этот прибор для обнаружения препятствий. Летающий дрон использует дальномер для баражирования над землей на заданной высоте. С помощью дальномера можно даже построить карту помещения, применив специальный алгоритм SLAM.

Содержание

1. Принцип действия

На этот раз мы разберем работу одного из самых популярных датчиков — ультразвукового (УЗ) дальномера. Существует много разных модификаций подобных устройств, но все они работают по принципу измерения времени прохождения отраженного звука. То есть датчик отправляет звуковой сигнал в заданном направлении, затем ловит отраженное эхо и вычисляет время полета звука от датчика до препятствия и обратно.Из школьного курса физики мы знаем, что скорость звука в некоторой среде величина постоянная, но зависящая от плотности среды. Зная скорость звука в воздухе и время полета звука до цели, мы можем рассчитать пройденное звуком расстояние по формуле: s = v*t где v — скорость звука в м/с, а t — время в секундах. Скорость звука в воздухе, кстати, равна 340.29 м/с. Чтобы справиться со своей задачей, дальномер имеет две важные конструктивные особенности. Во-первых, чтобы звук хорошо отражался от препятствий, датчик испускает ультразвук с частотой 40 кГц. Для этого в датчике имеется пьезокерамический излучатель, который способен генерировать звук такой высокой частоты. Во-вторых, излучатель устроен таким образом, что звук распространяется не во все стороны (как это бывает у обычных динамиков), а в узком направлении. На рисунке представлена диаграмма направленности типичного УЗ дальномера.Как видно на диаграмме, угол обзора самого простого УЗ дальномера составляет примерно 50-60 градусов. Для типичного варианта использования, когда датчик детектирует препятствия перед собой, такой угол обзора вполне пригоден. Ультразвук сможет обнаружить даже ножку стула, тогда как лазерный дальномер, к примеру, может её не заметить. Если же мы решим сканировать окружающее пространство, вращая дальномер по кругу как радар, УЗ дальномер даст нам очень неточную и шумную картину. Для таких целей лучше использовать как раз лазерный дальномер. Также следует отметить два серьезных недостатка УЗ дальномера. Первый заключается в том, что поверхности имеющие пористую структуру хорошо поглощают ультразвук, и датчик не может измерить расстояние до них. Например, если мы задумаем измерить расстояние от мультикоптера до поверхности поля с высокой травой, то скорее всего получим очень нечеткие данные. Такие же проблемы нас ждут при измерении дистанции до стены покрытой поролоном. Второй недостаток связан со скоростью звуковой волны. Эта скорость недостаточно высока, чтобы сделать процесс измерения более частым. Допустим, перед роботом есть препятствие на удалении 4 метра. Чтобы звук слетал туда и обратно, потребуется целых 24 мс. Следует 7 раз отмерить, прежде чем ставить УЗ дальномер на летающих роботов.

2. Ультразвуковой дальномер HC-SR04

В этом уроке мы будем работать с датчиком HC-SR04 и контроллером Ардуино Уно. Этот популярный дальномер умеет измерять расстояние от 1-2 см до 4-6 метров. При этом, точность измерения составляет 0.5 — 1 см. Встречаются разные версии одного и того же HC-SR04. Одни работают лучше, другие хуже. Отличить их можно по рисунку платы на обратной стороне. Версия, которая работает хорошо выглядит так:А вот версия, которая может давать сбои:

3. Подключение HC-SR04

Датчик HC-SR04 имеет четыре вывода. Кроме земли (Gnd) и питания (Vcc) еще есть Trig и Echo. Оба этих вывода цифровые, так что подключаем из к любым выводам Ардуино Уно:

HC-SR04 GND VCC Trig Echo
Arduino Uno GND +5V 3 2

Принципиальная схема устройстваВнешний вид макета

4. Программа

Итак, попробуем приказать датчику отправить зондирующий ультразвуковой импульс, а затем зафиксируем его возвращение. Посмотрим как выглядит временная диаграмма работы HC-SR04. На диаграмме видно, что для начала измерения нам необходимо сгенерировать на выводе Trig положительный импульс длиной 10 мкс. Вслед за этим, датчик выпустит серию из 8 импульсов и поднимет уровень на выводе Echo, перейдя при этом в режим ожидания отраженного сигнала. Как только дальномер почувствует, что звук вернулся, он завершит положительный импульс на Echo. Получается, что нам нужно сделать всего две вещи: создать импульс на Trig для начала измерения, и замерить длину импульса на Echo, чтобы потом вычислить дистанцию по нехитрой формуле. Делаем. int echoPin = 2; int trigPin = 3; void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { int duration, cm; digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); cm = duration / 58; Serial.print(cm); Serial.println(» cm»); delay(100); } Функция pulseIn замеряет длину положительного импульса на ноге echoPin в микросекундах. В программе мы записываем время полета звука в переменную duration. Как мы уже выяснили ранее, нам потребуется умножить время на скорость звука: s = duration * v = duration * 340 м/с Переводим скорость звука из м/с в см/мкс: s = duration * 0.034 м/мкс Для удобства преобразуем десятичную дробь в обыкновенную: s = duration * 1/29 = duration / 29 А теперь вспомним, что звук прошел два искомых расстояния: до цели и обратно. Поделим всё на 2: s = duration / 58 Теперь мы знаем откуда взялось число 58 в программе! Загружаем программу на Ардуино Уно и открываем монитор последовательного порта. Попробуем теперь наводить датчик на разные предметы и смотреть в мониторе рассчитанное расстояние.

Задания

Теперь, когда мы умеем вычислять расстояние с помощью дальномера, сделаем несколько полезных устройств.

  1. Строительный дальномер. Программа каждые 100мс измеряет расстояние с помощью дальномера и выводит результат на символьный ЖК дисплей. Для удобства полученное устройство можно поместить в небольшой корпус и запитать от батареек.
  2. Ультразвуковая трость. Напишем программу, которая будет «пищать» зуммером с различной частотой, в зависимости от измеренного расстояния. Например, если расстояние до препятствия более трех метров — зуммер издает звук раз в пол секунды. При расстоянии 1 метр — раз в 100мс. Менее 10см — пищит постоянно.

Ультразвуковой дальномер — простой в использовании, дешевый и точный датчик, который отлично выполняет свою функцию на тысячах роботов. Как мы выяснили из урока, у датчика есть недостатки, которые следует учитывать при постройке робота. Хорошим решением может стать совместное использование ультразвукового дальномера в паре с лазерным. В таком случае, они будут нивелировать недостатки друг друга. Вконтакте Facebook Twitter 1+

Подключение ультразвукового дальномера HC-SR04 к Arduino

Ультразвуковой дальномер HC-SR04 предназначен для измерения расстояния от устройства до объекта. Работа модуля основана на принципе эхолокации. Модуль посылает ультразвуковой сигнал и принимает его отражение от объекта. Измерив время между отправкой и получением импульса, не сложно вычислить расстояние до препятствия. Поскольку в основе работы устройства используется ультразвук, модуль плохо подходит для определения расстояния до звукопоглощающих объектов. Для идеального измерения расстояния поверхность объекта должна быть ровной и гладкой. В этой статье мы подключим ультразвуковой дальномер HC-SR04 к Arduino.

Схема подключения HC-SR04 к Arduino

Подключение ультразвукового датчика расстояния HC-SR04 к Arduino достаточно просто. Схема подключения показана на рисунке.
Контакт земли подключаем к выводу GND на плате Arduino, вывод питания соединяем с 5V. Trig и Echo подсоединяем к цифровым пинам платы.

Arduino HC-SR04
VCC Vcc
13 Trig
12 Echo
GND Gnd

Пример скетча

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

Результат

Установка библиотеки HC-SR04

Количество строк кода можно существенно уменьшить, используя библиотеку HCSR04 для работы с дальномером. Библиотеку можно установить из самой среды следующим образом:

  1. В Arduino IDE открываем менеджер библиотек: Скетч->Подключить библиотеку->Добавить .ZIP библиотеку…
  2. Выбираем .ZIP архив (HCSR04.zip) и кликаем Open/Открыть.
  3. Библиотека установлена.

Описание методов библиотеки HCSR04.zip

HCSR04(uint8_t, uint8_t, unsigned long)

Конструктор для создания экземпляра класса, первый параметр это номер trig пина, второй — echo, третий — timeout в микросекундах.

1 HCSR04(uint8_t trigPin, uint8_t echoPin, unsigned long timeout = 1000000);

begin()

Инициализация HC-SR04.

1 void begin();

getDistanceMm()

Возвращает расстояние в миллиметрах.

1 unsigned int getDistanceMm();

getDistanceCm()

Возвращает расстояние в сантиметрах.

1 unsigned int getDistanceCm();

getDistanceInch()

Возвращает расстояние в дюймах.

1 unsigned int getDistanceInch();

getDistanceMmFloat()

Возвращает расстояние в миллиметрах. Тип возвращаемых данных float.

1 float getDistanceMmFloat();

getDistanceCmFloat()

Возвращает расстояние в сантиметрах. Тип возвращаемых данных float.

1 float getDistanceCmFloat();

getDistanceInchFloat()

Возвращает расстояние в дюймах. Тип возвращаемых данных float.

1 float getDistanceInchFloat();

getDuration()

Это частный метод, который возвращает продолжительность в микросекундах — прошедшее время до объекта/препятствия и обратно.

1 unsigned long getDuration();

Проверить работоспособность библиотеки можно следующим примером:

Подключение HC-SR04 к Arduino и вывод на LCD1602

Чтобы не использовать компьютер для вывода информации, мы будем вывести данные о расстоянии на ЖКИ, в моём случае — это LCD1602 (два ряда по 16 символов). Лучше всего использовать PCF8574 — I2C модуль для LCD на базе HD44780. Подробнее в статье Подключение LCD1602 к Arduino по I2C (HD44780/PCF8574).

Схема подключения LCD1602 и HC-SR04 к Arduino

Подключение HC-SR04 к Arduino:

Arduino Pro Mini HC-SR04
VCC Vcc
13 Trig
12 Echo
GND Gnd

Подключение LCD1602 к Arduino:

Arduino Pro Mini LCD I2C модуль
GND GND
5V VCC
A4 SDA
A5 SCL

Материалы

Подключение LCD1602 к Arduino по I2C (HD44780/PCF8574)
HC-SR04 — ультразвуковой датчик расстояния
datasheets_HCSR04.pdf

Ардуино – уникальная система, представляющая собой пластилин в руках инженера, из которого он может слепить, что пожелает. Возможно это благодаря большому разнообразию датчиков и модулей разных направленностей. От простых чипов, измеряющих силу тока, до вещей вроде Arduino hc hc sr04.

Это специальный датчик, позволяющий, при помощи ультразвуковых волн, измерить расстояние до объекта, на который его направили. Несложно догадаться, что проще всего его применить для создания простого дальномера. Рассмотрим Arduino hc sr04 и какие нюансы в работе с ним стоит учитывать, прежде чем начать собирать проект.

1. Основы сборки дальномера на Ардуино с помощью датчика HC SR04

Если вы собираетесь собрать дальномер на Ардуино, то без HC SR04 просто не обойтись. Ведь именно этот модуль чаще всего применяют в подобных системах из-за его высокой востребованности, по причине простоты работы, доступности и низкой стоимости. При этом точность показаний остаётся на высоте, что очень важно в подобных системах. Из данного чипа можно собрать не только дальномер на Ардуино, но и полноценного робота, который будет чувствовать расстояние до объекта и обходить любое препятствие.

Однако сегодня мы рассмотрим именно вариант с дальномером на Аrduino, так как он идеально подойдёт для новичков в сфере, которые ещё не слишком хорошо разбираются в основах. Если же вы захотите затем модифицировать своё изобретение, то можно научить его моделировать полноценную трехмерную карту помещения, что будет удобно для тех, кто занимается дизайном и конструированием мебели или зданий. Но сначала стоит рассмотреть, как вообще работает данный прибор и какие основы сборки стоит усвоить, прежде чем создать лазерный дальномер на Ардуино своими руками.

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

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

Почему усреднённое?

Дело в том, что любой ультразвуковой датчик все равно будет ошибаться на десятые доли метра, связано это с тем, что различные материалы, окружение и прочие переменные могут повлиять на скорость движения и отражения от поверхности звука. А в данном проекте мы берём идеальную систему, которая в реальном мире работать не может.

Можно постараться учесть все эти факторы, но каждую переменную вы все равно не запрограммируете, поэтому наша задача – получить данные, максимально приближённые к показаниям профессиональных приборов, ведь дальномер Ардуино всё ещё далёк от них по точности.

Есть и ещё один нюанс, который вам стоит заранее учесть, собирая ультразвуковой дальномер Arduino – не все поверхности подходят для измерения. Дело в том, что некоторые материалы способны поглощать звук или слишком сильно искажать его движение, подобно тому, как черная рубашка поглощает электромагнитную световую волну.

Соответственно, лучше всего применять прибор к гладким и плоским поверхностям, которые не будут нарушать движения УВ, что также ограничивает его функционал. Но благодаря низкому ценнику и удобству работы датчик всё ещё остается достаточно популярным.

2. Что будет в уроке?

Мы соберем дальномер, который будет работать по следующему принципу: при приближении объекта на расстояние менее 4 сантиметров — загорается красный светодиод, иначе горит зеленый.

Достаточно простой пример, в котором мы проверим точность измерения расстояния дальномером hc-sr04. Основа проверки точности станет простая линейка 🙂

3. Инструменты

Чтобы лишний раз не бегать в магазин прямо посреди процесса сборки системы, лучше заранее подготовить все инструменты, что могут вам пригодиться. Так, стоит побеспокоиться, чтобы под рукой были:

  1. Паяльник. Хорошим выбором станут приборы с регулируемой мощностью, их можно приспособить к любой ситуации.
  2. Проводники. Естественно, датчик необходимо будет подсоединять к МК, и для этого не всегда подходят стандартные пины.
  3. Переходник под usb-порт. Если на вашем микроконтроллере нет встроенного порта, побеспокойтесь о том, чтобы его можно было подключить к ПК другим способом. Ведь вам необходимо будет подгружать дополнительные библиотеки и новую прошивку в ваш проект.
  4. Припой, канифоль и прочие мелочи, в том числе изолированное рабочее пространство.
  5. Сам чип и МК, а также, при необходимости, корпус будущего устройства. Наиболее опытные инженеры предпочитают распечатывать оболочку для своих проектов на 3Д принтере, однако, если вы живёте в крупном городе, не обязательно тратиться. Можете поискать компании, дающие в аренду принтеры.

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

Но, что хорошо, на работу устройства не оказывается никакого влияния со стороны ЭМ излучений и солнечной энергии. А в комплекте к датчику уже находятся нужные ресиверы и трансмиттеры, которые пригодятся, когда вы будете собирать ультразвуковой дальномер Ардуино.

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

4. Комплектующие

Так как мы решили пока ничего не паять — оптимальный набор деталей будет следующим:

  • 1 — Arduino UNO R3 (или аналог)
  • 1 — Ультразвуковой датчик расстояния HC-SR04
  • 1 — красный светодиод
  • 1 — зеленый светодиод
  • 2 — резистор 560 Ом
  • 1- макетная плата
  • 8 — проводов-перемычек (папа-папа)
  • 1 — линейка для измерения расстояния

5. Подключение датчика HC SR04

С подключением датчика не должно возникнуть никаких проблем. Достаточно с помощью проводников соединить пин на питание с источником или МК, а ввод и вывод, соответственно, присоединить непосредственно к МК. Воспользуйтесь схемой ниже для сборки схемы:

У самого сенсора SR04 следующие характеристики от которых вам стоит отталкиваться:

  1. Напряжение для питания – 5В.
  2. Работает в цепях с силой тока 15 мА.
  3. Если датчик не используется, то для поддержания его в пассивном состоянии всё ещё требуется до 2 мА.
  4. Угол обзора у модуля небольшой, всего 15 градусов.
  5. Разрешение сенсора – 3 десятых см.
  6. А вот угол для измерений составляет уже приятные 30 градусов.

Также на датчике имеются четыре вывода по стандарту 2.54 мм. В них входит контакт для питания с положительным напряжением +5В, пины для ввода и вывода сигнала и заземление.

В конечном варианте выглядеть устройство должно примерно таким образом:

6. Код

Код для нашего устройства ниже. Помните, что красный светодиод должен загораться при расстоянии менее 4 см.

/* Arduino HC-SR04 ультразвуковой датчик расстояния VCC подключается к 5v, GND к GND Echo к 13 пину на Arduino, Trig к 12 пину на Arduino Позитивная нога красного светодиода к 11 пину на Arduino Позитивная нога зеленого светодиода к 10 пину на Arduino */ #define trigPin 13 #define echoPin 12 #define led 11 #define led2 10 void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(led, OUTPUT); pinMode(led2, OUTPUT); } void loop() { long duration, distance; digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = (duration/2) / 29.1; if (distance < 4) { // На этом этапе происходит вкл/выкл светодиода digitalWrite(led,HIGH); // когда загорается красный, зеленый обязан выключится digitalWrite(led2,LOW); } else { digitalWrite(led,LOW); digitalWrite(led2,HIGH); } if (distance >= 200 || distance <= 0){ Serial.println(«Out of range»); // Вне диапазона } else { Serial.print(distance); Serial.println(» cm»); // тут тоже можно указать » см» } delay(500); }

Единственное, о чем стоит помнить, – далеко не все функции и библиотеки написаны профессионалами. Многие из них создаются такими новичками, как и вы, соответственно, старайтесь просматривать код, прежде чем заключать, что датчик не работает или выдаёт неправильные данные.

Но значительно лучше будет изучить основы программирования и С++, чтобы в дальнейшем самостоятельно писать многие вещи самому.

7. Запуск и настройка

При первом запуске устройства происходит следующее:

  1. Подается импульс на вход Trig.
  2. В самом датчике сигнал преобразуется в 8 импульсов, у которых частота достигает 40 кГц, их он, соответственно, и посылает вперёд.
  3. Доходя до препятствия, импульсы отражаются и возвращаются на приемник, происходят моментальные расчеты в МК, и вся информация подаётся на устройство вывода. В нашем случае – это консоль ПК, но в будущем мы сделаем урок, где данные будут выводиться на LED-экранчик.

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

Датчик пользуется большой популярностью и всё больше людей пишут свои решения для работы с ним.

Инфракрасный датчик расстояния

Обзор инфракрасного датчика расстояния

Инфракрасный датчик расстояния Sharp GP2Y0A является популярным выбором для различных проектов на базе Arduino, которым требуется точное измерение расстояния.

В датчиках Sharp установлен инфракрасный (IR) светодиод (LED) с линзой, который излучает узкий световой луч. Отраженный от объекта луч направляется через другую линзу на позиционно-чувствительный фотоэлемент (Position-Sensitive Detector, PSD). От местоположения падающего на PSD луча зависит его проводимость. Проводимость преобразуется в напряжение и, к примеру, оцифровывая его аналого-цифровым преобразователем микроконтроллера, можно вычислить расстояние.

Выход инфракрасного датчика расстояния Sharp обратно пропорциональный — с увеличением расстояния его значение медленно уменьшается. Вид графика зависимости между расстоянием и напряжением.

Датчики, в зависимости от их типа, имеют границы измерения, в пределах которых их выход может быть признан надежным. Измерение максимального реального расстояния ограничивают два фактора: уменьшение интенсивности отраженного света и невозможность PSD регистрировать незначительные изменения местоположения отображенного луча. В целом график зависимости между расстоянием и напряжением не является линейным, однако в пределах допустимых расстояний график обратной величины выходного напряжения и расстояния к линейности приближается достаточно близко, и с его помощью довольно просто получить формулу для преобразования напряжения в расстояние. Для нахождения такой формулы необходимо точки этого графика ввести в какую-либо программу обработки табличных данных и из них создать новый график. В программе обработки табличных данных на основе точек графика возможно автоматически вычислить линию тренда. Например, для датчика GP2Y0A021YK0F:

Технические характеристики инфракрасного дальномера Sharp

• Рабочее напряжение: 4,5 — 5,5 В; • Максимальный потребляемый ток: 40 мА (типичный — 30 мА); • Тип выходного сигнала: аналоговый; • Дифференциальное напряжение, большее диапазона распознавания расстояния: 2,0 В; • Время отклика: 38 ± 10 мс • Диапазон работы: • Датчик GP2Y0A41SK0F: 4 — 30 см; • Датчик GP2Y0A021YK0F: 10 см — 80 см; • Датчик GP2Y0A02YK0F: 20 см — 150 см;

Пример использования

Создадим пример подсчета посетителей магазина. Упростим задачу, предполагая, что вход осуществляется через неширокую дверь, и для входа и выхода разные двери. На входе ставим инфракрасный дальномер Sharp GP2Y0A21YK0F (20-150 cм) таким образом, чтобы при прохождении человека показания имели значения 10 – 50 см, при отсутствии людей 80 см. При обнаружении посетителя увеличиваем счетчик подсчета посетителей. Данные выводим на графический дисплей Nokia 5110. Для отображения информации с датчиков будем использовать ЖК-дисплей Nokia 5110. Это графический монохромный дисплей с разрешением 84×48 точек. Дисплей Nokia 5110 поставляется на плате в паре с контроллером PCD8544 и штыревым разъемом. Электропотребление дисплея позволяет питать его от выхода +3.3 В платы Arduino.
Для проекта нам понадобятся следующие детали:
• плата Arduino Uno
• макетная плата (Breadboard Half )
• инфракрасный датчик расстояния sharp GP2Y0A21YK0F
• дисплей Nokia 5110
• соединительные провода
Соберем схему, показанную на рисунке.

Запустим Arduino IDE. Создадим новый скетч и внесем в него следующее содержимое: //Инфракрасный датчик расстояния //3d-diy.ru // подключение библиотек для работы с дисплеем Nokia #include #include // Nokia 5110 // pin 3 — Serial clock out (SCLK) // pin 4 — Serial data out (DIN) // pin 5 — Data/Command select (D/C) // pin 6 — LCD chip select (CS) // pin 7 — LCD reset (RST) Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7); // аналоговый пин для подключения выхода Vo сенсора const int IRpin = A0; // переменные int value1; // для хранения аналогового значения unsigned long timevisitors; // время прохождения int count_visitors=0; // переменная подсчета посетителей void setup() { // запуск последовательного порта Serial.begin(9600); Serial.println(«start»); // инициализация дисплея display.begin(); // установить контраст фона экрана display.setContrast(60); display.clearDisplay(); // очистить экран display.setTextSize(1); // размер шрифта display.setTextColor(BLACK); // цвет // заставка display.setCursor(5,15); display.print(«Visitors: 0»); display.display(); delay(2000); } void loop() { // получаем сглаженное значение и переводим в напряжение value1=irRead(); if(value1>50) // фиксация прохождения { timevisitors=millis(); while(irRead()>50) ; if(millis()-timevisitors>300) // > минимального времени прохождения { Serial.println(«passage!!!»); count_visitors=count_visitors+1; // увеличение счетчика // вывод в монитор последовательного порта Serial.print(«count_visitors=»); Serial.println(count_visitors); // вывод на дисплей display.clearDisplay(); display.setCursor(5,15); display.print(«Visitors: «); display.print(count_visitors); display.display(); } } delay(200); } // Усреднение нескольких значений для сглаживания int irRead() { int averaging = 0; // переменная для суммирования данных // Получение 5 значений for (int i=0; i<5; i++) { value1 = analogRead(IRpin); // значение сенсора переводим в напряжение float volts = analogRead(IRpin)*0.0048828125; // и в расстояние в см int distance=32*pow(volts,-1.10); averaging = averaging + distance; delay(55); // Ожидание 55 ms перед каждым чтением } value1 = averaging / 5; // усреднить значения return(value1); } Работать с сенсорами SHARP очень просто — достаточно подключить к нему питание и завести вывод Vo на аналоговый вход Arduino. Значение получаемой функции analogRead представляет собой целое число от 0 до 1023. Таким образом, чтобы узнать напряжение на выходе сенсора, необходимо значение на аналоговом входе Arduino умножить на 0,0048828125 (5 В / 1024). Расстояние вычисляем по формуле distance=volts*0.0001831-0.003097. При чтении данных, при каждой итерации цикла, иногда приходят разные значения сигнала при одном и том же расстоянии. Датчик передает сигнал на аналоговый порт с некоторой амплитудой и иногда в момент считывания данных значение оказывалось отличным от нормального, потому что итерация приходится на провал. Для сглаживания значений, получаемых с дальномера используем функцию irRead(). Датчик обнаруживает попадание объекта в дверной проем. Далее ожидаем окончания прохода. Если это время больше минимального времени прохода (отсечение взмаха руки, пролет предмета и пр.) инкрементируем счетчик посетителей и выводим данные в последовательный порт и на дисплей. Для работы с дисплеем Nokia 5110 нам понадобятся Arduino библиотеки Adafruit_GFX и Adafruit_PCD8544.

Курс Arduino — Дальномеры

Дальномеры

В этом уроке мы поподробнее познакомимся с дальномерами.

Ультразвуковой дальномер HC-SR04

На сегодняшний день (2016 г) стоит не более 1$ на AliExpress.

Датчик имеет 4 вывода:

  • Vcc – На этот контакт подается питание в 5В.
  • Trig – На этот контакт нужно подать логическую единицу на 10мкс, чтобы дальномер испустил ультразвуковую волну.
  • Echo – После того, как ультразвуковая волна вернется обратно, на этот контакт будет подана логическая единица на время, пропорциональное расстоянию до объекта
  • Gnd – Этот контакт подключается к земле.

Ультразвуковой дальномер – работает по принципу “летучей мыши”. Он посылает ультразвуковую волну и считает время, за которое волна возвратится. Зная скорость звука и время, за которое волна пришла обратно, можно рассчитать расстояние до объекта.

С помощью этого дальномера мы соберем небольшой парктроник, который можно будет увеличить и собрать готовое устройство для парковки автомобиля. Еще я покажу, как можно использовать дальномер для управления своими устройствами.

Дальномер

Давайте соберем простенькую схему для того чтобы понять, как работает дальномер.

Код

#define ECHO 13 #define TRIG 12 void setup() { pinMode(ECHO, INPUT); // На ECHO нужно подать логическую единицу pinMode(TRIG, OUTPUT); //С TRIG мы будем считывать значение расстояния Serial.begin(9600); //Установим соединение с Serial портом } void loop() { //Подаем на TRIG HIGH и сразу LOW digitalWrite(TRIG, HIGH); digitalWrite(TRIG, LOW); //Считываем длину пришедшего сигнала в микросекундах int dist = pulseIn(ECHO, HIGH) / 54; // Делим на 54, чтобы перевести показания в см Serial.println(dist); //Выводим показания дальномера в Serial delay(300); //Ждем немного, чтобы глаз успевал различать показания }

Пояснения

pulseIn(ECHO, HIGH); — С помощью этой функции мы считали время, на которое на пине ECHO устанавливается значение HIGH. Это время считается в микросекундах.

В общем виде pulseIn(); можно записать так:

pulseIn(пин, значение, таймаут);

Пин – Пин, на котором будет производиться подсчет времени.

Значение – Уровень ожидаемого сигнала, при котором будет проводиться подсчет. HIGH или LOW.

Таймаут – время в микросекундах, в течение которого ожидается приход сигнала. По истечении таймаута значение, возвращаемое функцией, будет приравнено к нулю.

Так, с принципом работы дальномера разобрались. Время сделать парктроник для игрушечных машинок.

Парктроник

Схема парктроника выглядит так:

Код

#define ECHO 3 // Прием сигнала с дальномера #define TRIG 2 // Подача сигнала на дальномер #define COUNT 5 // Кол-во светодиодов #define BUZZ 6 // Пин для пищалки #define FIRST 9 // Первый пин светодиодов #define dist_setup 1 //Подстроечный коэффициент #define frequency 5000 void setup() { for(int i = 0; i < COUNT; ++i) //Обозначаем светодиоды как выход… { pinMode(i+FIRST, OUTPUT); } pinMode(ECHO, INPUT); //…ECHO как вход… pinMode(TRIG, OUTPUT); //…TRIG как выход… pinMode(BUZZ, OUTPUT); //…пищалку как выход Serial.begin(9600); //Установим соединение с Serial } void loop() { digitalWrite(TRIG, HIGH); //Подаем команду на дальномер digitalWrite(TRIG, LOW); int dist = pulseIn(ECHO, HIGH) / 54; //Измеряем расстояние до объекта dist = constrain(dist, 2, 60); //Полученные значения загоняем в диапазон от 2 до 60 //Сравниваем полученные показания и включаем нужный режим if (dist < 10) { all_led_on(); } else if ( dist < 20 * dist_setup) { four_led_on(); } else if (dist < 30 * dist_setup) { three_led_on(); } else if(dist < 40 * dist_setup) { two_led_on(); } else if(dist < 50 * dist_setup) { one_led_on(); } else { for(int i = 0; i < COUNT; ++i) { digitalWrite(i+FIRST, LOW); } noTone(BUZZ); } } // Описание режимов void one_led_on() { digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, LOW); digitalWrite(13, HIGH); tone (BUZZ, frequency, 1000); delay(1000); } void two_led_on() { digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, LOW); digitalWrite(12, HIGH); digitalWrite(13, HIGH); tone(BUZZ, frequency, 700); delay(700); } void three_led_on() { digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, HIGH); digitalWrite(12, HIGH); digitalWrite(13, HIGH); tone(BUZZ, frequency, 400); delay(400); } void four_led_on() { digitalWrite(9, LOW); digitalWrite(10, HIGH); digitalWrite(11, HIGH); digitalWrite(12, HIGH); digitalWrite(13, HIGH); tone(BUZZ, frequency, 200); delay(200); } void all_led_on() { for(int i = 0; i < COUNT; ++i) { digitalWrite(i+FIRST, HIGH); } tone(BUZZ, frequency, 5000); delay(5000); }

Пояснения

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

dist_setup – это коэффициент, с помощью которого можно регулировать расстояние до срабатывания парктроника.

У меня он равен единице. Если вам нужно уменьшить расстояние – нужно уменьшить коэффициент, но тогда он будет в виде 0.xxx. Для этого вводится переменная типа float.

Частоту писка можно также изменять. Для этого нужно изменить значение frequency. Но следует помнить, что пищит пьезоизлучатель ужасно. Крайне. И, мне кажется, что он быстро отобьет у вас желание им пользоваться дальше или дольше 5 минут.

Как вариант – понизить частоту до 20 Гц или подключить обычный динамик на 8 Ом, к примеру.

Пароль

Теперь попробуем сделать секретный шифр, который зажигает светодиоды. А если в схему включить сервомотор с задвижкой, то можно сделать замок на дверь или ящичек с паролем.

Внимание на схему.

Код

//Пины первого дальномера #define TRIG1 12 #define ECHO1 13 //Пины второго дальномера #define TRIG2 10 #define ECHO2 11 //Светодиоды #define FIRST 3 #define COUNT 5 //Кнопка сброса #define RESET 2 //Переменные для пароля int key1; int key2; int key3; void setup() { //Обозначение светодиодов как выход for( int i = 0; i < COUNT; i++) { pinMode(i+FIRST, OUTPUT); } //Обозначение пинов на дальномерах pinMode(TRIG1, OUTPUT); pinMode(ECHO1, INPUT); pinMode(TRIG2, OUTPUT); pinMode(ECHO2, INPUT); pinMode(RESET, INPUT_PULLUP); } void loop() { //Подача сигнала на дальномеры digitalWrite(TRIG2, HIGH); digitalWrite(TRIG2, LOW); int dist2 = pulseIn(ECHO2, HIGH,3000) / 54; digitalWrite(TRIG1, HIGH); digitalWrite(TRIG1, LOW); int dist1 = pulseIn(ECHO1, HIGH) / 54; //Дополнительная индикация «ввода» символов if(dist1 < 10 && dist2 < 10) { digitalWrite(5, HIGH); delay(100); } if(dist2 > 20 && dist2 < 25) { digitalWrite(4, HIGH); delay(100); } if(dist1 > 20 && dist1 < 25) { digitalWrite(6, HIGH); delay(100); } //Код пароля + индикация «ввода» символов if(dist2 > 10 && dist2 <15) { key1 = 1; digitalWrite(3, HIGH); delay(100); } if(dist1 > 10 && dist1 < 15) { digitalWrite(7, HIGH); delay(100); key1 = 0; } if(dist1 > 20 && dist1 < 25 && key1 == 1) { key2 = 1; } else if(dist2 > 20 && dist2 <25 || key1 == 0) { key1 = 0; key2 = 0; } if(dist1 < 10 && dist2 < 10 && key2 == 1) { key3 = 1; } if(key3 == 1) { for(int i = 0; i < COUNT; i++) { digitalWrite(i + FIRST, HIGH); } } if(key3 == 0) { for(int i = 0; i < COUNT; i++) { digitalWrite(i + FIRST, LOW); } } //Сброс пароля boolean res = digitalRead(RESET); if(res == 0) { key1 = 0; key2 = 0; key3 = 0; } }

Пояснения

Для того чтобы зажечь все пять светодиодов – нужно знать последовательность действий, которую нужно выполнять. Вот для вас задание – “Не смотря объяснения ниже, определить, какую же последовательность действий нужно выполнять, чтобы загорелись все пять светодиодов”

Это выполнимая задача, если вы читали первую часть курса и разобрались в работе функции if().

Разобрались? Если да – молодцы, а если нет – почти молодцы.

Всего есть три “символа ввода” – от 0 до 10, от 10 до 15 и от 20 до 25.

Состояние от 0 до 10 включается, если поднести обе руки на расстояние от 0 до 10 см к обоим дальномерам. Если это сделать – загорится желтый светодиод.

Состояние от 10 до 15 включится, когда вы поднесете руку к правому или левому дальномеру на расстояние от 10 до 15 см. О совершении этого действия вам подскажут крайний левый светодиод для левой руки и крайний правый – для правой.

Состояние от 20 до 25 включается в тот момент, когда расстояние от руки до одного из дальномеров будет от 20 до 25 см. Об этом вас проинформируют второй слева и второй справа светодиоды для левой и правой руки соответственно.

Стоит отметить, что выполнять последовательность нужно строго.

  • Поднести ПРАВУЮ руку на расстояние от 10 до 15.
  • После того, как загорелся крайний правый светодиод – поднести ЛЕВУЮ руку на расстояние от 20 до 25. Все это делается, не меняя положения правой руки.
  • После индикации второго слева светодиода – отвести ЛЕВУЮ руку влево, чтобы не загорелся крайний левый светодиод, иначе – код нужно будет набирать сначала. ПРАВУЮ руку приблизить на расстояние от 0 до 10, а ЛЕВУЮ подвести на это же расстояние, не задевая расстояние от 10 до 15
  • Светодиоды должны гореть и не реагировать на ваши действия.
  • Нажать кнопку RESET, для сброса пароля. Светодиоды должны потухнуть.

Каждое неверное движение сбрасывает пароль, и его нужно вводить заново. С первого раза может и не получиться, но спустя несколько минут тренировки, я уверен – все получится, и светодиоды загорятся.

После того, как у вас будет получаться зажечь все светодиоды, можно вам проверить себя и изменить код так, чтобы последовательность была другая – на ваше усмотрение. Можно сделать больше “символов”, а можно оставить те же, но сделать каждый символ с использованием двух дальномеров. Это будет заданием для самостоятельного решения.

Инфракрасный дальномер Sharp

С этими дальномерами все даже проще. Подключать их нужно, как и все аналоговые датчики. И даже можно без резистора на 10 кОм. Если вы по каким-то причинам этого не умеете, то это описано в моей статье про датчики.

Стоит такой 6-7$ на AliExpress

Терменвокс

Есть такой музыкальный инструмент, как терменвокс. И сейчас мы соберем подобие этого инструмента.

Код

// Обозначаем дальномер, кнопку и пищалку #define RFIND A5 #define BUT 9 #define BUZ 8 // Логические переменные для кнопки bool sound_on = false; bool but_up = true; void setup() { pinMode(RFIND, INPUT); pinMode(BUZ, OUTPUT); pinMode(BUT,INPUT_PULLUP); } void loop() { //Код для включения и выключения терменвокса bool but_now = digitalRead(BUT); if(but_up && !but_now) { delay(10); bool but_now = digitalRead(BUT); if(!but_now) { sound_on = !sound_on; } } but_up = but_now; //Код для терменвокса if(sound_on == 1) { int val, freq; val = analogRead(RFIND); //Со значениями constrain и map можно поиграть, как душе угодно val = constrain(val, 100, 400); freq = map(val, 100, 400, 1000, 2500); tone(BUZ, freq, 20); } }

Пояснения

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

Кнопка нужна для остановки или запуска нашего “Терменвокса”

Итог

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

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
Схема 1
Плата Arduino Arduino Uno 1 Поиск в Utsource В блокнот
Макетная плата Breadboard-half 1 Поиск в Utsource В блокнот
Соединительные провода «Папа-Папа» 4 Поиск в Utsource В блокнот
Дальномер HC-SR04 2 Поиск в Utsource В блокнот
Схема 2
Плата Arduino Arduino Uno 1 Поиск в Utsource В блокнот
Дальномер HC-SR04 1 Поиск в Utsource В блокнот
Соединительные провода «Папа-Папа» 15 Поиск в Utsource В блокнот
Макетная плата Breadboard-half 1 Поиск в Utsource В блокнот
Пьезоизлучатель 1 Поиск в Utsource В блокнот
Резистор 220 Ом 1 Поиск в Utsource В блокнот
Светодиод АЛ102Б 2 Поиск в Utsource В блокнот
Светодиод АЛ307В 1 Поиск в Utsource В блокнот
Светодиод АЛ307Д 2 Поиск в Utsource В блокнот
Схема 3
Плата Arduino Arduino Uno 1 Поиск в Utsource В блокнот
Дальномер HC-SR04 2 Поиск в Utsource В блокнот
Резистор 220 Ом 5 Поиск в Utsource В блокнот
Соединительные провода «Папа-Папа» 18 Поиск в Utsource В блокнот
Макетная плата Breadboard-full 1 Поиск в Utsource В блокнот
Светодиод АЛ307Б 4 Поиск в Utsource В блокнот
Светодиод АЛ307Д 1 Поиск в Utsource В блокнот
Кнопка тактовая 1 Поиск в Utsource В блокнот
Схема 4
Плата Arduino Arduino Uno 1 Поиск в Utsource В блокнот
Дальномер Sharp 1 Поиск в Utsource В блокнот
Кнопка тактовая 1 Поиск в Utsource В блокнот
Соединительные провода «Папа-Папа» 9 Поиск в Utsource В блокнот
Макетная плата Breadboard-half 1 Поиск в Utsource В блокнот
Пьезоизлучатель 1 Поиск в Utsource В блокнот
Добавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Инфракрасный дальномер (10-80см) GP2Y0A21YK0F (Датчик расстояния) для Arduino

Общие сведения

Инфракрасный дальномер GP2Y0A21YK0F — предназначен для измерения расстояния до препятствий от 10 до 80 см. Напряжение на аналоговом выходе датчика соответствует расстоянию до препятствия.

Характеристики

Подключение

Для удобства подключения к Arduino воспользуйтесь Trema Shield, Trema Power Shield, Motor Shield или Trema Set Shield.

Выход датчика (жёлтый провод) подключается к любому аналоговому входу Arduino.

Питание

Напряжение питания 5 В постоянного тока подаётся на вывод GND (чёрный провод) и Vcc (красный провод) датчика.

Подробнее о датчике

Датчик состоит из PSD (Position Sensitive Detector) — позиционно-чувствительного детектора, IRED (InfraRed Emitting Diode) — инфракрасного светодиода, оптических линз и схемы обработки сигналов.

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

Датчик способен измерять расстояние и выше 150 см, но корректные показания лежат в диапазоне от 20 до 150 см.

Формула расчета расстояния

L = K * VN, где:

  • L — расстояние в сантиметрах
  • V — напряжение на выходе датчика
  • K — коэффициент = 27,86
  • N — коэффициент = -1,15

Примеры

Вывод значения расстояния в монитор порта.

const uint8_t analog_Pin = 0; // Вывод к которому подключен датчик const double division_ADC = 0.0048828125; // Напряжение соответствующее одному делению АЦП (опорное напряжение / количество делений АЦП) = 5В / 1024 = 0.0048828125 double inputVoltage; // Рассчитанное напряжение полученное с датчика double distance_OBJ; // Рассчитанная дистанция до препятствия void setup(){ Serial.begin(9600); } void loop(){ inputVoltage = analogRead(analog_Pin)*division_ADC; // Рассчитываем напряжение на входе analog_Pin distance_OBJ = 27.86*pow(inputVoltage, -1.15); // Рассчитываем расстояние до объекта Serial.println(distance_OBJ); // Выводим полученное растояние delay(200); // Приостанавливаем выполнение программы на 0,2 сек }

Комплектация

  • 1x Инфракрасный дальномер GP2Y0A21YK0F;

Работа с инфракрасным дальномером Sharp

Добрый день, хочу поделиться своим методом работы с инфракрасными дальномерами Sharp на примере модели Sharp GP2D120 (4 — 40 см).
Я подробно опишу составление обрабатывающей функции и дам пример применения. Преимущество этой функции в том, что она позволяет использовать весь рабочий диапазон любого дальномера.
Ваш робот больше не будет терять препятствия.

1 — Читаем документацию

У каждого датчика уже есть замеренная вольт-амперная характеристика, которая находится по названию модели. Учитывая специфику датчиков, производитель поставил в соответствие выходному напряжению расстояние до препятствия:
Определяем по графику напряжение, соответствующее каждому расстоянию и записываем в два массива:
float voltage = {2.7, 2.34, 2.00, 1.78, 1.56, 1.4, 1.265, 1.06, 0.92, 0.8, 0.74, 0.66, 0.52, 0.42, 0.36, 0.32}; float distanse = {4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 25.0, 30.0, 35.0, 40.0}; int len = 16; // количество набранных в массив точек

2 — Реализуем интерполяцию

Вначале несколько раз (10) опросим датчик и возьмем среднее значение, чтобы избежать случайного шума:
int senPin = 0; // «Analog In», куда подключен датчик int out = 0; for (int i = 0; i < 10; i++){ out += analogRead(senPin); delay(8); // задержка получена опытным путём } out = out/10;
Зная, что в Ардуине analogRead() выдает значения от 0 до 1023, а датчики Sharp — от 0 до 5 Вольт, преобразуем out в вольты и найдем положение этого значения в массиве voltage:
int pos = 0; float volt_read = out * 0.00488758553; // 5 / 1023 = 0.00488758553 if((voltage > volt_read) && (voltage < volt_read)){ // убедились, что показания принадлежат рабочей области for (int i = 0; i < N-1; i++) { if(volt_read >= voltage){ pos = i; break; } } }
Предпоследний шаг.
Интерполировав график, рассчитываем расстояние соответствующее выходному вольтажу.
float y1 = voltage; float x1 = distance; float y2 = voltage; float x2 = distance; float distance_out = (x2 — x1)*(y1 — volt_read)/(y1 — y2) + x1; // следствие из подобия треугольников 123 и 145

3 — Собираем функцию

float getDistance(int senPin){ float voltage = {2.7, 2.34, 2.00, 1.78, 1.56, 1.4, 1.265, 1.06, 0.92, 0.8, 0.74, 0.66, 0.52, 0.42, 0.36, 0.32}; float distanse = {4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 25.0, 30.0, 35.0, 40.0}; int len = 16; int out = 0; int pos = 0; for (int i = 0; i < 10; i++){ out += analogRead(senPin); delay(8); } out = out/10; float volt_read = out * 0.00488758553; // 5 / 1023 = 0.00488758553 if((voltage > volt_read) && (voltage < volt_read)){ for (int i = 0; i < N-1; i++) { if(volt_read >= voltage){ pos = i; break; } } float y1 = voltage; float x1 = distance; float y2 = voltage; float x2 = distance; float distance_out = (x2 — x1)*(y1 — volt_read)/(y1 — y2) + x1; return distance_out } else return -1.0; }

4 — Правильно используем

Опытным путем я заметил, что функция лучше всего работает, если запускать ее с промежутком в 15 миллисекунд для любого количества дальномеров:

Digitrode

Простой лазерный дальномер на Arduino своими руками

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

В данном примере мы свяжем лазерный датчик расстояния ToF 10120 с Arduino и будем выводить получаемые с него данные на ЖК-дисплей.

Датчики типа ToF (Time-of-Flight) стали очень популярными благодаря своей надежности и простоте использования. Кроме того, лазерные датчики ToF, несмотря на более высокую цену относительно стоимости ультразвуковых датчиков, отлично подходят для высокочастотных приложений.

Лазерные датчики имеют тот же принцип работы, что и ультразвуковые: отправка сигнала и ожидание его возврата назад. Продолжительность между отправкой и получением называется временем полета (Time-of-Flight). Скорость известна заранее, длительность рассчитывается и делится на 2, в итоге мы можем найти расстояние.

Преимущество лазерных датчиков в том, что они очень малы по сравнению с другими типами, и могут использоваться для высокочастотных применений, таких как автофокусировка камеры.

Модуль ToF10120, который мы будем использовать в данном проекте, имеет 6 выводов: питание GND-VCC, RX-TX для UART и SDA-SCL для I2C. В этом примере мы будем использовать интерфейс I2C для подключения датчика к Arduino, а также добавим ЖК-экран с интерфейсом I2C, чтобы увидеть результаты измерений в мм.

Схема подключения Arduino, датчика расстояния ToF10120 и LCD-дисплея выглядит следующим образом.

Комментированный код программы получения данных от датчика расстояния следующий.

#include <Wire.h> unsigned char ok_flag; unsigned char fail_flag; unsigned short lenth_val = 0; unsigned char i2c_rx_buf; unsigned char dirsend_flag=0; void setup() { Wire.begin(); Serial.begin(9600,SERIAL_8N1); printf_begin(); } void loop() { int x=ReadDistance(); Serial.print(x); Serial.println(» mm»); } int serial_putc( char c, struct __file * ) { Serial.write( c ); return c; } void printf_begin(void) { fdevopen( &serial_putc, 0 ); } void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt) { unsigned short result=0; // шаг 1: дать указание датчику считать эхо-сигнал Wire.beginTransmission(82); // передать на устройство 82 (0x52) // адрес, указанный в документации — 164 (0xa4) // но i2c адресация использует старшие 7 бит, так что это 82 Wire.write(byte(addr)); // устанавливает адрес данных расстояния (адрес) Wire.endTransmission(); // прекратить передачу // Шаг 2: дожидаемся показаний delay(1); // в документации указано, что ждать нужно минимум 30 мкс // шаг 3: запрос показаний от датчика Wire.requestFrom(82, cnt); // запрос cnt байтов от ведомого устройства 82 (0x52) // шаг 5: получить показания от датчика if (cnt <= Wire.available()) { // если два байта были получены *datbuf++ = Wire.read(); // получить старший байт (перезаписывает предыдущее считывание) *datbuf++ = Wire.read(); // получить младший байт как младшие 8 бит } } int ReadDistance(){ SensorRead(0x00,i2c_rx_buf,2); lenth_val=i2c_rx_buf; lenth_val=lenth_val<<8; lenth_val|=i2c_rx_buf; delay(300); return lenth_val; }

Подключив компоненты и загрузив код в Arduino, можно протестировать устройство. Включите питание и наблюдайте за полученными показаниями сделанного своими руками лазерного дальномера. В документации на датчик максимальный диапазон составляет 1,8 метра, но, как показано ниже, можно измерить расстояние до 2 метров.

Простой дальномер на Arduino

Добрый день любители самоделок! Сегодня мы соберём простой дальномер на Arduino Pro Mini. Прибор способен измерять расстояние от 2 до 400 см. Погрешность данного устройства доходит всего до +/- 1-5 см, в зависимости от измеряемого расстояния.
Инструменты и материалы
-Arduino Pro mini
-Датчик hc-04
-Индикатор на tm1637
-Провода ( у меня — МГТФ 0,12 )
-Программатор
-Пластмассовый корпус
-Li-on аккумулятор
-Маленький выключатель
-Плата зарядки на TP4056
-Суперклей
-Паяльник
-Припой
-Канифоль
-Дрель, свёрла и т.д.
Шаг первый.Схема:
По схеме всё просто, без дополнений.
Шаг второй.Подготовка корпуса:
Сначала примеряем датчик и сверлом на 15 мм высверливаем два отверстия.
Далее сверлом на 3-3,5 мм делаем отверстие для micro-usb разъёма.
Подбираем сверло под диаметр выключателя и сверлим.
На крышке делаем «окошко» для семисегментного индикатора(на фото без обработки), и все неровности дорабатываем напильником.
Шаг третий.Прошивка:
В скетче выделены переменные которые можно подстроить для себя. Весь код закоментирован.
#include <Arduino.h> // библиотеки для работы #include <GyverTM1637.h> //————-Для настройки—————————————————————— bool Long = 0; // 0 — измеряем длину от датчика // 1 — измеряем длину от стенки корпуса, которая противоположна датчику unsigned int corpus = 10; // растояние от датчика до противоположной стенки корпуса (в сантиметрах) #define CLK 2 //пины для подключения #define DIO 3 #define TRIG 4 #define ECHO 5 //———————————————————————————————- unsigned int impulse=0; // переменные для расчёта unsigned int sm=0; GyverTM1637 disp(CLK, DIO); void setup() { pinMode(TRIG, OUTPUT); //задаём как выход pinMode(ECHO, INPUT); //задаём как вход disp.brightness(7); // яркость 0-7 disp.point(0); //выключаем двоеточие disp.clear(); //очищаем индикатор } void loop() { digitalWrite(TRIG, HIGH); //подаём 5 вольт delayMicroseconds(10); // задержка 10 микросекунд digitalWrite(TRIG, LOW); // подаём 0 impulse=pulseIn(ECHO, HIGH); // замеряем длину импульса sm=impulse/58; // переводим в сантиметры if(Long == 1){ // проверка настроек sm = sm+corpus; } if(sm <= 2){ // обнуляем ложные значения sm=1; } if(sm >= 405){ sm=1; } int integer = sm / 10; int decimal = sm % 10; decimal = decimal*10; disp.displayClock(integer,decimal); // вывод на индикатор delay(300); // задержка 0,3 сек. между выводом значений }
Далее подключаем программатор и прошиваем МК.
Шаг четвёртый.Сборка:
Так как устройство работает от аккумулятора,то лишние расходы заряда нам не нужны. Поэтому на плате Arduino выпаиваем светодиоды и кнопочку reset (для уменьшения размеров).
Приклеиваем на суперклей аккумулятор к корпусу. На АКБ приклеиваем плату зарядки, устанавливаем выключатель и спаиваем всё по схеме.
Приклеиваем датчик к корпусу и спаиваем всё по схеме.Сначала была идея приклеить плату на двухсторонний скотч, но потом было решено приклеить на суперклей.Индикатор можно прикрутить на винты или приклеить.
Шаг пятый.Тест:
Примечание: четвёртый сегмент всегда будет отображать 0. Это сделано для того, чтобы последний сегмент не был пустым. Получается если показание равно 270, то это означает, что расстояние равно 27 см.
Для уверенности, показания можно сверить с линейкой. Доставка новых самоделок на почту

Получайте на почту подборку новых самоделок. Никакого спама, только полезные идеи!

*Заполняя форму вы соглашаетесь на обработку персональных данных

Становитесь автором сайта, публикуйте собственные статьи, описания самоделок с оплатой за текст. .

Общее

Для точного трехмерного сканирования помещения я создал этот Lidar (LIght Detection And Ranging) турель. Основан он на Garmin ™ LIDAR-Lite v3, который сканирует свое окружение с помощью инфракрасного лазерного луча сама платформа вращается с помощью небольших серводвигателей. Это видео показывает, что в итоге получилось:

Время сканирования в основном зависит от выбранного шага серводвигателей. Диапазон составляет от менее минуты до 30 минут (полное разрешение, более 32 000 точек данных). Точность измерений составляет около 1 см, дальность до 40 метров.

Программное обеспечение для сбора и визуализации, которое я создал для этого проекта, может извлечь облако точек для дальнейшего использования (3D-печать, программное обеспечение CAD и т. Д.).

Аппаратная часть

С аппаратной точки зрения сканер довольно прост: два 9-граммовых микромотора контролируют оси вращения поворота и наклона. Корпус, конструкции, напечатан на 3D-принтере.

Что касается электроники, я использовал:

Файлы для 3D печати

  1. Arduino Nano : контроллер для турели. Он управляет серводвигателями и управляет лидаром, выполняя небольшое количество вычислений для вывода облака точек.
  2. LIDAR Lite V3 компактный, высокопроизводительный оптический датчик измерения расстояния Или более дешевый аналог TFmini Работать он будет на более коротком расстоянии (12м)
  3. Серводвигатели 9g SG90 приводы для поворота лидара. Хотя эти слабые двигатели являются основным слабым местом в системе, я использовал их просто потому, что они у меня уже были. Некоторые более мощные и менее «шаткие» сервоприводы определенно улучшат качество и скорость захвата.
  4. Конденсатор на 1000 мкФ этот большой электролитический конденсатор предотвращает перезагрузку микроконтроллера во время скачков тока, создаваемых как лидаром, так и двигателями.

Вот схема подключения моей лидарной башни:

Софт

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

Программное обеспечение

Код Arduino

Благодаря библиотекам Arduino Servo.h и LIDARLite.h, код для управления этими элементами стал намного проще. Основной рабочий процесс кода заключается в следующем:

Init. lidar, servos and serial; For YawAngle = 0 to 180 For PitchAngle = 0 to 180 Compute coordinates; Send value;

Если вы используете TFmini то вместо библиотеки LIDARLite.h вам потребуется библиотека TFMini.h

Микроконтроллер знает углы сервоприводов и расстояние до препятствия. Небольшое количество вычислений требуется, чтобы преобразовать угол поворота, угол наклона и информацию о дальности в гораздо более удобные координаты X, Y и Z.

Используя эти формулы преобразования сферических в декартовы системы координат, он выводит положение точки на последовательном порту.

Программное обеспечение для сбора и визуализации данных

Чтобы собирать, отображать и использовать данные, я создал программное обеспечение с использованием Processing. Это очень удобный Java-фреймворк с открытым исходным кодом, созданный для работы, связанной с графикой. LidarViewer считывает последовательный порт для получения данных; отображает его в виде трехмерного облака точек, которое мы можем масштабировать, перемещать, поворачивать и перемещать; и сохраняет его в файл, чтобы мы могли использовать его позже (например, в Meshlab).

Датчик Arduino VL53L0X является лазерным дальномером, который измеряет расстояние до целевого объекта в диапазоне до 2 метров.

О датчике VL53L0X

VL53L0X использует измерения дальности инфракрасного излучения для измерения дальности, что позволяет ему получать точные результаты независимо от цвета и поверхности цели.

Датчик VL53L0X от Adafruit (слева) и Pololu (справа)

Измерения расстояния могут быть считаны через цифровой интерфейс I²C. Плата имеет линейный регулятор 2,8 В и встроенные регуляторы уровня, которые позволяют ей работать в диапазоне входного напряжения от 2,6 В до 5,5 В, а расстояние между выводами 0,1″ облегчает использование со стандартными макетами без припоя.

График таблицы характеристик VL53L0X типичной производительности измерения дальности (в режиме по умолчанию):

Эффективный диапазон зависит от конфигурации, цели и среды. В техническом описании не указан минимальный диапазон, но эффективный предел составляет около 3 см.

Распиновка

Для использования платы VL53L0X необходимо как минимум четыре соединения (см. схему ниже):

  • VIN,
  • GND,
  • SCL,
  • SDA.

Вывод VIN должен быть подключен к источнику от 2,6 до 5,5 В, а заземление должно быть подключено к 0 вольт. Встроенный линейный регулятор напряжения преобразует VIN в источник питания 2,8 В для интегральной схемы VL53L0X.

Контакты I²C, SCL и SDA подключены к встроенным переключателям уровня, что делает их безопасными для использования при напряжениях свыше 2,8 В; они должны быть подключены к шине I²C, работающей на том же логическом уровне, что и VIN.

Вывод XSHUT является входом, а вывод GPIO1 — выходом с открытым стоком; оба контакта вытянуты платой до 2,8 В. Они не подключены к переключателям уровня на плате и не допускают 5 В, но их можно использовать как есть со многими микроконтроллерами 3,3 В и 5 В: микроконтроллер может считывать выходной сигнал GPIO1, пока его логический верхний порог ниже 2,8 В, и микроконтроллер может чередовать свой собственный выход между состояниями низкого и высокого импеданса, чтобы управлять выводом XSHUT. В качестве альтернативы, 4-канальный двунаправленный логический переключатель уровня может использоваться снаружи с этими выводами.

PIN (пин, вывод) Описание
VDD Регулируемый выход 2,8 В. Почти 150 мА доступно для питания внешних компонентов. Если вы хотите обойти внутренний регулятор, вместо этого вы можете использовать этот вывод в качестве входа 2,8 В с отключенным VIN.
VIN Это основной источник питания от 2,6 до 5,5 В. Переключатели уровня SCL и SDA поднимают линии I²C высоко до этого уровня.
GND Заземление (0 В) для подключения вашего источника питания.
SDA Сдвинутая по уровню линия данных I²C: ВЫСОКИЙ (HIGH) это VIN, НИЗКИЙ (LOW) — это 0 В
SCL Линия синхронизации I²C со сдвигом уровня: ВЫСОКИЙ (HIGH) это VIN, НИЗКИЙ (LOW) — это 0 В
XSHUT Этот вывод является активным-низким входом отключения; плата тянет его до VDD, чтобы включить датчик по умолчанию. Низкий уровень этого вывода переводит датчик в аппаратный режим ожидания. Этот вход не смещен по уровню.
GPIO1 Программируемый выход прерывания (логический уровень VDD). Этот вывод не сдвинут по уровню.

Принципиальная схема датчика

Схема подключения датчика

Мы подключаем датчик VL53L0X к Ардуино согласно следующей схеме:

В случае платы Arduino на 5 В включая Arduino Uno, Leonardo, Mega или Pololu A-Star 32U4:

Arduino -> VL53L0X
5V <-> VIN
GND <-> GND
SDA <-> SDA
SCL <-> SCL

В случае плат Arduino 3.3 В включая Arduino Due:

Arduino -> VL53L0X
3V3 <-> VIN
GND <-> GND
SDA <-> SDA
SCL <-> SCL

На схеме выше я обозначил выводы SDA и SCL.

Библиотека VL53L0X

По ссылке выше вы можете скачать библиотеку для этого датчика. Данная библиотека предназначена для работы с Arduino IDE версии 1.6.x или выше. Не знаю, работает ли она с более ранними версиями. В целом, эта библиотека должна поддерживать любую Arduino-совместимую плату, включая контроллеры Pololu A-Star 32U4.

Установка библиотеки

Если вы используете версию Arduino IDE 1.6.2 или более позднюю, то данная библиотека уже есть в «Менеджере библиотек» (англ. — Library Manager), что позволяет нам установить её через IDE.

В нашей среде разработки Ардуино мы выбираем:

Скетч -> Подключить библиотеку -> Управлять библиотеками

Далее мы попадаем в Менеджер библиотек, где начинаем вводить название библиотеки VL532L0X после чего нам нужно прокрутить окно вниз до VL53L0X by Polulu и нажать Установить:

Если у вас английская версия IDE, то вам нужно следовать такому пути:

Sketch -> Include Library -> Manage Libraries

Далее также ищем VL53l0X и жмем Install.

Если это не работает, вы можете вручную установить библиотеку. Для этого нам нужно скачать архив последней версии с GitHub и распаковать его. Потом переименовать vl53l0x-arduino-master в VL53L0X.

После чего перемещаем или копируем папку VL53L0X в папку libraries внутри директории где установлена Arduino IDE.

Вы можете просмотреть местоположение своего эскиза, открыв меню «Файл» (англ. — File) и выбрав «Найстроки» (Preferences) в Arduino IDE. Если в этом месте еще нет папки с библиотеками, создайте ее самостоятельно. После установки библиотеки перезапустите Arduino IDE.

Примеры скетчей

После установки библиотеки датчика VL53L0X становится доступно пару примеров скетчей, которые показывают, как использовать библиотеку.

Вы можете получить к ним доступ из IDE Arduino, открыв меню:

Файл -> Примеры -> VL53L0X

Я приведу код примеров ниже. Если вы не можете найти эти примеры, библиотека, вероятно, была установлена неправильно, и вам следует повторить приведенные выше инструкции по установке.

Пример №1

Первый пример показывает как использовать непрерывный режим для измерения дальности с помощью VL53L0X. Он основан на vl53l0x_ContinuousRanging_Example.c из API VL53L0X.

Показания диапазона приведены в миллиметрах.

Если вы просто скопируете код ниже, то не забудьте, что вам нужно установить две библиотеки для корректной работы — Wire.h и VL53LOX.h.

#include <Wire.h> #include <VL53L0X.h> VL53L0X sensor; void setup() { Serial.begin(9600); Wire.begin(); sensor.setTimeout(500); if (!sensor.init()) { Serial.println(«Не удалось обнаружить и инициализировать датчик!»); while (1) {} } // Запустите непрерывный режим (снимайте показания // как можно быстрее). Чтобы вместо этого использовать непрерывный синхронизированный режим, // укажите желаемый период между измерениями в мс // (например, sensor.startContinuous(100)). } void loop() { Serial.print(sensor.readRangeContinuousMillimeters()); if (sensor.timeoutOccurred()) { Serial.print(» ТАЙМАУТ»); } Serial.println(); }

Пример № 2

Во втором примере показано, как получить одиночное измерение дальности с помощью VL53L0X. При желании датчик можно настроить с различными профилями измерения дальности. Подробнее можно посмотреть в руководстве пользователя API VL53L0X, чтобы повысить производительность для определенного проекта. Код основан на четырех примерах «SingleRanging» из API VL53L0X.

Показания диапазона приведены в миллиметрах.

#include <Wire.h> #include <VL53L0X.h> VL53L0X sensor; // Раскомментируйте строку ниже, чтобы использовать дальний режим. // Это увеличивает чувствительность датчика и расширяет его потенциальный диапазон, // но увеличивает вероятность получения неточных показаний // из-за отражений от объектов, отличных от намеченной цели. // Лучше всего работает в темноте. //#define LONG_RANGE // Раскомментируйте одну из двух строк ниже, чтобы получить: // — более высокую скорость за счет меньшей точности ИЛИ // — более высокую точность за счет меньшей скорости //#define HIGH_SPEED //#define HIGH_ACCURACY void setup() { Serial.begin(9600); Wire.begin(); sensor.setTimeout(500); if (!sensor.init()) { Serial.println(«Не удалось обнаружить и инициализировать датчик!»); while (1) {} } #if defined LONG_RANGE // понижает предел скорости обратного сигнала (по умолчанию 0,25 MCPS (мчип/с)) sensor.setSignalRateLimit(0.1); // увеличить периоды лазерного импульса (по умолчанию 14 и 10 PCLK) // * — PCLK — это частота периферии sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18); sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14); #endif #if defined HIGH_SPEED // уменьшить тайминг до 20 мс (по умолчанию около 33 мс) sensor.setMeasurementTimingBudget(20000); #elif defined HIGH_ACCURACY // увеличить тайминг 200 мс sensor.setMeasurementTimingBudget(200000); #endif } void loop() { Serial.print(sensor.readRangeSingleMillimeters()); if (sensor.timeoutOccurred()) { Serial.print(» ТАЙМАУТ»); } Serial.println(); }

API VL53L0X

Большая часть функциональности этой библиотеки основана на API VL53L0X, предоставленной компанией производителем. Отдельные комментарии в коде цитируются или перефразированы из исходного кода API, руководства пользователя API (UM2039) и Технического описание VL53L0X.

Для получения дополнительной информации о коде библиотеки и о том, как он был получен из API, см. комментарии в файле VL53L0X.cpp на GitHub.

Эта библиотека предназначена для того, чтобы обеспечить более быстрый и простой способ начать использование VL53L0X с Arduino-совместимым контроллером, в отличие от настройки и компиляции API-интерфейса ST для Arduino.

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

Для продвинутых приложений, особенно когда хранение и память менее важны, рассмотрите возможность использования API VL53L0X напрямую (скачать документацию API можно выше).

Справочник по библиотеке

uint8_t last_status

Статус последней передачи записи I²C. Обратитесь к документации Wire.endTransmission() для получения возвращаемых значений.

VL53L0X(void)

Конструктор

void setAddress(uint8_t new_addr)

Изменяет адрес ведомого устройства I²C VL53L0X на заданное значение (7-разрядное, 7 бит).

uint8_t getAddress(void)

Возвращает текущий адрес I²C.

bool init(bool io_2v8 = true)

Инициализирует и настраивает датчик. Если необязательный аргумент io_2v8 равен true (по умолчанию, если не указан), датчик настроен на режим 2V8 (вход / выход 2,8 В); если false, датчик остается в режиме 1V8. Возвращаемое значение является логическим значением, указывающим, успешно ли завершена инициализация.

void writeReg(uint8_t reg, uint8_t value)

Записывает 8-битный регистр датчика с заданным значением.

Константы адреса регистра определяются типом перечисления regAddr в VL53L0X.h.

Пример использования: sensor.writeReg(VL53L0X::SYSRANGE_START, 0x01);

void writeReg16Bit(uint8_t reg, uint16_t value)

Записывает 16-битный регистр датчика с заданным значением.

void writeReg32Bit(uint8_t reg, uint32_t value)

Записывает 32-битный регистр датчика с заданным значением.

uint8_t readReg(uint8_t reg)

Считывает 8-битный регистр датчика и возвращает прочитанное значение.

uint16_t readReg16Bit(uint8_t reg)

Считывает 16-битный регистр датчика и возвращает прочитанное значение.

uint32_t readReg32Bit(uint8_t reg)

Считывает 32-битный регистр датчика и возвращает прочитанное значение.

void writeMulti(uint8_t reg, uint8_t const * src, uint8_t count)

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

void readMulti(uint8_t reg, uint8_t * dst, uint8_t count)

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

bool setSignalRateLimit(float limit_Mcps)

Устанавливает ограничение скорости обратного сигнала до данного значения в единицах MCPS (мегачип в секунду). Это минимальная амплитуда сигнала, отраженного от цели и полученного датчиком, необходимого для того, чтобы он мог сообщить правильное значение. Установка нижнего предела увеличивает потенциальный диапазон датчика, но также увеличивает вероятность получения неточного показания из-за отражений от объектов, отличных от намеченной цели. Этот лимит по умолчанию инициализируется до 0,25 MCPS. Возвращаемое значение является логическим значением, указывающим, был ли запрошенный предел действительным.

float getSignalRateLimit(void)

Возвращает текущий предел скорости обратного сигнала в MCPS.

bool setMeasurementTimingBudget(uint32_t budget_us)

Устанавливает временной интервал измерения для данного значения в микросекундах. Это время, разрешенное для одного измерения диапазона; более длительный тайминг позволяет проводить более точные измерения. По умолчанию составляет около 33000 микросекунд или 33 мс; минимум 20 мс. Возвращаемое значение является логическим значением, указывающим, было ли запрошенное значение действительным.

uint32_t getMeasurementTimingBudget(void)

Возвращает текущий тайминг измерения в микросекундах.

bool setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks)

Устанавливает период импульса VCSEL (лазер с поверхностным излучением с вертикальной полостью) для данного типа периода (VL53L0X::cselPeriodPreRange или VL53L0X::VcselPeriodFinalRange) равным данному значению (в PCLK). Более длительные периоды увеличивают потенциальный диапазон датчика. Допустимые значения (только четные числа):

— Предварительно: от 12 до 18 (по умолчанию инициализируется до 14)
— Итоговое: от 8 до 14 (по умолчанию инициализируется до 10)

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

uint8_t getVcselPulsePeriod(vcselPeriodType type)

Возвращает текущий период импульса VCSEL для данного типа периода.

void startContinuous(uint32_t period_ms = 0)

Начинает непрерывное измерение дальности. Если необязательный аргумент period_ms равен 0 (по умолчанию, если не указан), используется непрерывный режим (датчик проводит измерения как можно чаще); если он не нулевой, используется непрерывный синхронизированный режим с указанным периодом между измерениями в миллисекундах, определяющим, как часто датчик выполняет измерение.

void stopContinuous(void)

Останавливает непрерывный режим.

uint16_t readRangeContinuousMillimeters(void)

Возвращает показание диапазона в миллиметрах, когда активен непрерывный режим.

uint16_t readRangeSingleMillimeters(void)

Выполняет одиночное измерение дальности и возвращает показания в миллиметрах.

void setTimeout(uint16_t timeout)

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

admin

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Наверх