Skip to content
Home » Embedded Systems » Sensors » Motion and Proximity Sensors: Accelerometers, Gyroscopes, PIR, and Ultrasonic

Motion and Proximity Sensors: Accelerometers, Gyroscopes, PIR, and Ultrasonic

Sensors for Embedded Systems
Part 15 of 18 — View Full Path →

KEY TAKEAWAYS

  • PIR sensors use the pyroelectric effect to detect warm body movement through a Fresnel lens that focuses infrared radiation onto a dual-element detector.
  • The HC-SR04 ultrasonic sensor measures distance by timing a 40kHz echo pulse, with a usable range of 2cm to 400cm and plus-or-minus 3mm accuracy.
  • IR proximity sensors come in reflective (object detection) and break-beam (counting/safety) configurations, each suited to different range and accuracy needs.
  • The MPU6050 combines a 3-axis accelerometer and 3-axis gyroscope over I2C, making it the go-to IMU for orientation tracking in embedded projects.
  • Microwave radar sensors like the RCWL-0516 can detect motion through walls and enclosures, unlike PIR sensors that require line-of-sight.

Part of the Complete Guide to Sensors for Embedded Systems series.

Motion and proximity detection enables robotics, gesture recognition, security systems, drones, fitness trackers, and countless other embedded applications. This guide covers the most important motion and proximity sensor categories with practical interfacing guidance, complete code examples, and a comparison to help you choose the right sensor for your project.

PIR Sensor Working Principle

Passive Infrared (PIR) sensors detect changes in infrared radiation caused by a warm body moving across their field of view. They do not emit any energy. The sensing element is a dual-element pyroelectric detector made from lithium tantalate or similar crystalline material. When infrared radiation strikes the crystal, it generates a small surface charge through the pyroelectric effect. The dual-element design means that when a warm object moves across the sensor, it first heats one element (creating a positive voltage spike) and then the other (creating a negative spike). This differential signal is what triggers the output. A stationary warm object produces no signal because both elements see the same background.

The Fresnel lens mounted in front of the detector is critical to the sensor performance. It divides the field of view into alternating zones of sensitivity and insensitivity. As a person walks past, they cross these zones and create the alternating signal the sensor needs. Without the Fresnel lens, the tiny pyroelectric element would only detect motion within a few centimeters. The lens expands the detection range to 5-7 meters and the field of view to 110 degrees or more.

The HC-SR501 module includes the pyroelectric sensor, Fresnel lens, and analog processing circuitry. It has two potentiometers for adjusting sensitivity (detection range) and time delay (how long the output stays HIGH after motion stops, typically 3 seconds to 5 minutes). Output is digital: HIGH when motion detected, LOW otherwise. It operates on 5-20V and provides a clean 3.3V output signal compatible with most microcontrollers.

Ultrasonic Sensor (HC-SR04) with Code

The HC-SR04 ultrasonic sensor measures distance by sending a burst of eight 40kHz ultrasonic pulses and timing how long the echo takes to return. The speed of sound at 20 degrees Celsius is approximately 343 meters per second. The distance formula is: distance_cm = (pulse_duration_us * 0.0343) / 2. The division by 2 accounts for the round-trip travel of the sound wave.

To trigger a measurement, send a 10 microsecond HIGH pulse to the trigger pin. The sensor transmits the ultrasonic burst and sets the echo pin HIGH. Your microcontroller measures the echo pulse width using a timer. The usable range is 2cm to 400cm with an accuracy of plus-or-minus 3mm. The beam angle is about 15 degrees, which means nearby objects outside the direct path can cause false echoes.

Here is a complete C implementation for an STM32 microcontroller using a hardware timer for accurate pulse measurement:

/* HC-SR04 Ultrasonic Sensor Driver - STM32 HAL */
#include "stm32f4xx_hal.h"
#include <stdio.h>

#define TRIG_PIN    GPIO_PIN_0
#define TRIG_PORT   GPIOA
#define ECHO_PIN    GPIO_PIN_1
#define ECHO_PORT   GPIOA

