Программирование ультразвукового датчика ардуино

Датчик расстояния/Ультразвуковой дальномер

Ультразвуковые датчики расстояния широко применяются в робототехнике из-за своей относительной простоты, приемлемой точности и доступности. Датчики являются «глазами» робота и помогают объезжать препятствия, получать размеры предметов, моделировать карту помещения и сигнализировать о приближении или удалении объектов. Летающий дрон использует дальномер для полётов над землёй на заданной высоте. Также можно построить карту помещения, применив специальный алгоритм SLAM.

Способность ультразвукового датчика определять расстояние до объекта основано на принципе сонара – посылая импульсы ультразвука частотой 40 кГц и получая его отражение с задержкой, устройство определяет наличие объектов и расстояние до них. Подобный способ используют летучие мыши (коты услышали знакомое слово). Ультразвуковые сигналы, генерируемые приёмником, отражаясь от препятствия, возвращаются к нему через определённый промежуток времени. Этот временной интервал становится характеристикой, помогающей определить расстояние до объекта.

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

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

Если сравнивать ультразвуковые и лазерные дальномеры, то у каждого из них есть свои преимущества и недостатки. Ультразвуковой датчик хорошо видит перед собой и может обнаружить тонкую ножку стула, в отличие от лазерного. Но для сканирования окружающей среды ультразвуковой датчик не очень хорош, так как даёт очень неточную и шумную картину. Также будут проблемы с измерением расстояния сверху с землёй с высокой травой. Кроме того, скорость звука не слишком высока (для обнаружения объекта на расстоянии 4 метра требуется около 24 микросекунд), что может быть критичным для объектов с большой скоростью, вы можете не успеть среагировать на стенку.

Читайте также:  Геометрической интерпретации области допустимых решений задачи линейного программирования является

Ультразвуковой датчик расстояния HC-SR04

Популярная модель HC-SR04 доступна и проста в эксплуатации. Диапазон дальности его измерения составляет от 2 до 400 см. На его работу не оказывают существенного воздействия электромагнитные излучения и солнечная энергия.

На передней части модуля расположено два ультразвуковых датчика, первый с надписью T (Transmiter) является передатчиком ультразвуковых волн (TCT40-16T), а второй с надписью R (Receive) служит приёмником отражённых ультразвуковых волн (TCT40-16R), по центру расположен выводной кварцевый генератор на 27 МГц.

HC-SR04

Технические характеристики

  • Напряжение питания: 5 В
  • Потребление тока в рабочем режиме: 15 мА
  • Потребление тока в пассивном состоянии: Реклама

Источник

Ультразвуковой дальномер HC-SR04: подключение, схема и примеры работы

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

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

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

Модуль подключается четырьмя проводами. Контакты VCC и GND служат для подключения питания, а Trig и Echo — для отправки и приема сигналов дальномера. Подключим их к пинам 10 и 11 соответственно.

Напряжение питания дальномера 5 В. Модуль работает и с платами, напряжение которых 3,3 В — в этом случае подключайте его к пинам группы с P8 по P13. Установите джампер выбора питания V2 на Troyka Shield в положение V2+5V. Пин микроконтроллера, соединённый с пином Echo должен быть толерантен к 5 В. Приведённая схема подходит для подключения дальномера к Iskra JS.

Пример работы

Рассмотрим как работает дальномер.

Для того чтобы инициализировать отправку сигнала дальномером, необходимо подать высокий сигнал длительностью 10 μs на пин Trig .

После получения высокого сигнала длительностью 10 μs на пин Trig , модуль генерирует пучок из восьми сигналов частотой 40 кГц и устанавливает высокий уровень на пине Echo .

Зная продолжительность высокого сигнала на пине Echo можем вычислить расстояние, умножив время, которое потратил звуковой импульс, прежде чем вернулся к модулю, на скорость распространения звука в воздухе (340 м/с).

Функция pulseIn позволяет узнать длительность импульса в μs . Запишем результат работы этой функции в переменную duration.

