Ultrasonic sensor with LED, how can I do this?

Hello friends,

I want to build an occupancy indicator with an ultrasonic sensor. I'll tell you what I want to achieve, and if anyone knows how to do this, please let me know because I don't have any coding experience.

Components:
Arduino Uno
Ultrasonic sensor
RGB LED module

The ultrasonic sensor will be placed on the door frame, and I want it to work like this:

When it detects close distance (let's say less than 10cm), to deactivate the sensor for 1 minute, and turn the RGB LED Red.

When it detects distance less than 10 for the second time, the sensor should be deactivated for 1 minute, and the RGB LED set to Green again.

Code:
(with this, the LED is green, and turns red whenever I put my hand in front of the sensor:

#define echoPin 2 // attach pin D2 Arduino to pin Echo of HC-SR04
#define trigPin 3 //attach pin D3 Arduino to pin Trig of HC-SR04

// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
int red_LED = 10;
int green_LED = 9;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(red_LED, OUTPUT);
  pinMode(green_LED, OUTPUT);
  Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed
}
void loop() {
  //==============================================================
  // ULTRASONIC SENSOR
  //==============================================================
  // Clears the trigPin condition
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin HIGH (ACTIVE) for 10 microseconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  // Displays the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  //==============================================================
  // OCCUPANCY CODE
  //==============================================================
  if (distance < 10) {
    analogWrite(red_LED, 255);
    analogWrite(green_LED, 0);
  }
  else {
    analogWrite(green_LED, 255);
    analogWrite(red_LED, 0);
  }
  delay (1000);
}

What is the sensor detecting?

Distance, it's an ultrasonic sensor, and I want to use it to detect whenever a person is in front of it.

Then you need to gain some experience if you ever expect to get this project off the ground.


There are many examples that are included with the IDE.

Before proceeding, master these examples, then and only then should you venture out on your own.


All libraries come with examples too.

Hello Larry, thank you for your help, I understand basic code, but I don't know how to write complex expressions myself, It's not my main job, I do this as a hobby.

Seems fairly straightforward. In the setup section, turn the red LED on and instantiate an int toggle=0; and then in the loop, if you get a <10cm result, toggle the color of the LED. Something like this:

if (distance <  10)  {
 analogwrite(red_LED, toggle*255);  // should turn RED off in first pass thru loop 
 if (toggle == 1) toggle=0; else toggle=1;
 analogwrite(green_LED, toggle*255);  // should turn GREEN on in first pass
 delay(60000); // wait one minute before checking sensor again
}
1 Like

Then it's a matter of spending more time and effort to become more experienced.

aarg, I like your logic on line 64, that was really helpful.

Thank you so much haroldsutton, you are a true master and made my day better! :slight_smile:

1 Like

This is what I wrote by myself, but it's not working very well :slight_smile:

  if (isDoorOpen == 0) {
    analogWrite(red_LED, 0);
    analogWrite(green_LED, 255);
  }

  if (distance < 10) {
    isDoorOpen = 1;
  }

  if (isDoorOpen == 1) {
    analogWrite(red_LED, 255);
    analogWrite(green_LED, 0);
    delay (5000);
    if (distance > 10) {
      (isDoorClosed = 1);
    }
  }

  if (isDoorClosed == 1 && distance < 10) {
    isDoorOpen = 0;
  }

"not very well" doesn't really explain it well...

1 Like

I think a large part of the problem with the code in #10 is that you have two variables for the door state. If a door is open, it's not closed. If it's closed, it's not open. So to maintain two of them is bound to create confusion and errors.

Also if you want to do this with a flag 'isDoorOpen' you should make it a bool variable and assign it values of 'true' and 'false' instead of '0' and '1'. The readability itself will help avoid errors.

So you would have something like:

if (distance < 10) {
  isDoorOpen = true;
}
else {
  isDoorOpen = false;
}

if (isDoorOpen == true) {
  analogWrite(red_LED, 255);
  analogWrite(green_LED, 0);
  delay (5000);
}
else {
  analogWrite(red_LED, 0);
  analogWrite(green_LED, 255);
}

The code works really great, but how can I improve it with this?:

When I press a button, next time the door is open (distance <10 ) a buzzer should beep. But only next time, after pressing the button.

This way you can be announced by the buzer when the door is open and the person is leaving.

I was thinking something like:

bool PressedToEnter = false;

I was thinking:

If digitalread button HIGH {

PressedToEnter == true

}

else {

PressedToEnter == false

}

If PressedToEnter == true && distance < 10 {

Buzzer

Delay

Buzzer

Delay

Buzzer

PressedToEnter == false
}

Will it work? Or there is a better way to do it.

Not sure you'd get the behavior you want from that code.

How about this?

// in setup create 
bool pressed = false;

// in loop
void loop {
  distance = readultrasonic();
  pressed = readbutton();
  if distance < 10 {
    if (pressed) {
      buzz(3);
      pressed=false;
    }
    updateLEDS();
  }
}

int readultrasonic() {
  // your read from the ultrasonic sensor goes here
  // always returns an integer, whether the sensor yields one or not
  // if the sensor yields a non-integer result because nearest object is out of range
  // of detection, then return 11 (so the LEDs and buzzer won't trigger).
}

bool readbutton() {
  // your button checking code goes here
  // always returns false unless button is pressed
}

void updateLEDS() {
  // your LED toggling code goes here
}

void buzz(int numbuzzes) {
  // loop and buzz as many times as indicated by numbuzzes value

  // if you want to up your game, test for a button press after every buzz
}
1 Like

OMG, your knowledge is so incredible, you’re thinking for complex situations so fast. Thank you so much!

1 Like

Hello haroldsutton,
can you please help me integrate your code into mine?

I tried to implement it all day and I got all kind of errors since I'm not as experienced as you are.

This is my code for now:

#define echoPin 2
#define trigPin 3

long duration;
int distance;
int red_LED = 10;
int green_LED = 9;
int toggle = 0;
const int button = 8;
int buzzer = 4;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(red_LED, OUTPUT);
  pinMode(green_LED, OUTPUT);
  pinMode(button, INPUT);
  pinMode(buzzer, OUTPUT);
  bool buttonPressed = false;
  analogWrite(red_LED, 255);
  Serial.begin(9600);
}
void loop() {
  //==============================================================
  // ULTRASONIC SENSOR
  //==============================================================
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2;
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.print(" cm, ");

  //==============================================================
  // OCCUPANCY CODE
  //==============================================================
  if (distance <  10)  {
    analogWrite(red_LED, toggle * 255);
    if (toggle == 1) toggle = 0; else toggle = 1;
    analogWrite(green_LED, toggle * 255);
    delay (7000);
  }
  //==============================================================
  // BUTTON CODE
  //==============================================================
  bool buttonPressed = digitalRead(button);
  Serial.print ("Button Pressed = ");
  Serial.println(buttonPressed);

}

The sensor toggles the LED when I pass my hand over it, so it works fine, the push button is connected and it shows 1/0 when pressed, and the buzzer is connected and working, so everything works individually, but I don't know how to put them together, looks impossible to me since I got an error at almost every move I make.

If you really can't assemble that, you're essentially asking someone to code for you. You should either post specific attempts, along with the specific compiler error output, or else pay someone to do it.

By the way, so far I have not seen any variable to keep track of what event is "next time". In your description you talk about an alternating sequence but the program can't know what the previous state was without storing it somehow.

If your sketch is working, what more did you hope to achieve? Seems good for a beginning coder!

If I might suggest, read up on how to segment your code into Functions. It will help readability and debugging. Check out a basic tutorial here.

In the sample code I gave you (above), you will see how I suggested you might move your code into Functions. With them, most of the details are abstracted from the main Loop code, making that much easier to understand.

Best of luck!