Using multiple Ultrasonic Sensors witch 4 channel relay

Hi all, let me explain what i want to do :

I have 2 Utlrasonic HC-SR04 sensor , connected to a arduino uno r3 witch a 4 channel relais.

if sensor1 detects movement then relais1 gets on for 20 seconds
if sensor2 detects movement then relais2 gets on for 10 seconds.

the problem is i get this work, but not with delay.
if i use delay, then one of the sensor does'nt respons for the peroid of time.

i googled for this , get to millis but i dont know how to implant this to my code.

can somebody help me out with this ?

my code now is :

int Relais1 = 11;
int Relais2 = 10;

int trigSensor1 = 13;
int echoSensor1 = 12;

int trigSensor2 = 9;
int echoSensor2 = 8;

void setup() {
  Serial.begin (9600);
  pinMode(trigSensor1, OUTPUT);
  pinMode(echoSensor1, INPUT);
 
  pinMode(trigSensor2, OUTPUT);
  pinMode(echoSensor2, INPUT);
 
  pinMode(Relais1, OUTPUT);
  pinMode(Relais2, OUTPUT);
}

void firstsensor(){ // This function is for first sensor.
  int duration1, distance1;
  digitalWrite (trigSensor1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigSensor1, LOW);
  duration1 = pulseIn (echoSensor1, HIGH);
  distance1 = (duration1/2) / 29.1;

      Serial.print("1st Sensor: ");
      Serial.print(distance1); 
      Serial.print("cm    ");

  if (distance1 < 100) {  // Change the number for long or short distances.
    digitalWrite (Relais1, LOW);
  
  } else {
    digitalWrite (Relais1, HIGH);
  }   
}
void secondsensor(){ // This function is for second sensor.
    int duration2, distance2;
    digitalWrite (trigSensor2, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigSensor2, LOW);
    duration2 = pulseIn (echoSensor2, HIGH);
    distance2 = (duration2/2) / 29.1;
 
      Serial.print("2nd Sensor: ");
      Serial.print(distance2); 
      Serial.print("cm    ");
  
    if (distance2 < 70) {  // Change the number for long or short distances.
      digitalWrite(Relais2, LOW);
      
    }
 else {
      digitalWrite (Relais2, HIGH);
     
    }   
}

void loop() {
Serial.println("\n");
firstsensor();
secondsensor();
delay(100);
}

You should read the Using millis() for timing. A beginners guide tutorial that is anchored at the top of the forum. Everything will come clear :slight_smile:

(and you can take a "state machine" approach to coding this)

@J-M-L

I read that section, but i don't know where to put the code inside my code.

what do you mean with "state machine"?

J-M-L:
You should read the Using millis() for timing. A beginners guide tutorial that is anchored at the top of the forum. Everything will come clear :slight_smile:

(and you can take a "state machine" approach to coding this)

Practice with the tutorial until you get how it works

State machines -> google « Arduino state machine tutorial » I’m sure you will find tons of stuff

Oke i get it working but nog 100% good.

This happens now :

sensor1 detects someone, relais 1 goes on, after 10 seconds it goes off,

but when i wait for 5 seconds , and sensor detects again, it power off after 5 seconds.
i looks like that the timer is not resetting.

this is my code now :

#define INTERVAL_MESSAGE1 10000
#define INTERVAL_MESSAGE2 5000

unsigned long time_1 = 0;
unsigned long time_2 = 0;

int Relais1 = 11;
int Relais2 = 10;

int trigSensor1 = 13;
int echoSensor1 = 12;

int trigSensor2 = 9;
int echoSensor2 = 8;

void setup() {
  Serial.begin (9600);
  pinMode(trigSensor1, OUTPUT);
  pinMode(echoSensor1, INPUT);
 
  pinMode(trigSensor2, OUTPUT);
  pinMode(echoSensor2, INPUT);
 
  pinMode(Relais1, OUTPUT);
  pinMode(Relais2, OUTPUT);
}

void firstsensor(){ // This function is for first sensor.
  int duration1, distance1;
  digitalWrite (trigSensor1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigSensor1, LOW);
  duration1 = pulseIn (echoSensor1, HIGH);
  distance1 = (duration1/2) / 29.1;

      Serial.print("1st Sensor: ");
      Serial.print(distance1); 
      Serial.print("cm    ");

  if (distance1 < 100) {  // Change the number for long or short distances.
    digitalWrite (Relais1, LOW);
  } else {
     if(millis() > time_1 + INTERVAL_MESSAGE1){
        time_1 = millis();
        digitalWrite (Relais1, HIGH);
        Serial.println("I'm message number one!");
     }
  }   
}
void secondsensor(){ // This function is for second sensor.
    int duration2, distance2;
    digitalWrite (trigSensor2, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigSensor2, LOW);
    duration2 = pulseIn (echoSensor2, HIGH);
    distance2 = (duration2/2) / 29.1;
 
      Serial.print("2nd Sensor: ");
      Serial.print(distance2); 
      Serial.print("cm    ");
  
    if (distance2 < 70) {  // Change the number for long or short distances.
      digitalWrite(Relais2, LOW);
      
    }
 else {
      if(millis() > time_2 + INTERVAL_MESSAGE2){
        time_2 = millis();
        digitalWrite (Relais2, HIGH);
        Serial.println("I'm message number two!");
     }
     
    }   
}