extern TIM_HandleTypeDef htim2;  /* 1 MHz timer (prescaler = SystemCoreClock/1MHz - 1) */

void delay_us(uint16_t us) {
    __HAL_TIM_SET_COUNTER(&htim2, 0);
    while (__HAL_TIM_GET_COUNTER(&htim2) < us);
}

float hcsr04_read_distance_cm(void) {
    uint32_t echo_start, echo_end, pulse_us;

    /* Send 10us trigger pulse */
    HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET);
    delay_us(10);
    HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);

    /* Wait for echo pin to go HIGH (with timeout) */
    uint32_t timeout = 0;
    while (HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_RESET) {
        if (++timeout > 100000) return -1.0f;  /* No echo received */
    }
    echo_start = __HAL_TIM_GET_COUNTER(&htim2);

    /* Wait for echo pin to go LOW */
    timeout = 0;
    while (HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_SET) {
        if (++timeout > 100000) return -1.0f;  /* Echo too long */
    }
    echo_end = __HAL_TIM_GET_COUNTER(&htim2);

    /* Calculate distance */
    pulse_us = echo_end - echo_start;
    float distance_cm = (pulse_us * 0.0343f) / 2.0f;

    /* Validate range */
    if (distance_cm < 2.0f || distance_cm > 400.0f) {
        return -1.0f;  /* Out of range */
    }

    return distance_cm;
}

/* Usage in main loop */
void measure_and_print(void) {
    float dist = hcsr04_read_distance_cm();
    if (dist > 0) {
        printf("Distance: %.1f cmrn", dist);
    } else {
        printf("Out of range or no echorn");
    }
    HAL_Delay(100);  /* Minimum 60ms between measurements */
}

Important considerations: the speed of sound varies with temperature according to the formula 331.3 + (0.606 * temperature_celsius) meters per second. For precision applications, add a temperature sensor (like the DS18B20 or DHT22) and compensate the distance calculation. Also, multiple ultrasonic sensors can interfere with each other if triggered simultaneously. Always trigger them sequentially with at least 60ms between readings.

IR Proximity Sensors: Reflective vs Break-Beam

Infrared proximity sensors come in two fundamental configurations, each suited to different applications.

Reflective sensors contain an IR LED emitter and a photodetector side by side. The emitter shines IR light outward, and if an object is close enough, the light bounces back to the detector. The Sharp GP2Y0A21 is a popular analog reflective sensor with a range of 10-80cm. It outputs an analog voltage inversely proportional to distance. Simpler modules like the TCRT5000 are used for line-following robots and obstacle detection at short range (1-25mm). Reflective sensors are affected by the color and surface texture of the target. Dark or matte surfaces reflect less IR and reduce detection range.

Break-beam sensors place the emitter and detector on opposite sides of a gap. When an object passes through and interrupts the beam, the detector output changes. These are used for counting objects on conveyor belts, safety curtains on machinery, and door entry counters. Break-beam sensors are more reliable than reflective types because they do not depend on surface reflectivity. They provide a clean digital signal and work well at longer distances (several meters with focused beams).

RCWL-0516 Microwave Radar Sensor

The RCWL-0516 is a microwave Doppler radar module that detects motion by transmitting a 3.18GHz continuous wave and measuring the frequency shift of the reflected signal. Unlike PIR sensors, microwave radar can detect motion through walls, glass, wood, and plastic enclosures. This makes it ideal for hidden installations where the sensor must be concealed behind a panel or inside a product housing.

The module operates on 4-28V, has a detection range of approximately 5-7 meters, and provides a digital HIGH output (3.3V) for about 2 seconds after motion is detected. It is sensitive to any movement, including small hand gestures, which can be both an advantage (gesture detection) and a disadvantage (false triggers from fans, curtains, or even nearby electronics). For reliable operation, keep it away from large metal surfaces that can cause reflections and false detections.

