Ultrasonic Tripwire System

The following is my code:

const int trigPin = 2;
const int echoPin = 4;
int num = 0;
int occu = 0;


void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  
}

void loop()
{
 
  // establish variables for duration of the ping, 
  // and the distance result in inches and centimeters:
  long duration, inches, cm;

  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(trigPin, OUTPUT);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
 

  // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(echoPin, INPUT);
 
 duration = pulseIn(echoPin, HIGH); 
 

  // convert the time into a distance
  
  cm = microsecondsToCentimeters(duration);
  delay(2000);
  
  
  if (cm < 45) 
{
 num++;
 
} 
occu = num % 2;
Serial.println(occu);
};


long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

So what I want this to do is to print 1 to the Serial when an object passes by the ultrasonic sensors and is less than 45 cm away. However, this is to be installed outside a room on the door, so I need the modulo operator to compensate for the inability of the ultrasonic sensor to detect direction.

The output of this program, irrespective of whether there is an object in front of the sensor, is simply 1 0 1 0 1 0 all the way to infinity.

Is there any way I can fix this?

Help is much appreciated.

The output of this program, irrespective of whether there is an object in front of the sensor, is simply 1 0 1 0 1 0 all the way to infinity.

If you figured out how to get that output, surely you can figure out how to print the distance, too. With that, you just might find that cm is always less than 45.

If that's the case, you need to figure out why.

@PaulS - That's why I am confused. Either there is a mistake in the code (as in something I didn't want) or there is a problem with the sensor, though that is unlikely.

Could you please tell me if there is something that I missed out in the code?

Could you please tell me if there is something that I missed out in the code?

Debug prints?

Debug prints?

That should be

Debug prints!

@AWOL - Well, yeah. It was verified and debugged.

I'm glad you got the bugs out.

coolcheetah:
@AWOL - Well, yeah. It was verified and debugged.

I suspect there is a language problem here. "debugged" means that all the problems have been solved and the program works as required.

When @AWOL said "Debug prints?" he meant that you should add some Serial.println() statements to your code so that you can see what it is doing.

For example after the line

duration = pulseIn(echoPin, HIGH);

add the lines

Serial.print("Duration = ");
Serial.println(duration);

and tell us what values you get.

...R

Sorry for the late reply. The values I get for duration are correct. But could you please tell me how I can get the 1s and 0s as I want them to be printed?

Follow up question - Is the duration relevant in this case? Because I am getting correct values, but the zeros and ones still seem to be printing incorrectly.

Post your code.
Post your results

const int trigPin = 2;
const int echoPin = 4;
int num = 0;
int occu = 0;

void setup() {
  Serial.begin(9600);  // initialize serial communication:
}

void loop()
{
  // establish variables for duration of the ping, 
  // and the distance result in inches and centimeters:
  long duration, inches, cm; // PUT THIS LINE ABOVE SETUP()

  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(trigPin, OUTPUT);  //PUT THIS LINE IN SETUP
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(echoPin, INPUT);
 duration = pulseIn(echoPin, HIGH); 
  // convert the time into a distance
  cm = microsecondsToCentimeters(duration);
  delay(2000); //WHY ARE YOU DELAYING HERE, BEFORE THE CALCULATION?
  if (cm < 45) 
{
 num++;
} 
occu = num % 2; //DO YOU REALLY WANT TO DO THIS IF cm >= 45?
Serial.println(occu);
}; //WHY THE SEMICOLON?

long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

See all that stuff? That indicates you didn't select/copy/paste correctly. (Windows IDE, use CTRL-A, CTRL-C, then CTRL-V in to the forum with code tags, the </> button).
Modify the post, delete that stuff, and try again, so it looks like this:

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the Uno and
  Leonardo, it is attached to digital pin 13. If you're unsure what
  pin the on-board LED is connected to on your Arduino model, check
  the documentation at http://arduino.cc

  This example code is in the public domain.

  modified 8 May 2014
  by Scott Fitzgerald
 */


// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

Much better :slight_smile:

When occu = 1, then someone is inside the room, otherwise it is empty.

The variable occu stores the value of the number of favourable outcomes (the beam was blocked by a leg). If I don't incorporate a delay, then it will take a single passing obstruction to be two or three obstructions, therefore making occu irrelevant.

cm < 45 because that is/can be the distance of the passing obstruction (the leg) from the sensor. This sensor is, in essence, a tripwire system.

@Henry_Best - could you please modify your answer?

Any help from anyone will be appreciated.

See reply #10

Okay, I modified it like how Henry_Best said, and it works. I also made a minor correction by placing occu inside the if statement.

Thank you all for your help.