3.7.md
ИЗМЕРЕНИЕ РАССТОЯНИЙ С ПОМОЩЬЮ УЛЬТРАЗВУКОВОГО ДАТЧИКА
Мобильным устройствам необходимо обеспечить взаимодействие с окружающим миром, чтобы при движении они не сталкивались с препятствиями. Для таких целей часто используют датчики для определения расстояния до препятствия.
НАПОМИНАНИЕ
При использовании внешнего питания сначала подключаем внешнее питание, а потом USB-кабель для связи или программирования. При выключении все делаем наоборот: сначала вытаскиваем USB-кабель, а затем внешнее питание. Несоблюдение данного правила может привести к выходу из строя платы Рудирон.
Ультразвуковой датчик расстояния HC-SR04.Дальномер и датчик расстояний не являются одним и тем же устройством! Дальномер измеряет расстояние, а датчик преобразует расстояние в электрическую величину.
Ультразвуковой датчик расстояния HC-SR04, преобразовывает расстояние при помощи ультразвука в длительность электрического сигнала.
Характеристики дальномера HC-SR04
№ | Наименование | Значение | Назначение |
---|---|---|---|
1 | Напряжение питания | 5 В | —— |
2 | Потребляемый ток | 15 мА | —— |
3 | Ток покоя | < 2 мА | —— |
4 | Эффективный угол обзора | < 15° | Угол от центральной оси где происходит измерение расстояния |
5 | Диапазон преобразований | 2 см - 400 см | Минимальное и максимальное расстояния |
6 | Точность преобразований | 3 мм | —— |
Вход модуля | Назначени | Значения |
---|---|---|
GND | Общая шина земли | Подсоединяем к контактам контроллера с обозначением земли |
VСС | Шина питания от контроллера | Подсоединяем к контактам контроллера с обозначением +5 В |
TRIG | Вход для генерации ультразвуковых импульсов на излучение датчика | Подается логическая единица длительностью 10 мс (одиночный импульс) |
ECHO | Выход в виде импульса пропорционально дистанции до препятствия | Длина импульса от 150 мкс – 3 см дистанция до 25 мс – 4 метра дистанция |
Принцип работы, следующий - после подачи импульса длиной 10 мкс на вход TRIG датчик излучает 8 импульсов в пространство перед собой с частотой 40 кГц. Ультразвуковая волна возвращается в датчик, отражаясь от препятствия и фиксируется в виде импульса длиной пропорциональной расстоянию. Чем дальше препятствие, тем длиннее импульс.
TX сенсор излучает ультразвуковой импульс, который отражается от препятствия и принимается RX сенсором. Расстояние вычисляется по времени прохождения ультразвука от TX передатчика -> препятствие -> к RX приемнику. Скорость звука при температуре 20° C составляет 1235 км/ч или 343 м/с. При обработке данных от датчика расстояния нужно полученный результат поделить на 2. Так как ультразвук сначала движется до препятствия, а потом отразившись от него движется назад. То есть он преодолевает одно и тоже расстояние 2 раза. Еще стоит учитывать влажность воздуха и его температуру, скорость ультразвука изменяется в зависимости от этих параметров.
ПОДКЛЮЧЕНИЕ ДАТЧИКА К КОНТРОЛЛЕРУ И ПРОГРАММА
Подключим датчик к контроллеру «РУДИРОН»:
Земля датчика и контроллера соединены черными проводами, питание 5 вольт красные провода. Желтый провод от вывода 3 контроллера подключен ко входу датчика Trig. Зеленый провод подключен к 7 выводу контроллера и выходу датчика Echo. Расположение контроллера не совсем правильное. Он должен быть расположен позади ультразвукового датчика расстояний. Так было сделано, чтобы было видно к каким выводам контроллера подключен датчик. Так как ультразвуковой датчик вставлен в беспаечную плату, то контроллер будет находиться ниже датчика и не будет перекрывать ультразвуковую волну от излучателя.
Алгоритм работы ультразвукового датчика следующий:
- Подаем импульс продолжительностью 10 мкс на вывод Trig;
- На плате модуля входной импульс преобразуется в 8 импульсов частотой 40 кГц и посылается через TX-излучатель;
- Дойдя до препятствия, посланные импульсы отражаются и принимаются RX- приемником, в результате этого получаем выходной сигнал на выводе Echo.
- На стороне контроллера переводим полученный сигнал в расстояние по формуле: ширина импульса (мкс) /2 /29.1 = дистанция (см);
Для работы с датчиком нам понадобится новая команда pulseIn(). Команда измеряет длительность сигнала от выхода Echo.
#include “Arduino.h” void setup()
{
// Задаем номерам портов контроллера осознанные имена #define HCSR04_TRIG_PIN 3
#define HCSR04_ECHO_PIN 7
// Устанавливаем режим работы портов TRIG на выход и Echo на вход
pinMode(HCSR04_TRIG_PIN, OUTPUT); pinMode(HCSR04_ECHO_PIN, INPUT);
//конфигурация последовательного порта
Serial.begin(115200);
}
void loop()
{
// Генерируем импульс 10 мкс на выходе TRIG digitalWrite(HCSR04_TRIG_PIN, LOW);
// выход в 0 delayMicroseconds(5);
// пауза на 5 мкс
digitalWrite(HCSR04_TRIG_PIN, HIGH); // подача единицы на выход TRIG
delayMicroseconds(10); // Пауза 10 мкс В этот момент датчик будет
// посылать сигналы с частотой 40 КГц.
digitalWrite(HCSR04_TRIG_PIN, LOW); // Выход TRIG в ноль импульс
// в 10 мкс завершен
//Время задержки акустического сигнала на эхолокаторе.
int duration = pulseIn(HCSR04_ECHO_PIN, HIGH); // считываем
//длительность импульса
//Расстояние в сантиметрах
float distance = (duration / 2) / 29.1; // рассчитываем расстояние в
// сантиметрах Serial.print(«Расстояние до препятствия = «); Serial.print(distance,3);
Serial.print(“ сантиметров”); Serial.println();
delay(500); // ждем 0.5 секунды до следующего замера расстояния
}
Описание программы:
1 Настраиваем вывода контроллера для работы с датчиком:
#define HCSR04_TRIG_PIN 3
#define HCSR04_ECHO_PIN 7
// Устанавливаем режим работы портов TRIG на выход и Echo на вход
pinMode(HCSR04_TRIG_PIN, OUTPUT); pinMode(HCSR04_ECHO_PIN, INPUT);
Так как Echo выдает сигнал из датчика, то вывод 7 контроллера настраиваем на вход сигнала.
2 Формируем импульс длительностью 10 микросекунд на вход Trig датчика:
// Генерируем импульс 10 мкс на выходе TRIG digitalWrite(HCSR04_TRIG_PIN, LOW);
// выход в 0
delayMicroseconds(5); // пауза на 5 мкс digitalWrite(HCSR04_TRIG_PIN, HIGH);
// подача единицы на выход TRIG
delayMicroseconds(10); // Пауза 10 мкс В этот момент датчик будет
// посылать сигналы с частотой 40 КГц.
digitalWrite(HCSR04_TRIG_PIN, LOW); // Выход TRIG в ноль импульс
// в 10 мкс завершен
3 Измеряем длительность импульса от датчика:
int duration = pulseIn(HCSR04_ECHO_PIN, HIGH);
4 Рассчитываем расстояние в сантиметрах:
float distance = (duration / 2) / 29.1;
Функция pulseIn замеряет длину положительного импульса на ноге HCSR04_ECHO_ PIN в микросекундах. В программе мы записываем время полета звука в переменную duration. Как мы уже выяснили ранее, нам потребуется умножить время на скорость звука: s = duration * v = duration * 340 м/с
Переводим скорость звука из м/с в см/мкс: s = duration * 0.034 cм/мкс
Для удобства преобразуем десятичную дробь в обыкновенную: s = duration * 1/29 = duration / 29.1
А теперь вспомним, что звук прошел два искомых расстояния: до цели и обратно. distance = (duration / 2) / 29.1
5 Полученное расстояние в сантиметрах передаем в последовательный порт для отсылки на компьютер в программу терминал:
Serial.print(«Расстояние до препятствия = «);
Serial.print(distance,3);
Serial.print(“ сантиметров”);
Serial.println();
Загрузим программу в контроллер и поднесем ладонь к датчику на небольшое расстояние:
Мы увидим в терминале измеренное расстояние в зависимости от расстояния ладони до датчика.
Так как мы подсоединили выход датчика к выводу 7 контроллера и к этому же выводу подключен светодиод L2 можно увидеть, как изменяется яркость свечения светодиода (а иногда он и мигает) в зависимости от измеряемого расстояния. При очень близком расстоянии светодиод светит непрерывно так как импульсы с выхода датчика имеют максимальную длительность, а когда препятствие далеко импульсы, короткие и мы видим мигание светодиода. Получается вроде сигнала ШИМ.
Если перед датчиком поставить препятствие в виде ткани, то показания датчика могут быть очень сильно отличаться от реальных расстояний. Так происходит, потому что мы имеем дело с отражением ультразвуковой волны от поверхности предметов. Ткани оказывают сильное поглощающее воздействие. Данных факт необходимо учитывать при проектировании своего устройства
При измерении дистанции до неподвижного препятствия можно увидеть, что показания датчика непостоянны и имеют небольшой разброс в значениях. Для повышения точности измерения в таком случае можно применить расчет среднего значения. То есть провести, например 10 измерений и потом взять среднее. Таким образом мы повысим точность измерения. Если бы мы основывались на одном измерении, то каждое новое измерение могло сильно повлиять на работу программы так как работа датчика сильно зависит от внешних факторов (свойства отражающей поверхности, температуры воздуха, случайных предметов).
Напишем программу, которая делает 10 измерений и вычисляет среднее значение. Для усложнения задачи используем тип данных массив.
void setup()
{
// Задаем номерам портов контроллера осознанные имена
#define HCSR04_TRIG_PIN 3
#define HCSR04_ECHO_PIN 7
// Устанавливаем режим работы портов TRIG на выход и Echo на вход
pinMode(HCSR04_TRIG_PIN, OUTPUT); pinMode(HCSR04_ECHO_PIN, INPUT);
//конфигурация последовательного порта
Serial.begin(115200);
}
int duration;
double srednee;
double distance;
int massiv[10];
void loop()
{ // создаем цикл в 10 действий измерения расстояния с записью в массив
for (int i = 0; i < 10; i++)
{
digitalWrite(HCSR04_TRIG_PIN, LOW); // выход в 0 delayMicroseconds(5);
// пауза на 5 мкс digitalWrite(HCSR04_TRIG_PIN, HIGH); // подача единицы на выход TRIG
delayMicroseconds(10); // Пауза 10 мкс В этот момент датчик будет
// посылать сигналы с частотой 40 КГц.
digitalWrite(HCSR04_TRIG_PIN, LOW); // Выход TRIG в ноль импульс
// в 10 мкс завершен
//Время задержки акустического сигнала на эхолокаторе.
duration = pulseIn(HCSR04_ECHO_PIN, HIGH); // считываем длительность
// импульса
massiv[i] = duration;
}
// создаем цикл для расчета среднего значения на основании массива
srednee = 0;
for (int i = 0; i < 10; i++)
{
srednee = srednee + massiv[i];
}
srednee = srednee / 10; //Расстояние в сантиметрах
distance = (srednee / 2) / 29.1; // рассчитываем расстояние
// в сантиметрах
Serial.print(«Расстояние до препятствия = «);
Serial.print(distance,3);
Serial.print(“ сантиметров”);
Serial.println();
delay(500); // ждем 0.5 секунды до следующего замера расстояния
}
Программа дополнилась 2 циклами. Первый это заполнение массива 10 длинами импульсов от датчика. Второй это суммирование всех измерений для расчета среднего значения.
Цикл заполнения массива длинами 10 импульсов:
for (int i = 0; i < 10; i++)
{
// Генерируем импульс 10 мкс на выходе TRIG
digitalWrite(HCSR04_TRIG_PIN, LOW); // выход в 0
delayMicroseconds(5); // пауза на 5 мкс
digitalWrite(HCSR04_TRIG_PIN, HIGH); // подача единицы на выход TRIG
delayMicroseconds(10); // Пауза 10 мкс В этот момент датчик будет
// посылать сигналы с частотой 40 КГц.
digitalWrite(HCSR04_TRIG_PIN, LOW); // Выход TRIG в ноль импульс
// в 10 мкс завершен
// Время задержки акустического сигнала на эхолокаторе.
duration = pulseIn(HCSR04_ECHO_PIN, HIGH); // считываем длительность
// импульса
massiv[i] = duration;
}
Обратите внимание, что измеренное значение длины импульса от датчика всегда цело число. Поэтому мы создали в памяти целочисленный массив.
> int massiv[10];
Цикл по суммированию всех значений:
srednee = 0;
for (int i = 0; i < 10; i++)
{
srednee = srednee + massiv[i];
}
Перед суммированием мы «обнулили» переменную srednee, в которой будет храниться сумма всех элементов массива (записали в ячейку памяти 0), так как мы не знаем, что до этого хранилось в этой переменной. Так как сумму всех измерений мы будем делить на 10 - итоговое число не целочисленное! Поэтому когда мы создавали переменную мы определили для нее тип double (повышенная точность), чтобы не потерять значения после запятой.
ПРИМЕЧАНИЕ Если Вы хотите выполнять программу при последующих включениях «Рудирона», то не забудьте переставить перемычку из положения «Режим программирования» обратно в «Режим выполнения». Если этого не сделать, то программа при включении «Рудирона» выполняться не будет.
ВЫВОДЫ
Мы научились использовать внешние датчики в наших программах, поняли алгоритм работы ультразвукового датчика для определении расстояния до препятствия.
СПИСОК КОНТРОЛЬНЫХ ВОПРОСОВ
- По какому принципу работает ультразвуковой датчик расстояния HC-SR04?
- Какой алгоритм работы необходимо применить для определения расстояния до препятствия?
- Почему полученные данные в результате работы датчика и расчета расстояния необходимо делить на 2?
- Почему данные полученные при измерении расстояния несколько раз отличаются друг от друга?
- Каким способом можно получить более точное значение расстояния до преграды?
- Зачем необходимо «обнулять» значение переменной в которой происходит расчет среднего значения перед началом определения расстояния по среднему значению?
- Почему при измерении моргает встроенный светодиод L2?
- От каких еще условий может зависеть результат замера расстояния?
- С какой целью используется функция pulseIn()?
- Что будет результатом выполнения программы? В чем разница между первым и вторым вариантом программы?
СПИСОК ДОПОЛНИТЕЛЬНЫХ ЗАДАЧ
- Использовать для написания программы среду Arduino IDE.
- Увеличить интервал между проводимыми замерами до 1 секунды.
- Увеличить количество замеров для получения усредненного результата. Сравнить с предыдущими результатами работы программ.
ЭЛЕМЕНТЫ КОНТРОЛЯ И ПРОВЕДЕНИЯ СОРЕВНОВАНИЙ
- Проведение тестирования по контрольным вопросам. Критерии: кто быстрее и допустил меньшее количество ошибок.
- Написание одного из трех вариантов (исходный и два варианта из списка дополнительных задач) программы и загрузка этого варианта в контроллер. Критерии: Правильно написанная программа согласно выданного задания, работающий контроллер и наименьшее количество времени затраченного на эти работы.