Problem running 2 ultrasound sensors

So I am trying to connect 2 utrasound sensors to a single arduino nano every.

The Goal is to have them facing opposite directions and then alarm and light up when one of them is triggered but then alarm and light when they are both going (on slightly different buzzers and different colour LED's)

I have managed to get one side working fine so I decided to copy paste the code and tweak itr but I cannot seems to get it to act properly.

Below is my code if someone could have a look and see if I have made any mistakes that would be much appreciated

const int pingPin1 = 10; // Trigger Pin of Ultrasonic Sensor 1
const int echoPin1 = 11; // Echo Pin of Ultrasonic Sensor 1
const int buzzerPin1 = 12;  //
const int LEDPin1 = 7;

const int pingPin2 = 8; // Trigger Pin of Ultrasonic Sensor 2
const int echoPin2 = 9 ; // Echo Pin of Ultrasonic Sensor 2
const int buzzerPin2 = 6;  //
const int LEDPin2 = 4;
int PowerPin = 5;

void setup() {
   Serial.begin(9600); // Starting Serial Terminal
   pinMode(buzzerPin1, OUTPUT);
   pinMode(LEDPin1, OUTPUT);   
   pinMode(buzzerPin2, OUTPUT);
   pinMode(LEDPin2, OUTPUT);    
}

void loop() {
   long duration1;
   pinMode(pingPin1, OUTPUT);
   digitalWrite(pingPin1, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin1, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin1, LOW);
   pinMode(echoPin1, INPUT);
   duration1 = pulseIn(echoPin1, HIGH);

   long duration2;
   pinMode(PowerPin, OUTPUT);
   digitalWrite(PowerPin, HIGH);
   pinMode(pingPin2, OUTPUT);
   digitalWrite(pingPin2, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin2, HIGH);
   delayMicroseconds(10);
   digitalWrite(pingPin2, LOW);
   pinMode(echoPin2, INPUT);
   duration2 = pulseIn(echoPin2, HIGH);

   while(duration1<6000){
   Serial.println(duration1);
   int i=duration1/20; 
   digitalWrite(LEDPin1, HIGH);
   digitalWrite(buzzerPin1, HIGH);
   delay(i/2);
   digitalWrite(LEDPin1, LOW);
   digitalWrite(buzzerPin1, LOW);
   delay(i);
   break;
   }

   while(duration2<6000){
   Serial.println(duration2);
   int i2=duration2/20; 
   digitalWrite(LEDPin2, HIGH);
   digitalWrite(buzzerPin2, HIGH);
   delay(i2/2);
   digitalWrite(LEDPin2, LOW);
   digitalWrite(buzzerPin2, LOW);
   delay(i2);
   break;
   }   

}

The code has a few issues that need to be addressed:

  1. The program is not checking if both sensors are triggered at the same time.
  2. The code has two break statements, which will cause the while loop to exit prematurely.
  3. The code is not setting the PowerPin back to LOW after the second sensor has been triggered.

Here's a modified code that addresses these issues: const int pingPin1 = 10; // Trigger Pin of Ultrasonic Sensor 1
const int echoPin1 = 11; // Echo Pin of Ultrasonic Sensor 1
const int buzzerPin1 = 12; //
const int LEDPin1 = 7;

const int pingPin2 = 8; // Trigger Pin of Ultrasonic Sensor 2
const int echoPin2 = 9 ; // Echo Pin of Ultrasonic Sensor 2
const int buzzerPin2 = 6; //
const int LEDPin2 = 4;
int PowerPin = 5;

void setup() {
Serial.begin(9600); // Starting Serial Terminal
pinMode(buzzerPin1, OUTPUT);
pinMode(LEDPin1, OUTPUT);
pinMode(buzzerPin2, OUTPUT);
pinMode(LEDPin2, OUTPUT);
pinMode(PowerPin, OUTPUT);
}

void loop() {
long duration1;
long duration2;

// Trigger sensor 1
digitalWrite(pingPin1, LOW);
delayMicroseconds(2);
digitalWrite(pingPin1, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin1, LOW);
pinMode(echoPin1, INPUT);
duration1 = pulseIn(echoPin1, HIGH);

// Trigger sensor 2
digitalWrite(PowerPin, HIGH);
digitalWrite(pingPin2, LOW);
delayMicroseconds(2);
digitalWrite(pingPin2, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin2, LOW);
pinMode(echoPin2, INPUT);
duration2 = pulseIn(echoPin2, HIGH);
digitalWrite(PowerPin, LOW);

// Check if only one sensor is triggered
if (duration1 < 6000 && duration2 >= 6000) {
Serial.println("Sensor 1 Triggered");
int i = duration1 / 20;
digitalWrite(LEDPin1, HIGH);
digitalWrite(buzzerPin1, HIGH);
delay(i / 2);
digitalWrite(LEDPin1, LOW);
digitalWrite(buzzerPin1, LOW);
delay(i);
} else if (duration2 < 6000 && duration1 >= 6000) {
Serial.println("Sensor 2 Triggered");
int i2 = duration2 / 20;
digitalWrite(LEDPin2, HIGH);
digitalWrite(buzzerPin2, HIGH);
delay(i2 / 2);
digitalWrite(LEDPin2, LOW);
digitalWrite(buzzerPin2, LOW);
delay(i2);
} else if (duration1 < 6000 && duration2 < 6000) {
Serial.println("Both Sensors Triggered");
// Add code to handle both sensors being triggered
}
}
Please Note: The code assumes that the sensors are properly wired and that the distance calculation is accurate.

@walshy690
I removed the blocking delay and while statements where the delays could be excessive.
I also made it so both sensors could trip any time they needed to. as objects may be closer on one side, allowing for rapid pinging. I attempted to use as much of your example code as possible.
note the echo pins moved to pins 2 and 3 to allow for attachinterrupt() functionality
This code compiles and parts of it were tested in my other experiments :slight_smile:
This may be a direction you would like to adjust your program towards:

const int pingPin1 = 10; // Trigger Pin of Ultrasonic Sensor 1
const int echoPin1 = 2; // Echo Pin of Ultrasonic Sensor 1 *********** must be pin 2
const int buzzerPin1 = 12;  //
const int LEDPin1 = 7;
const int pingPin2 = 8; // Trigger Pin of Ultrasonic Sensor 2
const int echoPin2 = 3 ; // Echo Pin of Ultrasonic Sensor 2 *********** must be pin 3
const int buzzerPin2 = 6;  //
const int LEDPin2 = 4;
int PowerPin = 5;
uint16_t duration1;
uint16_t duration2;
volatile uint16_t dTime[2];
volatile uint16_t ChangeCount[2];

void PingDelta1() {
  static uint32_t EdgeTime;
  uint32_t cTime = micros();
  if (digitalRead(2)) { // SensorPin must be pins 2 & 3 as they are the only ones attachinterrupts link to
    EdgeTime= cTime; //Pulse went HIGH store the start time
    return ;
  } else {  // Pulse Went low calculate the duratoin
    ChangeCount[0]++;
    dTime[0] = cTime - EdgeTime; // Calculate the change in time up to 65535 micro seconds
  }
}
void PingDelta2() {
  static uint32_t EdgeTime;
  uint32_t cTime = micros();
  if (digitalRead(3)) { // SensorPin must be pins 2 & 3 as they are the only ones attachinterrupts link to
    EdgeTime = cTime; //Pulse went HIGH store the start time
    return ;
  } else {  // Pulse Went low calculate the duratoin
    ChangeCount[1]++;
    dTime[1] = cTime - EdgeTime; // Calculate the change in time up to 65535 micro seconds
  }
}

void setup() {
  Serial.begin(9600); // Starting Serial Terminal
  pinMode(buzzerPin1, OUTPUT);
  pinMode(LEDPin1, OUTPUT);
  pinMode(buzzerPin2, OUTPUT);
  pinMode(LEDPin2, OUTPUT);
  pinMode(pingPin1, OUTPUT);
  pinMode(pingPin2, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(echoPin2, INPUT);
  pinMode(PowerPin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2),PingDelta1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3),PingDelta2, CHANGE);
}

