Ультразвуковой датчик расстояния HC-SR04 на Raspberry Pi
В предыдущих руководствах мы рассмотрели датчики температуры, PIR-датчики движения и кнопки и переключатели, все из которых можно подключить напрямую к GPIO-портам Raspberry Pi. Ультразвуковой дальномер HC-SR04 очень прост в использовании, однако выходной сигнал необходимо преобразовать с 5 В до 3,3 В, чтобы не повредить наш Raspberry Pi! В этом руководстве мы познакомим вас с некоторыми основами физики и электроники, чтобы объяснить каждый шаг!
Что вам понадобится:
HC-SR04
Резистор 1 кОм
Резистор 2 кОм
Соединительные провода (Jumper Wires)
Ультразвуковые датчики расстояния
Звук состоит из колебательных волн, распространяющихся через среду (например, воздух), при этом высота тона определяется близостью этих волн друг к другу, что определяется как частота. Лишь часть звукового спектра (диапазона частот звуковых волн) воспринимается человеческим ухом и определяется как «акустический» диапазон. Очень низкочастотный звук ниже акустического диапазона называется «инфразвуком», а высокочастотный звук выше — «ультразвуком». Ультразвуковые датчики предназначены для определения близости объекта или расстояния до него с помощью отражения ультразвука, подобно радару, для вычисления времени, необходимого для отражения ультразвуковых волн между датчиком и твёрдым объектом. Ультразвук используется главным образом потому, что он не слышен человеческому уху и относительно точен на коротких дистанциях. Конечно, для этой цели можно использовать и акустический звук, но тогда у вас будет шумный робот, издающий звуковой сигнал каждые несколько секунд…
Базовый ультразвуковой датчик состоит из одного или нескольких ультразвуковых передатчиков (по сути, динамиков), приёмника и схемы управления. Передатчики излучают высокочастотный ультразвуковой сигнал, который отражается от любых ближайших твёрдых объектов. Часть этого ультразвукового шума отражается и обнаруживается приёмником датчика. Этот обратный сигнал затем обрабатывается схемой управления для вычисления разницы во времени между отправкой и получением сигнала. Это время впоследствии может быть использовано вместе с некоторыми хитрыми математическими расчётами для вычисления расстояния между датчиком и отражающим объектом.
Ультразвуковой датчик HC-SR04, который мы будем использовать в этом руководстве для Raspberry Pi, имеет четыре вывода: земля (GND), выход эхо-импульса (ECHO), вход триггерного импульса (TRIG) и питание 5 В (Vcc). Мы питаем модуль через Vcc, заземляем через GND и используем наш Raspberry Pi для отправки входного сигнала на TRIG, который запускает датчик для отправки ультразвукового импульса. Импульсные волны отражаются от ближайших объектов, и некоторые из них возвращаются обратно к датчику. Датчик обнаруживает эти обратные волны и измеряет время между триггерным и возвратным импульсом, а затем отправляет сигнал 5 В на вывод ECHO.
ECHO будет находиться в состоянии «низкого уровня» (0 В) до тех пор, пока датчик не будет запущен и не получит эхо-импульс. Как только обратный импульс будет обнаружен, ECHO устанавливается в «высокий уровень» (5 В) на время этого импульса. Длительность импульса — это полное время между отправкой датчиком ультразвукового импульса и обнаружением обратного импульса приёмником датчика. Поэтому наш Python-скрипт должен измерить длительность импульса и затем вычислить расстояние на основе этого значения.
ВАЖНО. Выходной сигнал датчика (ECHO) на HC-SR04 рассчитан на 5 В. Однако входной вывод GPIO Raspberry Pi рассчитан на 3,3 В. Подача 5 В сигнала на незащищённый вход 3,3 В может повредить ваши GPIO-выводы, чего мы хотим избежать! Нам потребуется использовать небольшую схему делителя напряжения, состоящую из двух резисторов, чтобы снизить выходное напряжение датчика до уровня, с которым наш Raspberry Pi может работать.
Делители напряжения
Делитель напряжения состоит из двух резисторов (R1 и R2), соединённых последовательно и подключённых к входному напряжению (Vin), которое необходимо понизить до нашего выходного напряжения (Vout). В нашей схеме Vin будет ECHO, которое необходимо уменьшить с 5 В до нашего Vout, равного 3,3 В.
Следующая схема и простое уравнение могут быть применены ко многим ситуациям, где необходимо снизить напряжение. Если вы не хотите вникать в техническую часть, просто возьмите 1 резистор на 1 кОм и 1 резистор на 2 кОм.
Не углубляясь слишком сильно в математику, нам фактически нужно вычислить только одно значение сопротивления, так как важно именно соотношение деления. Мы знаем наше входное напряжение (5 В) и требуемое выходное напряжение (3,3 В), и мы можем использовать любую комбинацию резисторов для достижения нужного снижения. У меня как раз есть куча лишних резисторов на 1 кОм, поэтому я решил использовать один из них в схеме в качестве R1.
Подставив наши значения, получим следующее:
Итак, мы используем резистор 1 кОм для R1 и резистор 2 кОм в качестве R2!
Сборка схемы
Для этого проекта мы будем использовать четыре вывода Raspberry Pi: GPIO 5V [Pin 2] — Vcc (питание 5 В), GPIO GND [Pin 6] — GND (земля 0 В), GPIO 23 [Pin 16] — TRIG (выход GPIO) и GPIO 24 [Pin 18] — ECHO (вход GPIO)
Подключите четыре провода «папа-мама» к выводам HC-SR04 следующим образом: Красный — Vcc, Синий — TRIG, Жёлтый — ECHO и Чёрный — GND.
Подключите Vcc к положительной шине макетной платы, а GND — к отрицательной шине.
Подключите GPIO 5V [Pin 2] к положительной шине, а GPIO GND [Pin 6] — к отрицательной шине.
Подключите TRIG к свободной шине и соедините эту шину с GPIO 23 [Pin 16]. (Вы можете подключить TRIG напрямую к GPIO 23, если хотите). Лично я просто предпочитаю делать всё на макетной плате!
Подключите ECHO к свободной шине, соедините с другой свободной шиной через R1 (резистор 1 кОм)
Соедините шину R1 с шиной GND через R2 (резистор 2 кОм). Оставьте промежуток между двумя резисторами.
Подключите GPIO 24 [Pin 18] к шине с вашим R1 (резистор 1 кОм). Этот GPIO-вывод должен находиться между R1 и R2
Вот и всё! Наш датчик HC-SR04 подключён к нашему Raspberry Pi!
Программирование на Python
Теперь, когда мы подключили наш ультразвуковой датчик к Pi, нам нужно написать Python-скрипт для определения расстояния!
Выходной сигнал ультразвукового датчика (ECHO) всегда будет на низком уровне (0 В), пока он не будет запущен — в этом случае он выдаст 5 В (3,3 В с нашим делителем напряжения!). Поэтому нам нужно настроить один GPIO-вывод как выход для запуска датчика и один как вход для обнаружения изменения напряжения на ECHO.
Сначала импортируем библиотеку Python GPIO, импортируем библиотеку time (чтобы наш Pi делал паузы между шагами) и зададим нумерацию GPIO-выводов.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
Далее нам нужно задать имена нашим входному и выходному выводам, чтобы мы могли обращаться к ним позже в нашем Python-коде. Мы назовём наш выходной вывод (который запускает датчик) GPIO 23 [Pin 16] как TRIG, а наш входной вывод (который считывает обратный сигнал от датчика) GPIO 24 [Pin 18] как ECHO.
TRIG = 23
ECHO = 24
Затем мы выведем сообщение, чтобы сообщить пользователю, что идёт измерение расстояния…
print("Distance Measurement In Progress")
Далее настроим два GPIO-порта как входы или выходы, как было определено ранее.
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
Затем убедимся, что вывод Trigger установлен в низкий уровень, и дадим датчику секунду на стабилизацию.
GPIO.output(TRIG, False)
print("Waiting For Sensor To Settle")
time.sleep(2)
Датчик HC-SR04 требует короткий импульс длительностью 10 мкс для запуска модуля, что заставит датчик начать программу дальнометрии (8 ультразвуковых импульсов на частоте 40 кГц) для получения эхо-ответа. Итак, чтобы создать наш триггерный импульс, мы устанавливаем вывод trigger в высокий уровень на 10 мкс, а затем снова в низкий.
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
Теперь, когда мы отправили наш импульсный сигнал, нам нужно прослушивать наш входной вывод, который подключён к ECHO. Датчик устанавливает ECHO в высокий уровень на время, необходимое для прохождения импульса туда и обратно, поэтому наш код должен измерить время, в течение которого вывод ECHO находится в высоком состоянии. Мы используем цикл «while» для обеспечения того, чтобы каждая временная метка сигнала была записана в правильном порядке.
Функция time.time() записывает последнюю временную метку для данного условия. Например, если вывод переходит из низкого в высокий уровень, и мы записываем низкое состояние с помощью функции time.time(), записанная временная метка будет последним моментом, когда этот вывод был в низком состоянии.
Поэтому нашим первым шагом должна быть запись последней временной метки низкого уровня для ECHO (pulse_start), то есть непосредственно перед получением обратного сигнала и переходом вывода в высокий уровень.
while GPIO.input(ECHO) == 0:
pulse_start = time.time()
Как только сигнал получен, значение меняется с низкого (0) на высокое (1), и сигнал будет оставаться высоким на протяжении длительности эхо-импульса. Поэтому нам также нужна последняя временная метка высокого уровня для ECHO (pulse_end).
while GPIO.input(ECHO) == 1:
pulse_end = time.time()
Теперь мы можем вычислить разницу между двумя записанными временными метками и, следовательно, длительность импульса (pulse_duration).
pulse_duration = pulse_end - pulse_start
Зная время, за которое сигнал проходит до объекта и обратно, мы можем вычислить расстояние по следующей формуле.
Скорость звука непостоянна и зависит от среды, через которую он распространяется, а также от температуры этой среды. Однако некоторые умные физики вычислили скорость звука на уровне моря, поэтому мы примем базовое значение 343 м/с. Если вы пытаетесь измерить расстояние через воду, именно здесь вы ошибётесь — убедитесь, что используете правильную скорость звука!
Нам также нужно разделить наше время на два, потому что то, что мы рассчитали выше, — это фактически время, за которое ультразвуковой импульс проходит расстояние до объекта и обратно. Нам нужно только расстояние до объекта! Мы можем упростить расчёт для выполнения в нашем Python-скрипте следующим образом:
Мы можем добавить этот расчёт в наш Python-скрипт:
distance = pulse_duration * 17150
Теперь нам нужно округлить наше расстояние до 2 знаков после запятой (для аккуратности!)
distance = round(distance, 2)
Затем мы выводим расстояние. Приведённая ниже команда выведет слово «Distance:», за которым следует переменная distance, а затем единица измерения «cm»
print("Distance:", distance, "cm")
Наконец, мы очищаем наши GPIO-выводы, чтобы убедиться, что все входы/выходы сброшены
GPIO.cleanup()
Сохраните ваш Python-скрипт (мы назвали наш «range_sensor.py») и запустите его с помощью следующей команды. Запуск от имени root (sudo) важен для этого скрипта:
Датчик стабилизируется в течение нескольких секунд, а затем измерит ваше расстояние!
Источники
Благодарим следующие источники за информацию для этого руководства:
Raspberry Pi Spy — Часть 1
Raspberry Pi Spy — Часть 2