ESP8266 - Motion Sensor

Have you ever asked yourself, “How can it do that?” when you come across places with doors that open and close automatically, light bulbs that turn on and off, or escalators that activate without any human intervention? If so, this tutorial will not only answer your question, but also show you how to make it happen by using ESP8266 and motion sensor. Let's get started!

This tutorial instructs you how to use ESP8266 with motion sensor. In detail, we will learn:

Hardware Preparation

1×ESP8266 NodeMCU
1×Micro USB Cable
1×HC-SR501 Motion Sensor
1×Jumper Wires
1×(Optional) 5V Power Adapter for ESP8266
1×(Optional) ESP8266 Screw Terminal Adapter

Or you can buy the following sensor kit:

1×DIYables Sensor Kit 30 types, 69 units
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

Overview of HC-SR501 Motion Sensor

HC-SR501 Motion Sensor

The HC-SR501 PIR sensor is a module that can sense the movement of people (or animals). It is often utilized in many applications to detect the presence of humans, such as automatically turning on/off a light bulb, opening/closing a door, activating/deactivating an escalator, or detecting an intruder.

The Motion Sensor Pinout

The HC-SR501 motion sensor has three pins:

  • GND pin: This must be linked to GND (0V)
  • VCC pin: This must be linked to VCC (5V)
  • OUTPUT pin: This is an output pin. It will be LOW when no motion is detected and HIGH when motion is detected. This pin needs to be connected to an ESP8266's input pin.

The HC-SR501 has one jumper and two potentiometers that are used to adjust the sensor's settings.

HC-SR501 Motion Sensor pinout

How It Works

The HC-SR501 sensor is able to detect motion based on changes in the infrared radiation coming from a moving object. In order for the HC-SR501 sensor to identify the object, two criteria must be met:

  • The object must be in motion or vibrating
  • The object must emit infrared radiation

Consequently:

  • If an object is moving but not emitting infrared rays (e.g., a robot or vehicle toy), it will not be detected by the sensor.
  • If an object is emitting infrared rays but not moving (e.g., a person standing still), it will not be detected by the sensor.

Humans and animals are the source of infrared radiation. Thus, the sensor can detect their movements.

The state of the OUTPUT pin of the sensor:

  • When no human (or animal) is present in the detected range, it is LOW.
  • When a human (or animal) enters the detected range, the pin will switch from LOW to HIGH, indicating motion has been detected.
  • When the human (or animal) leaves the detected range, the pin will switch from HIGH to LOW, showing that the motion has stopped.

The video above shows the way the motion sensor works in theory. In reality, the motion sensor functions slightly differently depending on the settings of the sensor (which are outlined in the Advanced Uses section).

Detecting the Presence of Human

The sensor does not detect diectly the presence of humans. It only detects motion. We use ESP8266 to infer whether humans are present or not based on the motion detected by the sensor, following this rule:

  • If motion is detected, it implies humans are present
  • If motion is not detected, it implies humans are absent

This rule is not perfect and does not work in a scenario, where humans are within the range of the sensor, but not moving, the motion is not detected and the ESP8266 concludes that the human is not present. Howerver, it is still acceptable because human usually makes small moves.

For instance, in your meeting room, the motion sensor is used to switch the light on and off. When people enter the room, it will be illuminated automatically. However, if everyone remains stationary during the meeting, the sensor will not detect any movement, indicating that no one is present, and the light will be switched off. To turn the light back on, someone needs to move.

However, this issue is NOT serious and the sensor is inexpensive. Therefore, it is widely used to detect humans in many applications.

ESP8266 - HC-SR501 Motion Sensor

Attach an Arduino's digital input pin to the OUTPUT pin of the HC-SR501 sensor. Using the ESP8266 code, check the value of the OUTPUT pin to detect motion.

Wiring Diagram

The wiring diagram between ESP8266 NodeMCU and Motion Sensor

This image is created using Fritzing. Click to enlarge image

See more in ESP8266's pinout and how to supply power to the ESP8266 and other components.

Initial Setting

Time Delay AdjusterScrew it in anti-clockwise direction fully.
Detection Range AdjusterScrew it in clockwise direction fully.
Repeat Trigger SelectorPut jumper as shown on the image.
arduino motion sensor initial setting

