Как сделать ультразвуковой датчик расстояния на Ардуино: дальномер своими руками

Ультразвуковой датчик расстояния HC-SR04 (и схожие модули) используют ультразвуковые волны, чтобы определить дистанцию до объекта.

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

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

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

Кстати, несмотря на то, что принцип работы всех ультразвуковых датчиков одинаков, НЕ ВСЕ ИЗ НИХ производят одинаковый вывод напряжения на пин эха. Так что, если у вас модуль, отличный от HC-S04, то уделите внимание четвертому шагу, где описаны возможные проблемы, и проверьте, возможно, ваш модуль есть в списке. Если его там нет, то придётся разбираться своими силами.

Шаг 1: Сборка железа своими руками

Сборка очень проста (собирайте всё отключенным от напряжения):

  1. Соедините 5V от Ардуино с пином VCC на модуле
  2. Соедините GND от Ардуино с GND на модуле
  3. Соедините цифровой пин 7 на Ардуино с пином Trig на модуле
  4. Соедините цифровой модуль 8 на Ардуино с пином Эхо на модуле

Шаг 2: Программирование модуля HC-SR04

Для того чтобы видеть результаты работы программы, нужно запустить serial monitor на Ардуино. Если вы не знакомы с этой функцией, то сейчас самое время открыть её и узнать о ней побольше — это отличная вещь, помогающая отладить код. В интерфейсе Ардуино посмотрите в правый угол, там вы найдёте кнопку, запускающую серийный монитор, она похожа на увеличительное стекло, кликните на ней и монитор откроется (или выберите TOOLS/Serial Monitor, или нажмите Ctrl+Shift+M).

Вот набросок рабочей программы:

// Начала Скетча для Аруино —
// Определяем константы (константы не изменяются и если вы попробуете переопределить их то получите ошибку во время компиляции)
const int triggerPin = 7; // создаёт константу с именем «triggerPin» и назначает на неё цифровой пин 7
const int echoPin = 8; // создаёт константу с именем «echoPin» и назначает на неё цифровой пин 8
// Определяем переменные (переменные могут изменяться и обычно изменяются по ходу программы, в них могут содержаться какие-либо рассчитываемые значения)
int duration = 0; // создаёт переменную с именем «duration» для хранения значения, возвращаемого pulseIn, изначально значение задаётся равным «0»
int distance = 0; // создаёт переменную для хранения значения, рассчитанного в качестве расстояния до объекта, находящегося перед датчиком, изначально значение задаётся равным «0»
void setup() // В этой секции можно настроить вашу плату и другие параметры, необходимые для работы вашей программы.
{
Serial.begin(9600); // инициализирует последовательную коммуникацию через USB между Ардуино и компьютером, нам это понадобится
//определяем режимы пинов
pinMode(triggerPin, OUTPUT); // «triggerPin» будет использоваться для ВЫВОДА, номер пина объявлен выше в секции «Определяем переменные»
pinMode(echoPin, INPUT); // «echoPin» будет использоваться для ВВОДА, номер пина объявлен выше в секции «Определяем переменные»
} // конец настройки
// всё, что было написано выше считывается программой лишь один раз — при Запуске или Сбросе (Reset)
void loop() // код программы в зацикленной части считывается беспрестанно и повторяется до тех пор, пока не выключится питание, или пока не будет сделан сброс
{
digitalWrite(triggerPin, HIGH); //начинает подавать ультразвуковые волны с модуля HC-SR04
delay(5); // небольшая пауза, она нужна для того, чтобы модуль функционировал правильно (можно уменьшить это значение, другие мои программы работают при значении 1)
digitalWrite(triggerPin, LOW); //останавливает ультразвуковые волны, идущие от модуля HC-SR04
duration = pulseIn(echoPin, HIGH); //особая функция, позволяющая определить продолжительность времени, при котором на пин эха подавалось напряжение в последнем завершенном цикле подачи ультразвука
delay(10); // опять небольшая пауза. Она нужна для стабильности, слишком короткая пауза может не дать результата
distance = (duration/2) / 58; //преобразовываем продолжительность в расстояние (значение, сохранённое в «duration» делится на 2, затем это значение делится на 58**) ** для сантиметров
delay(500); // еще одна пауза для стабильности — можете поиграть со значением, но это может испортить работу программы, так что по умолчанию используйте 500
Serial.print(distance); //отправляет вычисленное значение расстояния на серийный монитор
Serial.println(» cm»); //добавляет слово «cm» после значения расстояния и переводит каретку на серийном мониторе на новую строку
Serial.println(); //добавляет пустую строку на серийном мониторе (для удобства чтения)
} // Конец цикла

_________________________________________________

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

