Если в своем электронном проекте вы хотите измерять расстояние до препятствий (например, вы создаете робота, объезжающего препятствия), то наиболее просто это можно сделать с помощью одного из ультразвуковых датчиков измерения расстояний, самым распространенным из которых является датчик HC-SR04. В данной статье мы рассмотрим основные принципы работы ультразвукового датчика HC-SR04 и способ его подключения к WiFi модулю ESP32.
Датчик HC-SR04 имеет дальность обнаружения 13 футов (4 метра) и угол зрения 15 градусов, что отлично подходит для обнаружения препятствий. При этом он потребляет достаточно малый ток во время своей работы, что делает его отличным выбором для проектов, работающих от батареек (аккумуляторов).
Также на нашем сайте мы рассматривали подключение ультразвукового датчика HC-SR04 к другим микроконтроллерам (платам):
- к микроконтроллеру AVR;
- к микроконтроллеру PIC;
- к плате Arduino;
- к плате Raspberry Pi;
- к плате Raspberry Pi Pico;
- к модулю ESP8266;
- к плате STM32 Blue Pill.
Необходимые компоненты
- Модуль ESP32 (купить на AliExpress).
- Ультразвуковой датчик HC-SR04 (купить на AliExpress).
- OLED дисплей, работающий по протоколу I2C (купить на AliExpress).
Распиновка ультразвукового датчика HC-SR04
Ультразвуковой датчик для определения расстояний HC-SR04 содержит 4 контакта: VCC, Trig, Echo и Gnd. Вход и выход датчика являются цифровыми, поэтому их необходимо подключать к цифровым контактам микроконтроллера. Распиновка (назначение контактов) ультразвукового датчика HC-SR04 показана на следующем рисунке.
VCC – контакт для подачи питания на модуль HC-SR04. В нашем проекте его необходимо подключить к контакту 5V модуля ESP32.
Trig – триггерный (запускающий) контакт модуля HC-SR04. При подаче на данный контакт импульса HIGH на 10 мкс модуль запускается в работу и излучает в окружающее пространство серию ультразвуковых импульсов.
Echo – контакт echo модуля датчика HC-SR04. На этом контакте сохраняется уровень high до тех пор датчик не примет обратно излученную им серию ультразвуковых импульсов, либо не истечет заданное время для приема этих импульсов (кончится тайм-аут).
GND – контакт общего провода (земли) датчика, в нашем проекте его необходимо подключить к контакту ground модуля ESP32.
Принципы работы ультразвукового датчика HC-SR04
Ультразвук представляет собой звуковую волну, частота колебаний которой превосходит частоту, которое способно слышать человеческое ухо. За верхнюю частоту, слышимую человеческому уху, обычно принимают частоту равную 20 кГц. Таким образом, датчик HC-SR04 излучает звуковые волны, которые не в состоянии услышать человек.
HC-SR04 состоит из двух ультразвуковых датчиков, один работает как передатчик на частоте 40 кГц, а другой – как приемник импульсов на этой частоте. Датчик формирует на своем выходном контакте (Echo) импульс, длительность которого пропорциональна расстоянию до препятствия. Определив с помощью микроконтроллера длительность данного импульса мы можем рассчитать расстояние до препятствия. С помощью датчика HC-SR04 можно определять расстояния в диапазоне от 2 до 400 см. Датчик можно подключить к практически любому современному микроконтроллеру.
Чтобы начать процесс измерения расстояний на контакт trigger датчика HC-SR04 необходимо подать уровень high на время 10 мкс (10uS). После этого датчик излучит в пространство серию из 8 ультразвуковых импульсов, параметры которых подобраны таким образом, чтобы они существенно отличались от ультразвуковых волн окружающего пространства. Когда процесс передачи серии из данных 8 импульсов будет завершен, на контакте echo будет формироваться импульс, пропорциональный расстоянию до препятствия. Длительность этого импульса может составлять от 150 мкс до 25 мс. Если переданный сигнал не вернется в виде отраженной волны к датчику в течение 38 мс это будет означать что в диапазоне действия датчика не обнаружено никакого препятствия.
Расстояние до препятствия можно рассчитать по формуле:
1 |
Distance = Speed x Time |
Скорость звука в воздухе составляет 343,2 м/с, для удобства переведем ее в см/мкс, что составит 0,03432 см/мкс. Если длительность импульса на контакте echo будет равна 700 мкс, то расстояние до препятствия при этом составит:
1 |
Distance = (0.03432 cm/us x 700uS) / 2 = 12.012 cm |
Делим на 2 потому что длительность импульса на контакте echo равна времени распространения ультразвуковой волны до препятствия и обратно.
Наиболее часто задаваемые вопросы про датчик HC-SR04
Какова максимальная дальность действия датчика HC-SR04?
Она составляет 400 см (13 футов).
Может ли датчик HC-SR04 обнаруживать воду?
Да, может, поэтому его можно использовать для раннего обнаружения потопов, наводнений и т.д., а также для обнаружения уровня воды в контейнере.
Является ли ультразвуковой датчик HC-SR04 водозащищенным?
Нет, датчик HC-SR04 имеет достаточно хлипкую конструкцию и может быть легко поврежден порывами ветрами или водой (влагой). Но существует водозащищенная версия данного датчика, подключение которой к плате Arduino мы рассматривали в данной статье.
Может ли датчик HC-SR04 работать от напряжения 3.3V?
Согласно даташиту на датчик его нельзя запитывать от напряжения 3.3V, но его можно подключать к микроконтроллерам, контакты которых работают на 3.3V, в данном случае на контакт trigger датчика можно подавать уровень 3.3V, а для считывания импульса с контакта echo использовать делитель напряжения, преобразующий 5V в 3.3V.
Схема проекта
Схема подключения ультразвукового датчика HC-SR04 к модулю ESP32 представлена на следующем рисунке.
Внешний вид собранной конструкции проекта показан на следующем рисунке.
Объяснение кода программы
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
В нашей программе мы будем измерять расстояние до препятствия с помощью ультразвукового датчика HC-SR04 и выводить значение расстояния на экран дисплея с разрешением 128X64. В коде программы мы будем использовать библиотеки Adafruit_GFX, Adafruit_SSD1306.h и NewPing.h.
Первым делом в коде программы подключим используемые библиотеки. Библиотеке Adafruit_GFX для ее работы необходимы библиотеки SPI.h и Wire.h, поэтому также подключим их в программе.
1 2 3 4 5 |
#include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include "NewPing.h" |
Дадим осмысленные названия контактам модуля ESP32, к которым подключены контакты Trigger и echo датчика HC-SR04. Также укажем максимальное теоретическое расстояние, на котором датчик HC-SR04 может обнаруживать препятствие.
1 2 3 4 |
#define TRIGGER_PIN 14 #define ECHO_PIN 27 // Maximum distance we want to ping for (in centimeters). #define MAX_DISTANCE 400 |
Далее зададим ширину и высоту экрана для используемого нами OLED дисплея. Также зададим для параметра OLED Reset значение -1 – это требуется библиотекой.
1 2 3 4 |
#define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET -1 // |
Затем создадим объект для работы с датчиком HC-SR04 и объект для работы с OLED дисплеем.
1 2 |
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); |
После этого в функции setup инициализируем последовательную связь со скоростью 115200 для целей отладки и используем метод display.begin для инициализации OLED дисплея.
1 2 3 4 5 6 7 8 |
void setup() { Serial.begin(115200); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } } |
В функции loop() мы будем выводить измеренное значение расстояния в окно монитора последовательной связи и вызывать функцию update_display() для обновления информации на экране дисплея.
1 2 3 4 5 6 7 |
void loop() { Serial.print("Distance = "); Serial.print(sonar.ping_cm()); Serial.println(" cm"); delay(300); update_display(); } |
В функции update_display() мы будем очищать экран дисплея, устанавливать размер текста, устанавливать цвет экрана дисплея белым и выводить значения расстояния на экран дисплея.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void update_display(){ display.clearDisplay(); display.setTextSize(2); delay(1); display.setTextColor(WHITE); delay(1); display.println(F("Distance")); delay(1); display.println(sonar.ping_cm()); delay(1); display.println("cm"); delay(1); display.display(); delay(500); } |
Тестирование работы проекта
На следующем видео представлено тестирование работы нашего проекта. Мы запрограммировали модуль ESP32 таким образом, что информация на экране дисплея будет обновляться каждый раз когда в модуль ESP32 будут поступать новые данные о расстоянии до препятствия.
Возможные проблемы при работе с датчиком HC-SR04
Если вы наблюдаете какие либо проблемы при работе с ультразвуковым датчиком HC-SR04 первым делом проверьте линию подачи на него питания. Датчик HC-SR04 запитывается от напряжения 5V, если вы его запитали от 3.3V он будет работать нестабильно.
Модуль датчика HC-SR04 может выдавать некорректную информацию о расстоянии если вы используете не поддерживаемую им библиотеку, поэтому проверьте библиотеку, которую вы установили на предмет того чтобы она поддерживалась модулем.
Если ваш модуль HC-SR04 по прежнему не работает попробуйте заменить его на другой аналогичный.
Исходный код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
// Include NewPing Library #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include "NewPing.h" // Hook up HC-SR04 with Trig to Arduino Pin 9, Echo to Arduino pin 10 #define TRIGGER_PIN 14 #define ECHO_PIN 27 // максимальное расстояние, обнаруживаемое датчиком (в см) #define MAX_DISTANCE 400 #define SCREEN_WIDTH 128 // ширина OLED дисплея в пикселях #define SCREEN_HEIGHT 64 // высота display дисплея в пикселях // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) // создаем с помощью библиотеки NewPing объект для работы с ультразвуковым датчиком NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup() { Serial.begin(115200); // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // не продолжаем, бесконечный цикл } } void loop() { Serial.print("Distance = "); Serial.print(sonar.ping_cm()); Serial.println(" cm"); delay(300); update_display(); } void update_display() { display.clearDisplay(); display.setTextSize(2); delay(1); display.setTextColor(WHITE); delay(1); display.println(F("Distance")); delay(1); display.println(sonar.ping_cm()); delay(1); display.println("cm"); delay(1); display.display(); delay(500); ESP.restart(); } |