How To Program For Motion Sensor

  • Set up a digital input on an Arduino's pin by utilizing the pinMode() function.
pinMode(MOTION_SENSOR_PIN, INPUT);
  • Read the state of the OUTPUT pin of the sensor with the digitalRead() function.
motion_state = digitalRead(MOTION_SENSOR_PIN);
  • Identify when the pin changes from LOW to HIGH, indicating the start of motion.
prev_motion_state = motion_state; // store old state motion_state = digitalRead(MOTION_SENSOR_PIN); // read new state if (prev_motion_state == LOW && motion_state == HIGH) { // pin state change: LOW -> HIGH Serial.println("Motion detected!"); }
  • Identify when the pin changes from a HIGH to a LOW state, indicating motion has stopped.
prev_motion_state = motion_state; // store old state motion_state = digitalRead(MOTION_SENSOR_PIN); // read new state if (prev_motion_state == HIGH && motion_state == LOW) { // pin state change: HIGH -> LOW Serial.println("Motion stopped!"); }

ESP8266 Code

/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-motion-sensor */ #define MOTION_SENSOR_PIN D7 // The ESP8266 pin D7 connected to the OUTPUT pin of motion sensor int motion_state = LOW; // current state of pin int prev_motion_state = LOW; // previous state of pin void setup() { Serial.begin(9600); // Initialize the Serial to communicate with the Serial Monitor. pinMode(MOTION_SENSOR_PIN, INPUT); // set arduino pin to input mode to read value from OUTPUT pin of sensor } void loop() { prev_motion_state = motion_state; // store old state motion_state = digitalRead(MOTION_SENSOR_PIN); // read new state if (prev_motion_state == LOW && motion_state == HIGH) { // pin state change: LOW -> HIGH Serial.println("Motion detected!"); // TODO: turn on alarm, light or activate a device ... here } else if (prev_motion_state == HIGH && motion_state == LOW) { // pin state change: HIGH -> LOW Serial.println("Motion stopped!"); // TODO: turn off alarm, light or deactivate a device ... here } }

Detailed Instructions

To get started with ESP8266 on Arduino IDE, follow these steps:

  • Check out the how to setup environment for ESP8266 on Arduino IDE tutorial if this is your first time using ESP8266.
  • Wire the components as shown in the diagram.
  • Connect the ESP8266 board to your computer using a USB cable.
  • Open Arduino IDE on your computer.
  • Choose the correct ESP8266 board, such as (e.g. NodeMCU 1.0 (ESP-12E Module)), and its respective COM port.
  • Copy the code and open it with the Arduino IDE.
  • Click the Upload button in the Arduino IDE to send the code to the ESP8266.
  • Open the Serial Monitor.
  • Move your hand in front of the sensor's range.
  • Check out the output in the Serial Monitor.
COM6
Send
Motion detected! Motion stopped!
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Video Tutorial

Advanced Uses

This section includes advanced information that may be overwhelming. If you are unsure about the content, feel free to skip it and move on to the next sections.

As stated previously, we can alter the sensor's configuration by using one jumper and two potentiometers.

Detection Range Adjuster

This potentiometer is used to change how far something can be detected (around 3 to 7 meters):

  • If you turn it all the way to the right, it can only detect things within 3 meters.
  • If you turn it all the way to the left, it can detect things up to 7 meters away.
Motion Sensor Detection Range

Time Delay Adjuster

This potentiometer is utilized to modify the time delay:

  • When turned all the way clockwise, the time delay is roughly 5 minutes.
  • When turned all the way counterclockwise, the time delay is approximately 3 seconds.

The following section elucidates the concept of time delay in conjunction with Repeat Trigger.

motion sensor adjust time delay

Repeat Trigger Selector

A jumper exists that is utilized to pick trigger modes: either single trigger or repeatable trigger.

motion sensor trigger selection

Let us refer to the time delay setting (which is set via Time Delay Adjuster) as time_delay. If you keep moving in the range of the sensor for a long period of time (called motion_time) (several times longer than time_delay):

  • Single trigger mode: The state of the OUTPUT pin will be toggled between LOW and HIGH several times. The HIGH duration will be equal to time_delay, while the LOW duration will be fixed to 3 seconds.
