42 Light and Proximity Labs: Calibrating Sensors
42.1 Start With the Decision
Picture a cupboard light that should turn on when a hand reaches inside. It works at noon but fails at dusk because the test used one bright room and one clean target.
42.2 Route Overview
This is part 1 of 2. Continue with Light and Proximity Labs: Touch and Bus Integration.
42.3 Part Objectives
- Evaluate light and proximity sensors with range, error, power, and interface evidence.
- Evaluate hc-sr04 distance measurement with range, error, power, and interface evidence.
-
Start With the Measurement Story
-
In 60 Seconds
-
Light and Proximity Sensors
-
Prerequisites
-
Light Sensors
-
Optional ESP32 Implementation
-
Try It: Lux Level Explorer
-
Learning Points: Light Sensing
-
Checkpoint: Light Thresholds
-
Proximity & Presence Sensors
-
Optional ESP32 Implementation
-
Try It: PIR Detection Zone Simulator
-
Learning Points: PIR Sensors
-
Checkpoint: Presence Evidence
-
Ultrasonic Measurement Flow
-
Optional ESP32 Implementation
-
Putting Numbers to It
-
Try It: Ultrasonic Distance Calculator
-
Learning Points: Ultrasonic Sensors
-
HC-SR04 Distance Measurement
-
First, separate calibrated light readings from analog LDR behavior so threshold choices match the sensor.
-
Then, test PIR and ultrasonic proximity as different kinds of presence evidence rather than interchangeable detectors.
-
Next, connect I2C bus checks and analog circuits to the wiring faults that make labs unreliable.
-
Finally, use the challenges, quizzes, and readout companion to turn working readings into evidence records.
Checkpoint callouts mark places to pause and confirm the story so far; deep-dive and practice sections can be skimmed on a first lab pass and revisited when you need the implementation detail.
42.5 Learning Objectives
By the end of this chapter, you will be able to:
- Interface light sensors: Configure BH1750 digital lux meter and LDR analog sensors
- Build proximity detection: Use PIR motion sensors and HC-SR04 ultrasonic distance sensors
- Compare touch sensing technologies: Differentiate capacitive and skin-inspired tactile sensor architectures
- Diagnose I2C communication: Scan buses, address multiple sensors, and resolve communication issues
- Apply circuit fundamentals: Use voltage dividers and RC filters in sensor circuits
Light sensors measure how bright it is (like the automatic brightness on your phone screen), PIR motion sensors detect when a person walks by (like the sensor that turns on a porch light), and ultrasonic distance sensors measure how far away an object is by bouncing sound waves off it (like a bat navigating in the dark). These are some of the most commonly used sensors in smart home and security projects.
42.6 Prerequisites
Required Knowledge:
- Motion & Environmental Sensors - I2C basics
- Electronics Basics - Circuit fundamentals
- Sensor Circuits - Signal conditioning
Hardware Requirements:
- ESP32 development board
- BH1750 light sensor or LDR (photoresistor)
- PIR motion sensor (HC-SR501)
- HC-SR04 ultrasonic distance sensor
- Resistors (10kOhm for voltage divider, 4.7kOhm for I2C)
- Breadboard and jumper wires
42.7 Light Sensors
A digital ambient-light sensor supplies illuminance evidence for brightness decisions rather than a motion or distance reading. The BH1750 example uses an I2C interface and reports the light level in lux. Automatic displays can increase brightness in daylight and use a more moderate setting indoors. The useful decision connects the measured lighting condition to the display or lamp behavior instead of treating a bus address as a light measurement.
42.7.1 BH1750 (Digital Light Intensity)
The BH1750 is a digital ambient light sensor with spectral response close to the human eye, making it ideal for automatic brightness adjustment.
Specifications:
Start by Range: 1-65535 lux. Then Interface: I2C. Next Resolution: 1 lux. After that I2C Address: 0x23 (ADDR pin LOW/floating) or 0x5C (ADDR pin HIGH). Continue by Spectral response close to human eye. Finally Power: 120uA active, 0.01uA power down.
What to Observe Before Coding:
| Lux Range | Real-World Meaning | Device Decision Example |
|---|---|---|
| Below 50 lux | Dark or very dim | Turn on night lighting |
| 50-500 lux | Indoor lighting | Keep display brightness moderate |
| Above 2000 lux | Bright daylight | Increase display brightness or ignore PIR shadows |
The mathematical gist. The chapter’s 3.3 V supply and 10 kΩ fixed resistor give . Its bright, midpoint, and dark cases therefore map 1 kΩ, 10 kΩ, and 1 MΩ to 3.00 V (code 3723), 1.65 V (code 2048), and 0.0327 V (code 41). The same lab keeps its 50 cm proximity threshold empirical because target colour, angle, sunlight, and optics break a universal inverse-square calibration.
#include <Wire.h>
#include <BH1750.h>
BH1750 lightMeter;
void setup() {
Serial.begin(115200);
Wire.begin(); // Uses default ESP32 I2C pins: SDA=GPIO21, SCL=GPIO22
if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
Serial.println("BH1750 initialized");
} else {
Serial.println("Error initializing BH1750");
}
}
void loop() {
float lux = lightMeter.readLightLevel();
Serial.print("Light: ");
Serial.print(lux);
Serial.print(" lux");
// Classify light levels (approximate ranges)
String classification;
if (lux < 1) {
classification = "Darkness (moonlight)";
} else if (lux < 50) {
classification = "Very dim (street lighting)";
} else if (lux < 200) {
classification = "Dim (hallway)";
} else if (lux < 500) {
classification = "Normal (home/office)";
} else if (lux < 2000) {
classification = "Bright (retail/overcast)";
} else if (lux < 25000) {
classification = "Very bright (daylight)";
} else {
classification = "Extremely bright (direct sun)";
}
Serial.print(" - ");
Serial.println(classification);
delay(1000);
}
A light reading supports different actions as the available natural illumination changes during the day. Street lighting can dim when natural light is sufficient, while a display adjusts backlighting for its viewing conditions. A greenhouse can supplement natural illumination with artificial light when the crop needs it. The energy benefit comes from avoiding unnecessary full brightness rather than collecting lux values without changing the load.
Lux Reference Values:
| Condition | Lux Level |
|---|---|
| Full moon | 0.1-1 |
| Street lighting | 10-50 |
| Home lighting | 150-300 |
| Office | 300-500 |
| Overcast sky | 1,000-2,000 |
| Full daylight | 10,000-25,000 |
| Direct sunlight | 100,000+ |
Real-World Applications:
Start with Smart street lights: Dim when natural light is sufficient. Then Display backlighting: Adjust screen brightness based on ambient light. Next Greenhouse automation: Supplement natural light with artificial lighting. Finally Energy efficiency: Reduce power when full brightness isn’t needed.
Checkpoint: Light Thresholds
You now know:
- A BH1750 reports calibrated lux over I2C, while an LDR needs a divider and ADC interpretation.
- Thresholds are decisions about scenes: dark, indoor, daylight, and direct sunlight lead to different device actions.
- Hysteresis belongs in the control rule when one threshold would make an output flicker.
The light lab established how illumination becomes a stable decision. The next question is how a device should notice a nearby person or object when brightness is not the signal.
42.8 Proximity & Presence Sensors
42.8.1 PIR Motion Sensor (HC-SR501)
PIR (Passive Infrared) sensors detect motion by measuring changes in infrared radiation from warm bodies (humans, animals).
Different bodies can provide the same PIR motion capability: the module, Fresnel lens, adjustment controls, terminals, and enclosure change how the sensor is mounted and commissioned without changing the fact that it reports infrared change rather than identity or distance.
Read across the four forms from exposed prototype to finished wall unit. The lens and housing determine optical zones, adjustment access, weather and tamper protection, and mounting repeatability; none of them changes the PIR evidence boundary examined next.
Specifications:
- Detection Range: 3-7 meters (adjustable)
- Detection Angle: 110 degree cone
- Output: Digital HIGH when motion detected
- Hold Time: ~2.5 to 200 seconds (adjustable via potentiometer)
- Power: 5V, ~65µA quiescent
- Trigger Modes: Single trigger or repeatable trigger
What to Observe Before Coding:
PIR sensors do not identify people. They detect changes in infrared energy across their detection zones. In the simulator below, focus on how distance, angle, and environment affect false triggers.
#define PIR_PIN 13 // GPIO13 for PIR sensor
bool motionDetected = false;
unsigned long lastMotionTime = 0;
void setup() {
Serial.begin(115200);
pinMode(PIR_PIN, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
Serial.println("PIR Motion Sensor Test");
Serial.println("Warming up sensor (30-60 seconds)...");
delay(60000); // PIR needs 30-60s warm-up time
Serial.println("Ready!");
}
void loop() {
int pirState = digitalRead(PIR_PIN);
if (pirState == HIGH) {
if (!motionDetected) {
motionDetected = true;
lastMotionTime = millis();
Serial.println("MOTION DETECTED!");
Serial.print("Time: ");
Serial.println(millis() / 1000);
// Trigger action (turn on light, send alert, etc.)
digitalWrite(LED_BUILTIN, HIGH);
}
} else {
if (motionDetected) {
unsigned long motionDuration = (millis() - lastMotionTime) / 1000;
Serial.print("Motion ended. Duration: ");
Serial.print(motionDuration);
Serial.println(" seconds");
motionDetected = false;
digitalWrite(LED_BUILTIN, LOW);
}
}
delay(100);
}
A PIR motion sensor provides a digital state for a motion-triggered light or alert. The sensor needs a warm-up interval after power-on before the test should judge its normal behavior. Sensitivity and hold-time controls change detection and output persistence rather than converting the output into an illuminance reading. A useful test connects motion in the detection area to the expected light or security response.
Key Characteristics:
Start by PIR sensors need a 30-60 second warm-up period after power-on. Then Output is digital (HIGH/LOW), making interfacing very simple. Next The sensor stays HIGH as long as motion is detected. Finally Adjustable potentiometers control sensitivity and hold time.
Real-World Applications:
Start by Smart lighting: Turn on lights when someone enters a room. Then Security systems: Send alerts when motion detected while away. Next Energy saving: Power down devices when no one is present. Finally Occupancy counting: Track room usage patterns.
Checkpoint: Presence Evidence
You now know:
- PIR output is a digital motion signal, so it is good for presence changes but not for distance.
- Mounting height, hold time, trigger mode, and environment all shape whether a motion event is useful evidence.
- A warm-up period and confirmation delay are part of the lab design, not optional cleanup.
PIR answers whether motion changed in a detection zone. Ultrasonic ranging answers a different question: how far away the reflecting surface is, and whether the timing math still holds under the current air temperature.
42.8.2 Ultrasonic Distance Sensor (HC-SR04)
Ultrasonic sensors measure distance by timing the echo return of a 40kHz sound pulse.
Before applying the echo-time equation, inspect Figure to assign the module’s two acoustic paths and four electrical pins. Distance is inferred from a timed round trip, not read directly by either metal can.
Read Figure, identify the transmitter and receiver first, then trace trigger and echo at the header alongside power and ground. The outgoing 40 kHz burst and returning echo define the measured interval, connecting target geometry, blind zone, and sound speed to the distance calculation.
Specifications:
- Range: 2cm to 400cm
- Accuracy: +/-3mm
- Measuring angle: 15 degrees
- Trigger pulse: 10us
- Power: 5V, 15mA
The HC-SR04 operates at 5V logic, but the ESP32 GPIO pins are 3.3V. The ECHO pin outputs a 5V HIGH signal that can damage the ESP32. Use a voltage divider (two resistors, e.g., 1kOhm + 2kOhm) on the ECHO line to reduce it to ~3.3V, or use a 3.3V-compatible variant like the HC-SR04P.
What to Observe Before Coding:
The HC-SR04 measures time, not distance directly. The microcontroller sends a trigger pulse, waits for the echo pulse, then converts travel time into distance using the speed of sound.
An ultrasonic distance measurement starts with a trigger and uses the returning echo pulse as timing evidence. The measured echo interval includes the outward and return travel of the sound. The distance calculation divides that round-trip path by two to obtain the one-way range. Temperature affects the speed of sound, so compensation changes the conversion from elapsed time to the reported distance.
Start by Send a 10 microsecond trigger pulse. Then Measure the echo pulse width. Finally Convert round-trip echo time into one-way distance using the speed of sound.
#define TRIG_PIN 5
#define ECHO_PIN 18
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
void loop() {
float distance = measureDistance();
Serial.print("Distance: ");
Serial.print(distance, 1);
Serial.println(" cm");
// Object detection
if (distance > 0 && distance < 50) {
Serial.println("Object detected nearby!");
}
delay(100);
}
float measureDistance() {
// Send 10us pulse
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Measure echo pulse duration
long duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout
// Calculate distance (speed of sound = 343 m/s at 20°C)
// distance = (duration * 0.0343) / 2
float distance = duration * 0.0343 / 2.0;
return distance;
}
Ultrasonic sensors measure distance using the time-of-flight formula where sound travels to the object and back.
where is distance, is echo pulse duration in microseconds, and is 343 m/s (0.0343 cm/µs) at 20°C.
Worked example: The HC-SR04 measures an echo pulse duration of 1,750 µs. Calculate the distance:
Temperature compensation: At 0°C, speed of sound is 331.3 m/s (3.4% slower), so the same 1,750 µs pulse would calculate as 29.0 cm instead of 30.0 cm, introducing 1 cm error per 30 cm distance without compensation.
Run it: Before you read echo time as distance, switch the Light and Proximity Sensing Workbench to Proximity mode. Set an object distance and an air temperature and watch the speed of sound (v = 331.3 + 0.606 x T) and the round-trip echo time update together, so a warmer day visibly shortens the echo for the same distance. Then move the detect and release thresholds and toggle hysteresis to see the dead band absorb chatter as an object approaches the stop line.
Adjust the echo pulse duration and ambient temperature to see how they affect the calculated distance. Notice how temperature changes the speed of sound and therefore the distance measurement.
Key Concepts:
Start with Time-of-Flight: distance = (time ** speed_of_sound) / 2. Then Speed of Sound: 343 m/s at 20°C (0.0343 cm/µs). Next Temperature Compensation: Speed varies ~0.6 m/s per °C. Finally Blind zone: Cannot measure objects closer than 2cm.
Real-World Applications:
Start by Parking sensors: Alert drivers to obstacles. Then Robotics: Obstacle avoidance and navigation. Next Liquid level sensing: Measure tank fill levels. Finally People counting: Detect presence at doorways.
Temperature Compensation: Sound travels faster in warmer air. Add about 0.606 m/s to the 331.3 m/s baseline for each degree Celsius, then divide the round-trip echo distance by two.
The HC-SR04 uses time-of-flight measurement with these precise steps:
Start with Send trigger pulse - 10µs HIGH signal on TRIG pin activates the sensor. Then Sensor emits ultrasound - 8 cycles of 40 kHz sound burst (inaudible to humans). Next Wait for echo - ECHO pin goes HIGH when sound is transmitted. After that Measure echo duration - ECHO pin goes LOW when reflected sound returns. Finally Calculate distance - distance_cm = (echo_duration_µs × 0.0343) / 2.
Why divide by 2? The sound travels to the object AND back, so the total time covers twice the distance.
42.9 Continue to the Next Part
Carry this evidence into Light and Proximity Labs: Touch and Bus Integration, which begins with Touch and Skin Sensing.