Теперь вычислим расстояние переведя скорость из м/с в см/мкс:

distance = duration * 340 м/с = duration * 0.034 м/мкс

Преобразуем десятичную дробь в обыкновенную

distance = duration * 1/29 = duration / 29

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

Оформим в код всё вышесказанное и выведем результат в Serial Monitor

// Укажем, что к каким пинам подключено int trigPin = 10; int echoPin = 11; void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { int duration, distance; // для большей точности установим значение LOW на пине Trig digitalWrite(trigPin, LOW); delayMicroseconds(2); // Теперь установим высокий уровень на пине Trig digitalWrite(trigPin, HIGH); // Подождем 10 μs delayMicroseconds(10); digitalWrite(trigPin, LOW); // Узнаем длительность высокого сигнала на пине Echo duration = pulseIn(echoPin, HIGH); // Рассчитаем расстояние distance = duration / 58; // Выведем значение в Serial Monitor Serial.print(distance); Serial.println(" cm"); delay(100); }

Работа с библиотекой

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

#include #define TRIGGER_PIN 10 #define ECHO_PIN 11 #define MAX_DISTANCE 400 NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); void setup() { Serial.begin(9600); } void loop() { delay(50); Serial.print("Ping: "); Serial.print(sonar.ping_cm()); Serial.println("cm"); }

Работа с Iskra JS

var sonic = require('@amperka/ultrasonic') .connect({trigPin: P10, echoPin: P11}); sonic.ping(function(err, value) { if (err) { console.log('An error occurred:', err); } else { console.log('The distance is:', value, 'millimeters'); } }, 'mm');

Источник

Arduino и датчик расстояния HC-SR04

HC-SR04 – ультразвуковой датчик расстояния. Характеристики:

  • Питание: 5V
  • Рабочий ток: 15 мА
  • Звуковая частота: 40 кГц
  • Угол измерения: 15 градусов
  • Диапазон измерения: 2 см.. 4 м
  • Точность: ~1 мм при грамотной фильтрации

Датчик работает довольно интересно: подаём импульс с продолжительностью 10 мкс на пин Trig, модуль посылает ультразвуковой импульс, он отражается от препятствия и детектируется. Затем с пина Echo возвращается импульс по продолжительности соответствующий времени путешествия звуковой волны. Ардуина этот импульс должна измерить.

Подключение

Подключаем к питанию и любым цифровым пинам:

Библиотеки

С датчиком можно работать без библиотек, стандартными средствами Arduino. Но есть и библиотеки:

  • HC-SR04 – можно установить по названию HC-SR04 из менеджера библиотек (автор Dirk Sarodnick)
  • NewPing – можно установить по названию NewPing из менеджера библиотек

Примеры

Небольшой момент: чтобы датчик не ловил “эхо” от самого себя – его не рекомендуется опрашивать чаще 30 мс!

Для опроса используем встроенные Arduino-функции

// пины #define HC_TRIG 3 #define HC_ECHO 2 void setup() < Serial.begin(9600); // для связи pinMode(HC_TRIG, OUTPUT); // trig выход pinMode(HC_ECHO, INPUT); // echo вход >void loop() < float dist = getDist(); // получаем расстояние Serial.println(dist); // выводим delay(50); >// сделаем функцию для удобства float getDist() < // импульс 10 мкс digitalWrite(HC_TRIG, HIGH); delayMicroseconds(10); digitalWrite(HC_TRIG, LOW); // измеряем время ответного импульса uint32_t us = pulseIn(HC_ECHO, HIGH); // считаем расстояние и возвращаем return (us / 58.2); >

Подвигаю рукой перед датчиком:

Отфильтруем данные при помощи простейшего экспоненциального фильтра

