Ультразвуковой датчик (HC-SR04), регистрирующий случайное расстояние

Я пытаюсь создать код, который автоматически управляет реле на основе измерений ультразвукового датчика. Я использую NodeMCU в качестве микроконтроллера, а не arduino. Реле и ультразвуковой датчик питаются от источника 5 В, а nodemcu - от источника 3,3 В. Я не думаю, что ни один из датчиков не мешает друг другу, поскольку все датчики находятся на расстоянии. Из-за случайных значений мое реле защелкивается без какой-либо причины. Может кто-нибудь, пожалуйста, помочь мне с этой проблемой. Я не хочу, чтобы эти значения (выше 3000) отображались на последовательном мониторе.

#define TRIGGER 5
#define ECHO    4
#define RELAY   0

void setup() {
  Serial.begin(9600);
  pinMode(TRIGGER, OUTPUT);
  pinMode(ECHO, INPUT);
  pinMode(BUILTIN_LED, OUTPUT);
  pinMode(RELAY, OUTPUT);
}
void loop() {
  long duration, distance;
  digitalWrite(TRIGGER, LOW);
  delayMicroseconds(10);

  digitalWrite(TRIGGER, HIGH);
  delayMicroseconds(10);

  digitalWrite(TRIGGER, LOW);
  duration = pulseIn(ECHO, HIGH);
  distance = (duration / 2) / 29.1;

  if (distance < 30 ){
    digitalWrite(RELAY, HIGH);
  }else{  
    digitalWrite(RELAY, LOW);
  }

  Serial.print("Centimeters: ");
  Serial.println(distance);

}

, 👍3

Обсуждение

Пожалуйста, никакого текста в качестве изображения. Вы можете скопировать и вставить текст с последовательного монитора и отформатировать его как код., @chrisl

Первое, что нужно сделать: отсоедините реле и попробуйте просто измерить расстояние. Если это все так же плохо, то либо ваша цель не дает достаточно сильного эха, либо какой-то другой объект дает слишком сильное эхо., @Edgar Bonet


1 ответ


1

Эти случайные значения могут быть ничем иным, как шумом, поскольку ваш приемник может воспринимать другой источник ультразвука. В вашем случае схема особенно чувствительна, так как выход питает реле, и любой шум на стороне входа приведет к "дребезжанию" реле. Существует множество подходов к фильтрации и сглаживанию сигнала. Одним из методов может быть реализация базового алгоритма усреднения, при котором вы снимаете несколько показаний, а затем усредняете результат. Сравните этот результат с пороговым значением, и результат должен быть более плавным.

Обновлено

Вот элементарный пример, где я беру несколько показаний (измерения nb_measurements), а затем беру среднее значение по нему:

long getDuration() {
  digitalWrite(TRIGGER, LOW);
  delayMicroseconds(10);

  digitalWrite(TRIGGER, HIGH);
  delayMicroseconds(10);

  digitalWrite(TRIGGER, LOW);
  return pulseIn(ECHO, HIGH);
}

void loop() {
  float duration = 0, distance = 0;
  int nb_measurements = 10;
  for (int i = 0; i < nb_measurements; i++) {
    duration += getDuration();
  }
  duration = duration/nb_measurements;
  distance = (duration / 2) / 29.1;

  if (distance < 30 ){
    digitalWrite(RELAY, HIGH);
  } else{  
    digitalWrite(RELAY, LOW);
  }

  Serial.print("Centimeters: ");
  Serial.println(distance);

}

Из-за дополнительной обработки теоретически это будет медленнее, чем ваш предыдущий код, но на практике вы не почувствуете этого, если будете поддерживать nb_measurements на разумном уровне. Существуют более сложные алгоритмы фильтрации цифровых сигналов, поищите их, и вы сможете найти хорошую документацию и библиотеки в Интернете.

,

Не могли бы вы помочь мне с этим, пожалуйста, @Shubham Bajaj

@ShubhamBajaj, Обязательно взгляните на отредактированный ответ, @glamis

Посмотрите на данные операции: усреднение не поможет. Плохие значения примерно в 50 раз больше, чем хорошие. Одно неверное значение в пределах ваших 10 выборок полностью снизит среднее значение. И эти плохие значения составляют около 50% выборок., @Edgar Bonet

Есть ли способ уменьшить шум на аппаратном уровне, а не на программном?, @YaMiN

@YaMin Некоторый высокочастотный шум можно устранить с помощью развязывающего конденсатора малой величины, @glamis