void loop() {
  static int i1, i2;
  static unsigned long Pulse1Timer;
  static unsigned long Pulse2Timer;
  static unsigned long duration1Timer;
  static unsigned long duration2Timer;
  if ((millis() - Pulse1Timer) >= (i1)) {
    digitalWrite(pingPin1, HIGH);
    delayMicroseconds(10);
    digitalWrite(pingPin1, LOW);

  }
  if (ChangeCount[0] > 0) {
    cli ();         // clear interrupts flag
    ChangeCount[0] = 0;
    duration1 = dTime[0];
    sei ();
    Serial.print("duration1: ");
    Serial.println(duration1);
  }
  if (duration1 < 6000) {
    int i = duration1 / 20;
    digitalWrite(LEDPin1, HIGH);
    digitalWrite(buzzerPin1, HIGH);
    duration1Timer = millis();
  }
  if ((millis() - duration1Timer) >= (duration1 / 40)) {
    digitalWrite(LEDPin1, LOW);
    digitalWrite(buzzerPin1, LOW);
    Pulse1Timer = millis();
  }

  if ((millis() - Pulse2Timer) >= (i2)) {

    digitalWrite(pingPin1, HIGH);
    delayMicroseconds(10);
    digitalWrite(pingPin1, LOW);

  }
  if (ChangeCount[1] > 0) {
    cli ();         // clear interrupts flag
    ChangeCount[1] = 0;
    duration2 = dTime[1];
    sei ();
    Serial.print("duration2: ");
    Serial.println(duration2);
  }
  if (duration2 < 6000) {
    int i2 = duration2 / 20;
    digitalWrite(LEDPin2, HIGH);
    digitalWrite(buzzerPin2, HIGH);
    duration2Timer = millis();

  }
  if ((millis() - duration2Timer) >= (duration2 / 40)) {
    digitalWrite(LEDPin2, LOW);
    digitalWrite(buzzerPin2, LOW);
    Pulse2Timer = millis();
  }
}

While I have not tested this code as a whole it should work
Let us know if it works for you.
Z

It would have been helpful if you'd described how it is acting and what it is doing that is different than what you expect it to do.

One possible problem with the OP's code (and both of the proposed solutions) is that they do not appear to allow for the possibility that echos from one sensor may confound the other sensor. That problem can be solved by triggering one sensor, waiting for the echo, pausing about 40 or 50 ms, and then triggering the other. (And for that, using interrupts is not necessary.)

An optimization that may or may not be related to the "problem": the default timeout for pulseIn() is one second so if, for some reason, a sensor doesn't get a return, it will hold up all subsequent code ("block") until one second passes. That slows performance considerably. You can shorten the timeout to whatever makes sense for your project by using pulseIn()'s third parameter (it should be less than or equal to the out-and-back duration associated with HC-SR04's max range).

And, as others have pointed out, the OP should have used the "if" statement in lieu of the "while()...break" construction.

The OP could also greatly benefit from learning about how to use millis() for timing things like blinking LEDs and buzzing buzzers.

Some ultrasonic sensors require a trigger pulse of 10 us instead of 2 us. Try that or look at the datasheet of your sensor.

I've not had a chance to try these suggestions just yet but as soon as I do I will respond.

I can also record what each one does to show the behaviour.

Thanks for the help

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.