Ультразвуковой датчик HC-SR04 определения расстояния до предметов. Принцип роботы как у сонара, посылается пучок импульсов и получает отражения, и на основании задержки определяется расстояние до предмете. Так как датчик для определения расстояния основан на ультразвуки, он плохо работает для определения расстояния до звукопоглощающих предметов. Идеальными являются предметы с ровной и гладкой поверхностью например ПАНЕЛИ, ВАГОНКА ПВХ.
Описание ультразвукового дальномера HC-SR04
Датчик HC-SR04 является бесконтактным. Точность измерения обеспечивается от 2 до 400 см. На его работу не оказывает существенного воздействия электромагнитные излучения и солнечная энергия.
Ультразвуковой дальномер HC-SR04 имеет такие технические параметры:
- Рабочее напряжение 5В
- Сила тока в пассивном состоянии < 2 мА
- Рабочий параметр силы тока – 15 мА
- Измерительный угол — 30°
- Обзорный угол — 15°
Контакты подключения:
- Контакт питания +5В
- Trig – выход сигнала входа
- Echo – вывод сигнала выхода
- GND – «Земля»
Схема подключения ультразвукового датчика HC-SR04 к Arduino UNO
Самой распространенной библиотекой для работы с датчиком HC-SR04 является NewPing. Описание и подледную версию можно найти на страничке проекта
Пример скетча который предложен на странице библиотеки NewPing
#include <NewPing.h>
#define TRIGGER_PIN 12
#define ECHO_PIN 11
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
void setup() {
Serial.begin(115200);
}
void loop() {
delay(200);
Serial.print("Ping: ");
Serial.print(sonar.ping_cm());
Serial.println("cm");
}
Откроем монитор Serial порта.
Как видим датчик HC-SR04 работает но есть шум. Выводит через определенное время нулевые значения. Данный код можно улучшить.
#include <NewPing.h>
#define TRIGGER_PIN 12
#define ECHO_PIN 11
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
float dist_3[3] = {0.0, 0.0, 0.0}; // массив для хранения трёх последних измерений
float middle, dist, dist_filtered;
float k;
byte i, delta;
unsigned long dispIsrTimer, sensTimer;
void setup() {
Serial.begin(115200);
}
void loop() {
if (millis() - sensTimer > 200) { // измерение и вывод каждые 50 мс
// счётчик от 0 до 2
// каждую итерацию таймера i последовательно принимает значения 0, 1, 2, и так по кругу
if (i > 1) i = 0;
else i++;
dist_3[i] = (float)sonar.ping() / 57.5; // получить расстояние в текущую ячейку массива
dist = middle_of_3(dist_3[0], dist_3[1], dist_3[2]); // фильтровать медианным фильтром из 3ёх последних измерений
delta = abs(dist_filtered - dist); // расчёт изменения с предыдущим
if (delta > 1) k = 0.7; // если большое - резкий коэффициент
else k = 0.1; // если маленькое - плавный коэффициент
dist_filtered = dist * k + dist_filtered * (1 - k); // фильтр "бегущее среднее"
Serial.print("Ping: ");
Serial.print(dist_filtered);
Serial.println("cm"); // вывести
sensTimer = millis(); // сбросить таймер
}
}
// медианный фильтр из 3ёх значений
float middle_of_3(float a, float b, float c) {
if ((a <= b) && (a <= c)) {
middle = (b <= c) ? b : c;
}
else {
if ((b <= a) && (b <= c)) {
middle = (a <= c) ? a : c;
}
else {
middle = (a <= b) ? a : b;
}
}
return middle;
}
Данные стали более стабильные и немного точнее. Но идеальных значений не получить. Потому что значения зависит от расстояния измерения. Чем ближе предмет и более гладкая поверхность тем точнее будут измерения.
Подписывайтесь на мой канал на Youtube и вступайте в группы в Вконтакте и Facebook.
Спасибо за внимание!
Понравилась статья? Поделитесь ею с друзьями:
Комментарии
Войдите или Зарегистрируйтесь И Вы сможете общаться на форуме и оставлять комментарии без капчи.