motion sensor single trigger mode
  • Repeatable trigger mode: The state of the OUTPUT pin will remain HIGH for the duration of (motion_time plus time_delay).
motion sensor repeatable trigger mode

Testing

  • Single Trigger Mode:
    • Place the jumper to select the single trigger mode
    • Move your hand in front of the sensor for approximately 10 seconds
    • Take your hand out of the range of the sensor
    • Wait for 3 seconds and you will observe the output in the serial monitor as follows:
    COM6
    Send
    Motion detected! Motion stopped! Motion detected! Motion stopped! Motion detected! Motion stopped!
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  

    Repeatable trigger mode:

    • Place the jumper to select Repeatable trigger mode
    • Wave your hand in front of the sensor for approximately 10 seconds
    • Move your hand away from the sensor's range
    • Wait for 3 seconds, you will observe the output in the serial monitor as follows:
    COM6
    Send
    Motion detected! Motion stopped!
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  

    We can observe that in single trigger mode, the sensor triggers two or three times. Whereas, in repeatable trigger mode, it only triggers once.

    ※ NOTE THAT:

    During the LOW (3 seconds) time, which is fixed and unadjustable, the sensor is unable to detect any motion. This does not cause any issues in practice.

    It is advised to use the repeatable trigger mode.

    In many real-world applications, we switch on or activate machines/devices when a person is present, and we do not switch them off or deactivate them immediately when the person is no longer present. Instead, we wait for a timeout before turning them off or deactivating them.

    How To Use Time Delay

    If no human is detected, the automation system will wait for a period of time before initiating action.

    The time delay can be adjusted on the motion sensor and ESP8266 code:

    • On motion sensor: the minimum is 3 seconds and the maximum is 5 minutes, which is done via the Time Delay Adjuster.
    • On ESP8266 Code: any value can be set, which is done by coding.

    If we do not specify a timeout in the ESP8266 code, . the timeout value will be the same as the time delay in the sensor's configuration.

    If we specify a timeout in the ESP8266 code, the total time delay will be the combination of the delay set in the sensor and the delay specified in the ESP8266 code.

    Setting time delay in ESP8266 code

    /* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-motion-sensor */ #define MOTION_SENSOR_PIN D7 // The ESP8266 pin D7 connected to the OUTPUT pin of motion sensor int motion_state = LOW; // current state of pin int prev_motion_state = LOW; // previous state of pin const unsigned long DELAY_TIME_MS = 30000; // 30000 miliseconds ~ 30 seconds bool delay_enabled = false; unsigned long delay_start_ms; void setup() { Serial.begin(9600); // Initialize the Serial to communicate with the Serial Monitor. pinMode(MOTION_SENSOR_PIN, INPUT); // set arduino pin to input mode to read value from OUTPUT pin of sensor } void loop() { prev_motion_state = motion_state; // store state motion_state = digitalRead(MOTION_SENSOR_PIN); // read new state if (prev_motion_state == LOW && motion_state == HIGH) { // pin state change: LOW -> HIGH Serial.println("Motion detected!"); Serial.println("Turning on / activating"); delay_enabled = false; // disable delay // TODO: turn on alarm, light or activate a device ... here } else if (prev_motion_state == HIGH && motion_state == LOW) { // pin state change: HIGH -> LOW Serial.println("Motion stopped!"); delay_enabled = true; // enable delay delay_start_ms = millis(); // set start time } if (delay_enabled == true && (millis() - delay_start_ms) >= DELAY_TIME_MS) { Serial.println("Turning off / deactivating"); delay_enabled = false; // disable delay // TODO: turn off alarm, light or deactivate a device ... here } }

    If the repeatable trigger mode is enabled, the delay will be set to 30 seconds plus time_delay, which can be adjusted on the sensor's settings using the Time Delay Adjuster.

Challenge Yourself

Utilize the motion sensor to accomplish one of the following projects:

  • Activate the lights when you enter your room and deactivate them after 30 seconds after you leave. Tip: Take a look at ESP8266 - Relay.
  • Set off an alarm when someone approaches your valuable items. Tip: Check out ESP8266 - Piezo Buzzer.

Function References