3

I am am trying to make a code which automatically controls relay on basis of ultrasonic sensor measurements. I am using a nodeMCU as a microcontroller rather than an arduino. The relay and the ultrasonic sensor is being powered from a 5V source and nodemcu from a 3.3V Source. I don't think none of the sensors are interfering with each other as all the sensors are kept at a distanceenter image description here. Due to the random values my relay is being latched without any reason. Can someone please help me out with the problem. I don't want these values(above 3000) being shown in the serial monitor.

#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);

}
  • Please no text as image. You can copy and paste the text from the serial monitor and format it as code. – chrisl Nov 20 '20 at 21:35
  • First thing: disconnect the relay, and try to just measure the distance. If it's still as bad, then either your target is not providing a strong enough echo, or some other object is giving too strong an echo. – Edgar Bonet Nov 23 '20 at 10:44
1

These random values could be nothing but noise as your receiver may be sensing other source of ultra sound. In your case, the circuit is especially sensitive as the output powers a relay and any noise in the input side will cause the relay to "chatter". There are many approaches to filtering and smoothing out the signal. One method would be to implement a basic averaging algorithm where you take several readings and then average out the result. Compare this result with the threshold and the output should be smoother.

EDIT

Here is a rudimentry example, where I take multiple readings (nb_measurements measurements) and then take the average over it:

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);

}

Due to the extra processing, this will be in theory slower than your previous code but in practice, you wouldn't perceive it as long as you keep nb_measurements at a reasonable value. There are more complex digital signal filtering algorithms, search around and you can find good documentation and libraries online.

  • Could you help me with that please – Shubham Bajaj Nov 21 '20 at 14:05
  • @ShubhamBajaj, Sure have a look at the edited answer – glamis Nov 22 '20 at 21:58
  • Look at the OP's data: averaging won't help. The bad values are about 50 times larger than the good ones. A single bad value within your 10 samples will put the average completely off. And these bad values are about 50% of the samples. – Edgar Bonet Nov 23 '20 at 10:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.