Posted in rasberrypi, hc-sr04

How to detect your door activity using Raspberry Pi and HC-SR04

I plan to hang my Raspberry Pi on top of the door and detect if it was opened or closed. No one will ever pass that door without you knowing (not even the night monsters). To achieve this I will be using a Raspberry Pi Zero along with HC-SR04 distance sensor.

Remember that you are free to leave any comment below for requests/improvements/bugs or anything you would like to discuss.

Hardware used in this project

In this project, I plan to use HC-SR04 ultrasonic sensor to measure distance and it will be connected to the Raspberry Pi Zero. The HC-SR04 can measure a minimum distance of 2cm and a maximum distance of 400cm.

Because the Echo pin is at 5V and the GPIO pins from Rasp are at 3.3V. In order to convert the input voltage to a lower one, we need a Voltage Divider. The schema for it is defined below:

hc-sr04 coonected to raspberry pi with a voltage divider

In order to obtain the desired 3.3V, I have chosen the resistors to be as following R1=1k and an R2=2k (I didn't have a resistor with 2.4k value so I used 2x1k resistors in series). If you don't have 1k resistors don't despair, remember that you need resistors in order to build the 2/3 fraction, another possible combination is R1=2.4k and R2=4.7K. I have detailed how I came to this fraction:

voltage divider formula

If it's hard to follow how the cables are connected in the above image, use this table instead. But don't forget to add the voltage divider.

 HC-SR04Raspberry Pi Zero
2TrigGPIO18 with PWM 1 (PIN12)
3Echo 5VGPIO17 3.3V (PIN11)

The logic behind 

In order to achieve our goal of observing when the door is open or closed, we need to know the distance and a way to know the status of the door. 

How I measure the distance? Before putting the hands of the formula, let's explain a little bit what is happening behind the scene. I'm focusing here mostly on the distance() function defined in the code below. 

The first thing that needs to be done is to notify (setting Trig to True) the sensor of your intention of measuring: "Hey, how far is the nearest obstacle?". Immediately after this, the sensor tries to find the answer for you and will send 8 sonic bursts at 40kHz. After this 'research' of the upfront area, will come with an answer: "Hey, the distance is about HIGH ...wait... STOP."  (Echo pin set to True).

Maybe you wonder how the distance can be measured from this. Even though the only information that the ultrasonic sensor gives is emitting the '1 value' (actually 5V) on Echo pin for a specific duration. Using the duration of the HIGH level multiplied by the sonic speed of 343m/s and everything divided by 2 we will give us the distance in cm.

The first idea that came to my mind was to use the percentage change function to identify if the status of the door, open or close, for simplicity I went with an if statement. For open, I chose the distance greater than 10cm and for close otherwise. A better idea will be to use 

Below you can find all the code associated with this project. I tried to comment everything in order to make it more easily understandable.

#   The Humble Code
import RPi.GPIO as GPIO
import time

# use channel numbers on the Broadcom SOC
# configure your preffered GPIO pins
def distance():
    # send a pulse to the utlrasonic sensor
    GPIO.output(GPIO_TRIGGER, True)
    # The pulse must be of 0.01ms=10uS TTL pulse 
    time.sleep(0.00001) # seconds
    GPIO.output(GPIO_TRIGGER, False)
    # the sensor computes the distance
    # using the time when the emmited wave was sent
    # and the time when it 'bounced' back 
    startTime = time.time()
    stopTime = startTime
    # wait to send sonic burst at 40 kHz
    while GPIO.input(GPIO_ECHO) == 0:
        startTime = time.time()
    # sonic burst finished, waiting for echo
    while GPIO.input(GPIO_ECHO) == 1:
        stopTime = time.time()
    # time difference between start and arrival
    timeElapsed = stopTime - startTime
    # multiply with the sonic speed (34300 cm/s)
    # and divide by 2, the emmited wave and reflected wave
    distance = (timeElapsed * 34300) / 2
    return distance

if __name__ == '__main__':
        while 1:
            currentDistance = distance()
            print ("Distance = %.1f cm" % currentDistance)

            # If the distance is greater than 10cm
            if currentDistance > 10:
                print ("Door open.")
                print ("Door closed.")

        # close execution by pressing CTRL + C
    except KeyboardInterrupt:
        print("Intrerrupted by user")
        print("Program stopped")

Run the code using the following command on the terminal and press CTRL + C to cancel anytime.


Door status on terminal


This can be an interesting way to learn how to use the distance sensor, and if you are not bothered by the sensor hanging in front of the door it's perfect. But this can be solved by hiding it in a place where it can go unnoticed, not necessarily close to the door, it has a range of 400cm that can be used. 

As a next step, you can add notifications via SMS or email with the door status. This way you will know for sure what happened without being close to the monitor. Or you can publish metrics to see how much the door is used for a period of time.

Don't stop learning!