void loop() {
Serial.println("\n");
firstsensor();
secondsensor();
delay(100);
}

Is your relay active LOW or HIGH?

When you trigger (or re-trigger) you need to initialize time1 or time2 to the current value of millis(), this way you’ll get going for an extra full 20s

Note that it’s best to use unsigned long for things related to timing and the test to see if time is up is best written

if (millis() - startTime >= duration) {
  // timeOut - we are done
} else {
  // still within duration
}

rather than having the start time on the other side of the >=. That’s because when millis() rolls over (in 50 days...) a subtraction will keep the test valid.

it is a low relay,

i tried your suggestion, but it doesn't work

Post what you tried

This is what is tried :

#define INTERVAL_TIME1 10000
#define INTERVAL_TIME2 5000

unsigned long time_1 = 0;
unsigned long time_2 = 0;

int Relais1 = 11;
int Relais2 = 10;

int trigSensor1 = 13;
int echoSensor1 = 12;

int trigSensor2 = 9;
int echoSensor2 = 8;

void setup() {
  Serial.begin (9600);
  pinMode(trigSensor1, OUTPUT);
  pinMode(echoSensor1, INPUT);
 
  pinMode(trigSensor2, OUTPUT);
  pinMode(echoSensor2, INPUT);
 
  pinMode(Relais1, OUTPUT);
  pinMode(Relais2, OUTPUT);
}

void firstsensor(){ // This function is for first sensor.
  int duration1, distance1;
  digitalWrite (trigSensor1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigSensor1, LOW);
  duration1 = pulseIn (echoSensor1, HIGH);
  distance1 = (duration1/2) / 29.1;

      Serial.print("1st Sensor: ");
      Serial.print(distance1); 
      Serial.print("cm    ");

  if (distance1 < 100) {  // Change the number for long or short distances.
    digitalWrite (Relais1, LOW);
  } else {
     if(millis() > time_1 + INTERVAL_TIME1){
        time_1 = millis();
        digitalWrite (Relais1, HIGH);
        Serial.println("I'm message number one!");
     }
  }   
}
void secondsensor(){ // This function is for second sensor.
    int duration2, distance2;
    digitalWrite (trigSensor2, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigSensor2, LOW);
    duration2 = pulseIn (echoSensor2, HIGH);
    distance2 = (duration2/2) / 29.1;
 
      Serial.print("2nd Sensor: ");
      Serial.print(distance2); 
      Serial.print("cm    ");
  
    if (distance2 < 70) {  // Change the number for long or short distances.
        digitalWrite(Relais2, LOW);
    }
 else {
        if(millis() - time_2 >= INTERVAL_TIME2){
        time_2 = millis();
        digitalWrite (Relais2, HIGH);
        Serial.println("I'm message number two!");
        }
    }   
}

void loop() {
Serial.println("\n");
firstsensor();
secondsensor();
delay(100);
}

I don’t see anything I said being taken into account here

if (distance1 < 100) {  // Change the number for long or short distances.
    digitalWrite (Relais1, LOW);
  } else {
     if(millis() > time_1 + INTERVAL_TIME1){
        time_1 = millis();
        digitalWrite (Relais1, HIGH);
        Serial.println("I'm message number one!");
     }
  }

I get it working , witch the code below !

can i put also a servo in this code ?

#define INTERVAL_TIME1 10000
#define INTERVAL_TIME2 5000

unsigned long time_1 = 0;
unsigned long time_2 = 0;
unsigned long currentMillis = 0;

int Relais1 = 11;
int Relais2 = 10;

int trigSensor1 = 13;
int echoSensor1 = 12;

int trigSensor2 = 9;
int echoSensor2 = 8;

void setup() {
  Serial.begin (9600);
  pinMode(trigSensor1, OUTPUT);
  pinMode(echoSensor1, INPUT);
 
  pinMode(trigSensor2, OUTPUT);
  pinMode(echoSensor2, INPUT);
 
  pinMode(Relais1, OUTPUT);
  pinMode(Relais2, OUTPUT);
}