Accelerometer and Gyroscope (MPU6050) I2C Interface

The MPU6050 is a 6-axis Inertial Measurement Unit (IMU) that combines a 3-axis accelerometer (configurable to plus-or-minus 2g, 4g, 8g, or 16g) and a 3-axis gyroscope (configurable to plus-or-minus 250, 500, 1000, or 2000 degrees per second). It communicates over I2C at address 0x68 (or 0x69 if the AD0 pin is pulled high). The accelerometer measures linear acceleration and tilt, while the gyroscope measures angular velocity.

Here is a complete C example for reading raw accelerometer and gyroscope data from the MPU6050 over I2C:

/* MPU6050 I2C Driver - STM32 HAL */
#include "stm32f4xx_hal.h"
#include <stdio.h>

#define MPU6050_ADDR        (0x68 << 1)  /* 7-bit addr shifted for HAL */
#define REG_PWR_MGMT_1      0x6B
#define REG_ACCEL_CONFIG     0x1C
#define REG_GYRO_CONFIG      0x1B
#define REG_ACCEL_XOUT_H     0x3B

extern I2C_HandleTypeDef hi2c1;

typedef struct {
    int16_t accel_x, accel_y, accel_z;
    int16_t gyro_x, gyro_y, gyro_z;
    int16_t temperature;
} MPU6050_Data_t;

HAL_StatusTypeDef mpu6050_write_reg(uint8_t reg, uint8_t val) {
    return HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, reg, 1, &val, 1, 100);
}

HAL_StatusTypeDef mpu6050_init(void) {
    /* Wake up the sensor (clear sleep bit) */
    if (mpu6050_write_reg(REG_PWR_MGMT_1, 0x00) != HAL_OK) return HAL_ERROR;
    HAL_Delay(100);

    /* Set accelerometer range to +/-2g */
    mpu6050_write_reg(REG_ACCEL_CONFIG, 0x00);

    /* Set gyroscope range to +/-250 deg/s */
    mpu6050_write_reg(REG_GYRO_CONFIG, 0x00);

    return HAL_OK;
}

HAL_StatusTypeDef mpu6050_read(MPU6050_Data_t *data) {
    uint8_t buf[14];

    /* Read 14 bytes starting from ACCEL_XOUT_H */
    if (HAL_I2C_Mem_Read(&hi2c1, MPU6050_ADDR, REG_ACCEL_XOUT_H,
                          1, buf, 14, 100) != HAL_OK) {
        return HAL_ERROR;
    }

    data->accel_x = (int16_t)(buf[0] << 8 | buf[1]);
    data->accel_y = (int16_t)(buf[2] << 8 | buf[3]);
    data->accel_z = (int16_t)(buf[4] << 8 | buf[5]);
    data->temperature = (int16_t)(buf[6] << 8 | buf[7]);
    data->gyro_x = (int16_t)(buf[8] << 8 | buf[9]);
    data->gyro_y = (int16_t)(buf[10] << 8 | buf[11]);
    data->gyro_z = (int16_t)(buf[12] << 8 | buf[13]);

    return HAL_OK;
}

/* Convert raw values to physical units */
void mpu6050_print(MPU6050_Data_t *d) {
    float ax = d->accel_x / 16384.0f;  /* +/-2g range: 16384 LSB/g */
    float ay = d->accel_y / 16384.0f;
    float az = d->accel_z / 16384.0f;
    float gx = d->gyro_x / 131.0f;     /* +/-250 dps: 131 LSB/dps */
    float gy = d->gyro_y / 131.0f;
    float gz = d->gyro_z / 131.0f;
    float temp = (d->temperature / 340.0f) + 36.53f;

    printf("Accel: X=%.2fg Y=%.2fg Z=%.2fgrn", ax, ay, az);
    printf("Gyro:  X=%.1f  Y=%.1f  Z=%.1f dpsrn", gx, gy, gz);
    printf("Temp:  %.1f Crn", temp);
}