// Программа модуля ультразвукового датчика расстояния HC-SC04
const int triggerPin = 7; //триггер на 7
const int echoPin = 8; // ECHO на 8
int duration = 0; // хранит значение из pulseIn
int distance = 0; // хранит значение рассчитанного расстояния
void setup()
{
Serial.begin(9600);
pinMode(triggerPin, OUTPUT); //определяет режимы пинов
pinMode(echoPin, INPUT);
}
void loop()
{
digitalWrite(triggerPin, HIGH); // начинает отправлять ультразвук
delay(5); //необходимая команда, настраивается (но не ниже 10микросекунд)
digitalWrite(triggerPin, LOW); // модуль прекращает отправлять ультразвук
duration = pulseIn(echoPin, HIGH); // определяет, как долго подавалось напряжение на пин ECHO
delay(10); //необходимая команда, настраивается, но аккуратно
distance = (duration/2) / 58; // высчитываем расстояние в см до объекта
delay(500); // пауза для стабильности, уменьшение может сломать ход программы, лучше оставить как есть
Serial.print(distance); // отправляет текущее значение, хранимое в distance на серийный монитор
Serial.println(» cm»); // отображает слово «cm» сразу после расстояния
Serial.println(); // создаёт одну пустую строку в серийном мониторе (для удобства чтения)
}

К инструкции я также приложу файлы.ino

Файлы
  1. HCSR04BareBones.ino — этот файл сильно закомментирован и содержит кое-какую информацию по модулю HC-SR04, а также инфу по сборке.
  2. BareBonesLight.ino — модуль с небольшим количеством комментариев

Шаг 3: Советы и рекомендации

Вот мой совет. Я знаю, что код работает, но перед тем, как прикреплять файлы к инструкции, я перепроверил всё и серийный монитор стабильно показывал «0 cm». Проблема оказалась в сгоревшем модуле, а его замена исправила ситуацию.

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

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

Схема выше использовалась мной для того, чтобы определять, что от датчика все объекты находятся на расстоянии дальше, чем 60 см. В проекте использовалось три диода и пищалка. Когда все предметы были дальше 60 см, горел зеленый диод. Когда что-то приближалось менее чем на 60см, зеленый диод гас, а красный загорался. Если объект оставался на близком расстоянии на какой-то время, то загорался второй красный диод, а пищалка начинала пищать. Когда объект удалялся на 60см, пищалка умолкала, красные диоды гасли, и снова загорался зеленый. Это не предотвращало все ложные тревоги, но работало с большинством случаев, когда мимо датчика пролетала птица или любопытная белка пробегала мимо.

Шаг 4: Известные проблемы

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

  1. US-105
  2. DYP-ME007TX

Модуль US-105

Ультразвуковой модуль US-105 использует вывод GPIO на пин ECHO, что подразумевает другие вычисления для определения расстояния. При выводе GPIO на пин ECHO, пин не удерживается под напряжением во время отправки волны. Вместо этого, при получении отраженного ультразвука на пин ECHO подается конкретное напряжение, которое пропорционально времени, потребовавшемуся ультразвуковой волне для того, чтобы отправиться и вернуться обратно на датчик. С этим модулем будет работать такой код:

// Код для ультразвукового модуля US-105
unsigned int EchoPin = 2;
unsigned int TrigPin = 3;
unsigned long Time_Echo_us = 0;
//Len_mm_X100 = length*100
unsigned long Len_mm_X100 = 0;
unsigned long Len_Integer = 0; //
unsigned int Len_Fraction = 0;
void setup()
{
Serial.begin(9600);
pinMode(EchoPin, INPUT);
pinMode(TrigPin, OUTPUT);
}
void loop()
{
digitalWrite(TrigPin, HIGH);
delayMicroseconds(50);
digitalWrite(TrigPin, LOW);
Time_Echo_us = pulseIn(EchoPin, HIGH);
if((Time_Echo_us  1))
{
Len_mm_X100 = (Time_Echo_us*34)/2;
Len_Integer = Len_mm_X100/100;
Len_Fraction = Len_mm_X100%100;
Serial.print("Растояние: ");
Serial.print(Len_Integer, DEC);
Serial.print(".");
if(Len_Fraction < 10)
Serial.print("0");
Serial.print(Len_Fraction, DEC);
Serial.println("mm");
delay(1000);
} // Конец программы

Модуль DYP-ME007TX

// Код для ультразвукового модуля DYP-ME007TX

/* Инструкции по подключению
* 5V от Ардуино к VCC на модуле
* GNG от Ардуино к GND на модуле
* OUT от модуля к цифровому пину 7 на Ардуино
*/

#include 
#define RXpin 7
#define TXpin 7
SoftwareSerial mySerial(RXpin, TXpin);
long mili = 0;
byte mybuffer[4] = {0};
byte bitpos = 0;
void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
}
void loop()
{
  bitpos = 0;
  while (mySerial.available())
  {
    if (bitpos < 4) {
      mybuffer[bitpos++] = mySerial.read();
    }
    else break;
  }
  mySerial.flush(); 
  mili = mybuffer[1] << 8 | mybuffer[2];
  Serial.print("Distance: ");
  Serial.print(mili / 25.4);
  Serial.print (" inches");
  Serial.println();
  delay(500);
}
Игорь Самоделов
Игорь Самоделов

Рассказываю как сделать какую-либо вещь с пошаговыми фото и видео инструкциями.

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

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