// пины #define HC_TRIG 3 #define HC_ECHO 2 void setup() < Serial.begin(9600); // для связи pinMode(HC_TRIG, OUTPUT); // trig выход pinMode(HC_ECHO, INPUT); // echo вход >float distFilt = 0; void loop() < float dist = getDist(); // получаем расстояние distFilt += (dist - distFilt) * 0.2; // фильтруем Serial.println(distFilt); // выводим delay(50); >// сделаем функцию для удобства float getDist() < // импульс 10 мкс digitalWrite(HC_TRIG, HIGH); delayMicroseconds(10); digitalWrite(HC_TRIG, LOW); // измеряем время ответного импульса uint32_t us = pulseIn(HC_ECHO, HIGH); // считаем расстояние и возвращаем return (us / 58.3); >

Данная библиотека умеет выдавать результат только в целых сантиметрах

// пины #define HC_TRIG 3 #define HC_ECHO 2 #include // указываем пины и макс. расстояние в сантиметрах NewPing sonar(HC_TRIG, HC_ECHO, 100); void setup() < Serial.begin(9600); // для связи >void loop() < // получаем и выводим Serial.println(sonar.ping_cm()); delay(50); >

Кстати, опрос датчика при помощи pulseIn() , не так плох, как про него пишут на форумах: погрешность измерения составляет всего 0.5 мкс:

что в пересчёте на расстояние даёт точность 0.17 мм! На деле точность получается в два раза выше, так как фактически мы измеряем сигнал два раза (путь до препятствия и обратно). Сам датчик шумит гораздо сильнее, поэтому миллиметровую точность получить абсолютно не проблема. Но есть проблема в другом: выполнение кода блокируется на время измерения, например на трёх метрах это будет 17 мс. Вроде и немного, но для некоторых задач это будет весьма критично.

Ещё один момент: скорость звука зависит от температуры: при +20°С это 343 м/с, а при -20°С – 318 м/с! А ведь это целых 318/343=7%, что на расстоянии в 1 метр даст погрешность 7 сантиметров. Много, гораздо больше возможных погрешностей в измерении. Давайте это исправим.

В диапазоне -50.. 50°С зависимость является линейной и аппроксимируется уравнением V = 0.609 * t + 330.75 :

Таким образом для нахождения более точного расстояния с поправкой на температуру достаточно делить время импульса не на 58, а на.. кстати, откуда берётся 58? Для прохождения 1 м звуку понадобится 1 / 343 = 0.0029 с, или 2.915 мс. Мы получаем время туда и обратно, поэтому умножаем ещё на 2. В и для сантиметров – ещё на 10, и получаем 58.3. Гораздо понятнее было бы умножать время импульса на скорость звука и делить пополам.

Таким образом для расчёта расстояния в миллиметрах с учётом температуры в °С получим формулу:

S = us * V / 2000 S = us * (0.609 * t + 330.75) / 2000 S = us * (t * 6 / 10 + 330) / 2000

Настолько высокая точность нам не нужна, поэтому можно избавиться от float , чтобы код весил меньше (третье уравнение). Погрешность составит не более 1 мм на 1 метр. И финальный пример тогда (подставим в первую программу):

// пины #define HC_TRIG 3 #define HC_ECHO 2 void setup() < Serial.begin(9600); // для связи pinMode(HC_TRIG, OUTPUT); // trig выход pinMode(HC_ECHO, INPUT); // echo вход >void loop() < int t = 24; // представим, что получили с датчика int dist = getMm(t); // получаем расстояние в мм Serial.println(dist); // выводим delay(50); >// сделаем функцию для удобства int getMm(int t) < // импульс 10 мкс digitalWrite(HC_TRIG, HIGH); delayMicroseconds(10); digitalWrite(HC_TRIG, LOW); // измеряем время ответного импульса uint32_t us = pulseIn(HC_ECHO, HIGH); // считаем расстояние и возвращаем return (us * (t * 6 / 10 + 330) / 2000ul); >

Отфильтровать – и будет супер!

Домашнее задание

  • Попробовать другие библиотеки для HC-SR04
  • Попробовать разные фильтры из урока на финальном примере

Источник

Оцените статью