void firstsensor(){ // This function is for first sensor.
  int duration1, distance1;
  digitalWrite (trigSensor1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigSensor1, LOW);
  duration1 = pulseIn (echoSensor1, HIGH);
  distance1 = (duration1/2) / 29.1;

      Serial.print("1st Sensor: ");
      Serial.print(distance1); 
      Serial.print("cm    ");

  if (distance1 < 150) {  // Change the number for long or short distances.
    if(currentMillis - time_1 >= INTERVAL_TIME1){
    digitalWrite (Relais1, LOW);
    time_1 = currentMillis;
    }
  } else {
     if(currentMillis - time_1 >= INTERVAL_TIME1){
        digitalWrite (Relais1, HIGH);
        Serial.println("I'm message number one!");
     }
  }   
}
void secondsensor(){ // This function is for second sensor.
    int duration2, distance2;
    digitalWrite (trigSensor2, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigSensor2, LOW);
    duration2 = pulseIn (echoSensor2, HIGH);
    distance2 = (duration2/2) / 29.1;
 
      Serial.print("2nd Sensor: ");
      Serial.print(distance2); 
      Serial.print("cm    ");
  
    if (distance2 < 150) {  // Change the number for long or short distances.
        if(currentMillis - time_2 >= INTERVAL_TIME2){
    digitalWrite (Relais2, LOW);
    time_2 = currentMillis;
    }
  } else {
     if(currentMillis - time_2 >= INTERVAL_TIME2){
        digitalWrite (Relais2, HIGH);
        Serial.println("I'm message number two!");
     }
    }   
}

void loop() {
Serial.println("\n");
firstsensor();
secondsensor();
currentMillis = millis();
delay(100);
}

can i put also a servo in this code ?

there is no law against it that I'm aware of :slight_smile:

code looks good with capturing the value of millis() when the event happens now. Press ctrl-t to indent the code in the IDE, it will even looks better

Hi, how can i get this working ?

i have a servo,
this servo have to move when movement detected from sensor1

int trigSensor1 = 13;
int echoSensor1 = 12;

and the movement have to be

for (pos = 0; pos <= 90; pos += 1)
myservo.write(pos);
if (currentMillis - servotime >= INTERVAL_SERVO1) {
servotime = currentMillis;
for (pos = 90; pos >= 0; pos -= 1)
myservo.write(pos);

this is how my code looks like

#define INTERVAL_TIME1 10000
#define INTERVAL_TIME2 5000
#define INTERVAL_SERVO1 1500
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

unsigned long time_1 = 0;
unsigned long time_2 = 0;
unsigned long servotime = 0;
unsigned long currentMillis = 0;

int Relais1 = 11;
int Relais2 = 10;

int trigSensor1 = 13;
int echoSensor1 = 12;

int trigSensor2 = 9;
int echoSensor2 = 8;

void setup() {
  Serial.begin (9600);
  pinMode(trigSensor1, OUTPUT);
  pinMode(echoSensor1, INPUT);

  pinMode(trigSensor2, OUTPUT);
  pinMode(echoSensor2, INPUT);

  pinMode(Relais1, OUTPUT);
  pinMode(Relais2, OUTPUT);

  myservo.attach(7);  // attaches the servo on pin 9 to the servo object

}

void firstsensor() { // This function is for first sensor.
  int duration1, distance1;
  digitalWrite (trigSensor1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigSensor1, LOW);
  duration1 = pulseIn (echoSensor1, HIGH);
  distance1 = (duration1 / 2) / 29.1;

  Serial.print("1st Sensor: ");
  Serial.print(distance1);
  Serial.print("cm    ");

  for (pos = 0; pos <= 90; pos += 1)
    myservo.write(pos);
  if (currentMillis - servotime >= INTERVAL_SERVO1) {
    servotime = currentMillis;
    for (pos = 90; pos >= 0; pos -= 1)
      myservo.write(pos);
  }

  if (distance1 < 70) {  // Change the number for long or short distances.


    if (currentMillis - time_1 >= INTERVAL_TIME1) {

      digitalWrite (Relais1, LOW);
      time_1 = currentMillis;
    }

  } else {
    if (currentMillis - time_1 >= INTERVAL_TIME1) {
      digitalWrite (Relais1, HIGH);
      Serial.println("I'm message number one!");

    }
  }
}


void secondsensor() { // This function is for second sensor.
  int duration2, distance2;
  digitalWrite (trigSensor2, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigSensor2, LOW);
  duration2 = pulseIn (echoSensor2, HIGH);
  distance2 = (duration2 / 2) / 29.1;

  Serial.print("2nd Sensor: ");
  Serial.print(distance2);
  Serial.print("cm    ");

  if (distance2 < 50) {  // Change the number for long or short distances.
    if (currentMillis - time_2 >= INTERVAL_TIME2) {
      digitalWrite (Relais2, LOW);
      time_2 = currentMillis;
    }
  } else {
    if (currentMillis - time_2 >= INTERVAL_TIME2) {
      digitalWrite (Relais2, HIGH);
      Serial.println("I'm message number two!");
    }
  }
}





void loop() {
  Serial.println("\n");
  firstsensor();
  secondsensor();
  currentMillis = millis();
  delay(100);
}

it is moving but not when movement is detected, it moves continuosly .

I am confused, the latest code you posted moves the servo without any care of what the variable distance1 contains.

What is the point of the for loops for servo position?

for (pos = 0; pos <= 90; pos += 1)
    myservo.write(pos);

I would think.

myservo.write(90);

Would accomplish the same result with less wasted ticks.

I want to create a halloween project, with lasers,

when someone trades my garden, then the laser goes on , smoke machine goes on, and the servo turns the lasers back and forward .

this is what i want to create, and after 10 seconds everything stops , and when there is again a movement, it will start again from begin