I can't seem to identify the problem, please help

Hey guys,

Here is what this is supposed to do:

When the ultrasonic value is lesser than 50 Centimeters,

Both the buzzers(RPiezo,LPiezo) should go off, and with a delay of 200
microseconds, they should turn off.

I ran this on a simulator (Tinkercad) and what happened was that the buzzer went off, but it never turned off.

I even tried setting the microsecond value to like 2000000000,
but that still didn't work.
There were no Syntax errors.

So, I can't seem to identify the problem, please help.

Code:

#define RechoPin 9 
#define RtrigPin 8

long duration; 
int distance; 
int RPiezo (6);
int LPiezo (5);

void setup() {
  pinMode(RtrigPin, OUTPUT); 
  pinMode(RechoPin, INPUT); 
  Serial.begin(9600); 
  Serial.println("Ultrasonic Sensor HC-SR04 Test"); 
  Serial.println("with Arduino UNO R3");
}
void loop() {
 
  digitalWrite(RtrigPin, LOW);
  delayMicroseconds(2);
  
  digitalWrite(RtrigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(RtrigPin, LOW);
   
  duration = pulseIn(RechoPin, HIGH);
  
  distance = duration * 0.034 / 2; 
 
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  
  if
    (distance < 50) {
    digitalWrite(RPiezo, HIGH);
    digitalWrite(LPiezo, HIGH);
    delayMicroseconds(200);
    digitalWrite(RPiezo, LOW);
    digitalWrite(LPiezo, LOW);
  }
}

There are a million microseconds in a second. Perhaps you wanted to use milliseconds (1000 in a second)?


Until simulation reset or making the value greater than 50cm?


By the way, the buzzer will still stay on with this code. After the buzzers become LOW, they will become HIGH right afterwards.


@anon44338819

Don't the piezo pins need to be set to pinMode OUTPUT?

Try half a second ON and at least half a second OFF:

  if
    (distance < 50) {
    digitalWrite(RPiezo, HIGH);
    digitalWrite(LPiezo, HIGH);
    delay(500);
    digitalWrite(RPiezo, LOW);
    digitalWrite(LPiezo, LOW);
    delay(500);
  }

Try this:

#define RechoPin 9
#define RtrigPin 8

long duration;
int distance;
byte RPiezo (6);
byte LPiezo (5);

void setup() {
  pinMode(RtrigPin, OUTPUT);
  pinMode(RechoPin, INPUT);
  pinMode(RPiezo, OUTPUT);  // Added after comment from post #6
  pinMode(LPiezo, OUTPUT);  // Added after comment from post #6

  Serial.begin(9600);
  Serial.println("Ultrasonic Sensor HC-SR04 Test");
  Serial.println("with Arduino UNO R3");
}
void loop() {
  static bool distanceUndercut = false;

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

  duration = pulseIn(RechoPin, HIGH);

  distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  if (distance < 50 && distanceUndercut == false) {
    distanceUndercut = true;
    digitalWrite(RPiezo, HIGH);
    digitalWrite(LPiezo, HIGH);
    delay(500);
    digitalWrite(RPiezo, LOW);
    digitalWrite(LPiezo, LOW);
  } else if (distance >= 50 && distanceUndercut == true) {
    distanceUndercut = false;
  }
}

You are still writing to inputs. The digitalWrite(pin , HIGH); is just setting the internal pullup resistor on and digitalWrite(pin, LOW); turns the internal pullup resistor off. Is that your intention?

No it wasn't. I simply overlooked the fact that the pin mode for LPiezo and RPiezo was not set.

Here a small simulation with LEDs instead of buzzers. To change the distance while the simulation is running, click on the HC-SR04 drawing in the diagram and use the slider to set the distance value.

Does this code do what you want? It uses a variation on the state change detection method so that the buzzer only fires when the distance changes from more than 50cm to less than 50cm. Tested on real hardware.

const byte RechoPin = 9;
const byte RtrigPin = 8;
const byte RPiezo = 6;
const byte LPiezo = 5;

long duration;
int distance;

const int threshold = 50;
const int hysteresis = 2;
bool sensorState = false;

void setup()
{
   pinMode(RtrigPin, OUTPUT);
   pinMode(RechoPin, INPUT);
   pinMode(RPiezo, OUTPUT);
   pinMode(LPiezo, OUTPUT);
   Serial.begin(9600);
   Serial.println("Ultrasonic Sensor HC-SR04 Test");
   Serial.println("with Arduino UNO R3");
}
void loop()
{

   static bool lastSensorState = true;
   static unsigned long timer = 0;
   unsigned long interval = 50;
   if (millis() - timer >= interval)
   {
      timer = millis();

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

      duration = pulseIn(RechoPin, HIGH);

      distance = duration * 0.034 / 2;

      Serial.print("Distance: ");
      Serial.print(distance);
      Serial.println(" cm");

      if (distance < threshold - hysteresis)
      {
         sensorState = true;
      }
      else if (distance > threshold + hysteresis)
      {
         sensorState = false;
      }

      if (sensorState != lastSensorState)
      {
         if (sensorState == true)
         {
            digitalWrite(RPiezo, HIGH);
            digitalWrite(LPiezo, HIGH);
            delay(200);
            digitalWrite(RPiezo, LOW);
            digitalWrite(LPiezo, LOW);
         }
         lastSensorState = sensorState;
      }
   }
}

HELP.

I tried this code:

#define RechoPin 9
#define RtrigPin 8

long duration;
int distance;
byte RPiezo (6);
byte LPiezo (5);

void setup() {
  pinMode(RtrigPin, OUTPUT);
  pinMode(RechoPin, INPUT);
  pinMode(RPiezo, OUTPUT);  // Added after comment from post #6
  pinMode(LPiezo, OUTPUT);  // Added after comment from post #6

  Serial.begin(9600);
  Serial.println("Ultrasonic Sensor HC-SR04 Test");
  Serial.println("with Arduino UNO R3");
}
void loop() {
  static bool distanceUndercut = false;

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

  duration = pulseIn(RechoPin, HIGH);

  distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  if (distance < 50 && distanceUndercut == false) {
    distanceUndercut = true;
    digitalWrite(RPiezo, HIGH);
    digitalWrite(LPiezo, HIGH);
    delay(500);
    digitalWrite(RPiezo, LOW);
    digitalWrite(LPiezo, LOW);
  } else if (distance >= 50 && distanceUndercut == true) {
    distanceUndercut = false;
  }
}

Now the Piezo just won't stop.

I tried this on the simulator and my ears are paining.

Help.

I tried it, but it didn't work unfortunately. Thank you though.

I tried it, it also didn't work unfortunately.

No, it wasn't.

It was my mistake, but thanks to you and the other beautiful members of this community, I fixed it.

@johnwasser @groundFungus Someone please help

@Kai-R @anon44338819

That conveys no information that I can use to help you. I tested that code on real hardware and I can assure you that it works fine for the intended purpose. It does as stated: "that the buzzer only fires when the distance changes from more than 50cm to less than 50cm."

So, what does my code do for you? In what way does it not work? What, exactly, should the code do?

Did you try the code I posted? If it "didn't work", in what way did it not work?

Here is the whole sketch:

const byte LPiezo = 5;
const byte RPiezo = 6;
const byte RtrigPin = 8;
const byte RechoPin = 9;

void setup()
{
  Serial.begin(9600);
  delay(200);
  Serial.println("Ultrasonic Sensor HC-SR04 Test");
  Serial.println("with Arduino UNO R3");
  
  pinMode(RtrigPin, OUTPUT);
  pinMode(RechoPin, INPUT);
  pinMode(RPiezo, OUTPUT);
  pinMode(LPiezo, OUTPUT);
}

void loop()
{
  digitalWrite(RtrigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(RtrigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(RtrigPin, LOW);

  unsigned long duration = pulseIn(RechoPin, HIGH, 30000);

  // Check for timeout (out of range)
  if (duration != 0)
  {
    int distance = duration * 0.034 / 2;

    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");

    if (distance < 50)
    {
      digitalWrite(RPiezo, HIGH);
      digitalWrite(LPiezo, HIGH);
      delay(500);
      digitalWrite(RPiezo, LOW);
      digitalWrite(LPiezo, LOW);
      delay(500);
    }
  }
}

@johnwasser @groundFungus

I think it might be a problem with my simulator and I cant really test it IRL since my Ultrasonic sensors are to arrive tomorrow.

Both of the code actually works, well, kind of...

The buzzers just don't care, when the simulation starts, the just keep making sounds. No breaks, but the pitch does change.

The worst part of this is that the serial monitor shows 215 CM, but it still doesn't work

Well, i postet a simulation in #6. Did you ever try it? The code worked fine in the Wokwi simulation.

I tried it, and it didn't work in my simulator. But, when I tried it with Wokwi, it did work perfectly.

It was a problem with my simulator, I guess.

Thank you all!

This is not the first time that I have seen TinkerCad doing something that confuses the user. Nothing beats the real thing. No simulator can be perfect, at least one that we can afford to use.

If the problem is solved, please mark the thread as solved so that other members do not waste their time opening the thread wanting to help only to find that the problem has been solved.