Applications of accelerometers include step counting for fitness trackers, tilt measurement for digital bubble levels, free-fall detection for hard drive protection, vibration monitoring for machinery health, and screen rotation on mobile devices. Gyroscopes measure angular velocity and, when fused with accelerometer data using a complementary filter or Kalman filter, provide stable orientation estimates for drone flight controllers, VR headsets, and self-balancing robots.

Sensor Comparison Table

The following table summarizes the key characteristics of each sensor type to help you select the right one for your application:

PIR (HC-SR501) — Range: 5-7m | Output: Digital | Power: 65mA at 5V | Cost: Very low | Best for: Occupancy detection, security alarms, motion-activated lights.

Ultrasonic (HC-SR04) — Range: 2cm-400cm | Output: Pulse width | Power: 15mA at 5V | Cost: Very low | Best for: Distance measurement, obstacle avoidance, level sensing.

IR Reflective (Sharp GP2Y0A21) — Range: 10-80cm | Output: Analog voltage | Power: 30mA at 5V | Cost: Low | Best for: Short-range distance, line following, edge detection.

IR Break-Beam — Range: Up to several meters | Output: Digital | Power: 20mA | Cost: Low | Best for: Object counting, safety curtains, door entry detection.

Microwave Radar (RCWL-0516) — Range: 5-7m | Output: Digital | Power: 3mA at 5V | Cost: Low | Best for: Through-wall detection, concealed installations, gesture sensing.

IMU (MPU6050) — Range: Configurable (2g-16g, 250-2000 dps) | Output: I2C digital | Power: 3.9mA | Cost: Low | Best for: Orientation, tilt, vibration, step counting, drone stabilization.

Common Mistakes and Troubleshooting

False triggers with PIR sensors are the most common complaint. Causes include direct sunlight hitting the sensor, nearby heat sources creating convection currents, and mounting the sensor near air conditioning vents. Solutions include adding a time-based debounce in firmware, reducing sensitivity via the potentiometer, and shielding the sensor from heat sources. Note that PIR sensors cannot detect motion through glass because glass blocks the far-infrared wavelengths they rely on.

Dead zones with ultrasonic sensors occur at distances below 2cm where the sensor cannot distinguish between the transmitted pulse and the echo. The 15-degree beam angle also creates blind spots. For narrow-beam applications, consider a laser time-of-flight sensor like the VL53L0X instead. Temperature changes affect the speed of sound and can introduce measurement errors of up to 2% across a 40-degree Celsius temperature range.

MPU6050 drift is a well-known issue with gyroscopes. Integrating angular velocity over time accumulates errors, causing the calculated angle to drift. The solution is sensor fusion using a complementary filter or Kalman filter that combines the short-term accuracy of the gyroscope with the long-term stability of the accelerometer. A simple complementary filter blends the two: angle = 0.98 * (angle + gyro_rate * dt) + 0.02 * accel_angle.

Project Idea: Automatic Door Opener with Ultrasonic Sensor

A practical project combining several concepts from this guide is an automatic door opener. Use the HC-SR04 ultrasonic sensor to detect when a person approaches within 50cm. When someone is detected, activate a servo motor to swing the door open. Keep the door open as long as the person remains within range, then close it after a 3-second timeout when the person moves away. Add hysteresis to prevent the door from repeatedly opening and closing when someone stands near the threshold distance. For example, open at 50cm but only close when the person moves beyond 70cm. This project teaches you distance measurement, threshold logic with hysteresis, servo motor control, and state machine design.

Related on this site

  • For a deep dive on the HC-SR04 ultrasonic sensor specifically — trigger/echo timing, the distance math, and full Arduino code — see working of an ultrasonic sensor.
  • Infrared proximity modules use a different physical principle entirely (IR LED plus phototransistor); IR sensor module walks through the practical wiring and code.
  • Analog accelerometer outputs typically need amplification and filtering before the ADC — see signal conditioning for sensors for the standard circuits.

Leave a Reply

Your email address will not be published. Required fields are marked *