Using a HC-SR04 to activate relay for 15 seconds. How to avoid delay??

Hi guys,

I’ve been pulling my hair out with this one, and I know it’s a simple fix using millis.

I have a HC-SR04 and I want it to activate a relay when someone is within about 50 cm.

I’ve been using the ‘blinkwithoutdelay’ tutorials on the web, but it clicks the relay on and then instantly off again, every 5 seconds (my chosen interval). I’d like the relay to be held on, for 5 seconds, and then turned off for five.

Can you help? I think I’m going bald with not quite understanding what’s going on.

Sorry for the formatting!

#include <NewPing.h>
#define trigPin 5
#define echoPin 6
#define relayPin 7
#define MAX_DISTANCE 400
NewPing sonar (trigPin,echoPin,MAX_DISTANCE);

int relayState = LOW;
unsigned long previousMillis = 0;
unsigned long onTime = 5000;

void setup() {


pinMode(trigPin,OUTPUT);
pinMode(echoPin, INPUT);
pinMode(relayPin,OUTPUT);

}
void loop() {

int duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin,HIGH);
delayMicroseconds(10);
digitalWrite(trigPin,LOW);
duration = pulseIn(echoPin,HIGH);
distance = (duration /2) /29.1;

if (distance <= 50){
unsigned long currentMillis = millis();

 if (currentMillis - previousMillis >= onTime) {
   previousMillis = currentMillis;
   if (relayState == LOW) {
     relayState = HIGH;
   } else {
     relayState = LOW;
   }
   digitalWrite(relayPin, relayState);
 }
}
}
}

Change to this:

previousMillis = currentMillis + onTime;

Hi,
Something's funny here; too many closing braces?? Oh, and Crossroad's point !!

The IDE will show you the matching braces if you click to one of them (other is then highlighted)

And use Tools > Auto Format to make it easier to see stuff..


          Code : [Select]
#include <NewPing.h>
#define trigPin 5
#define echoPin 6
#define relayPin 7
#define MAX_DISTANCE 400
            NewPing sonar (trigPin, echoPin, MAX_DISTANCE);

int relayState = LOW;
unsigned long previousMillis = 0;
unsigned long onTime = 5000;

void setup() {


  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(relayPin, OUTPUT);

}
void loop()
{

  int duration, distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2) / 29.1;

  if (distance <= 50)
  {
    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= onTime)
    {
      previousMillis = currentMillis;
      if (relayState == LOW) {
        relayState = HIGH;
      } else {
        relayState = LOW;
      }
      digitalWrite(relayPin, relayState);
    }
  } // END distance < 50
}  // END Loop
// why is this here?   }

Thank you for the replies!

Unfortunately it didn't seem to work.

I have uploaded a short video of the issue. You can see it's bouncing around all over the place.

I'm sure it's something to do with the de-bounce code, I just can't get my head around it. It's perfectly fine when using delay() as it hides all the noise, but I cannot use this as I'm running other things.

Here's a video of it buzzing like crazy.

Also thank you for the formatting tip! Auto format! Amazing!

Okay sussed it out!

Thanks for the help!

I’m back!

I got the sensor working fine. No noise, no stuttering (thanks to the internal pullup resistor I’d forgotten about)

HOWEVER

I want the relay to activate when approached, stay on for 2 seconds, and then stay off for 4 seconds. During the 6 seconds it is on and off, I want it to ignore any further inputs (it’s powering a mist machine)

I have got to the point where it will turn on for two seconds, however, it then stays on if you remain within the allotted distance. I need it to turn off, and stay off, for the 4 seconds.

I’ve studied the BlinkWithOutDelay tutorials, but they rely on state changes, which is not what I want. I effectively want to copy the digitalWrite(relayPin,HIGH) - delay(2000) - digitalWrite(relayPin,LOW) - delay(4000) code.

Would you be able to point me in the right direction?

Here’s the code (ignore the float switch bits)

#include <NewPing.h>
#define trigPin 5
#define echoPin 6
#define relayPin 2
#define floatSwitch 8
#define MAX_DISTANCE 400
NewPing sonar (trigPin, echoPin, MAX_DISTANCE);

//SONAR STUFF

unsigned long onTime;
unsigned long offTime;
long previousMillis = 0;

void setup() {


  pinMode(floatSwitch, INPUT_PULLUP);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(relayPin, OUTPUT);

}
void loop() {

  unsigned long currentMillis = millis();
  byte switchState = digitalRead (floatSwitch);

  //FLOAT SWITCH STUFF

  if (switchState == LOW) {
    digitalWrite(relayPin, LOW);
  }
  else
  {

    //DISTANCE MEASURING STUFF

    int duration, distance;
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(50);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    distance = (duration / 2) / 29.1;

    //RELAY ON/OFF STUFF

    if (distance <= 100) {

      (digitalWrite(relayPin, HIGH));
      onTime = currentMillis + 2000;
      if
      (currentMillis > onTime) {
        (digitalWrite(relayPin, LOW));
        offTime = currentMillis + 4000;
        currentMillis = previousMillis;
      }
    }

  }
  if (millis() > onTime) {
    digitalWrite(relayPin, LOW);
  }
}