#113Beginner

Reading Light Intensity with the ESP32 LDR Module

Real-time monitoring of the LDR module's raw ADC value and relative light percentage calculated from dark and light reference values in the Serial Monitor. This percentage is not a lux measurement. Teaches the module’s calibration logic. It is ideal to complete this before Project 10, as it is used to determine the threshold value.

4.6(36)
55 completed
Reading Light Intensity with the ESP32 LDR Module
A simple light meter that shows how bright your room is as a percentage. The light sensor measures the surroundings, and the ESP32 turns that into zero for darkness and a hundred for full light, writing it on your computer screen every half second. Before building a night light, you take this measurement to decide at which level the lamp should switch on.

Video

Circuit Diagram

Reading Light Intensity with the ESP32 LDR Module - Circuit

Source Code

Arduino (C++)
1// ─────────────────────────────────────────
2//   BlueGrays · bluegrays.com
3//   Reading Light Intensity with the ESP32 LDR Module
4// ─────────────────────────────────────────
5// Reads the analog output (AO) of the LDR module with the 12-bit ADC and
6// converts it to a 0-100 light percentage using the calibration values.
7// The result is printed to the Serial Monitor (115200 baud) every 0.5 s.
8//
9// Pins:
10//   GPIO 34 (classic ESP32) / GPIO 1 (ESP32-S2/S3) -> LDR module AO
11//   LDR module VCC -> 3V3, GND -> GND
12
13#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
14  const int LDR_PIN = 1;   // ESP32-S2/S3: ADC1_CH0
15#else
16  // Classic ESP32 DevKit V1: ADC1_CH6, input-only. GPIO 1 clashes with Serial TX here
17  const int LDR_PIN = 34;
18#endif
19
20// Calibration: measure in your own room and enter the values here. On the LDR module the AO voltage
21// (and raw) DROPS as the light gets brighter.
22const int RAW_DARK  = 4000;  // Dark raw
23const int RAW_LIGHT = 100;   // Light raw
24
25void setup() {
26  Serial.begin(115200);
27  analogReadResolution(12);  // Force 12-bit
28  Serial.println("LDR Okuma / LDR Reading");
29  Serial.println("-----------------------------");
30}
31
32void loop() {
33  int raw = analogRead(LDR_PIN);
34  // Clip to the calibration range, dark = 0%
35  int clipped = constrain(raw, RAW_LIGHT, RAW_DARK);
36  int percent = map(clipped, RAW_DARK, RAW_LIGHT, 0, 100);
37
38  Serial.print("Raw: ");
39  Serial.print(raw);
40  Serial.print(" | Light: %");
41  Serial.println(percent);
42
43  delay(500);
44}
45

FAQ

What values does the ESP32's ADC return?▾

The ESP32's ADC is 12-bit and returns values ranging from 0 to 4095. Since this differs from the 0–1023 range on the Arduino Uno, you should adjust your thresholds and calculations accordingly.

Analog readings are distorted when Wi-Fi is on. Why?▾

On the ESP32, the ADC2 channel (GPIO 0, 2, 4, 12–15, 25–27) cannot be used while Wi-Fi is enabled. Connecting analog sensors to the ADC1 pins (GPIO 32–39) prevents this issue.

Is the reading the actual lux value?▾

No, this code does not calculate lux; it displays the raw ADC value and a relative light percentage based on the selected dark and light reference values. The LDR's response is not linear and varies from model to model. For precise lux measurement, a calibrated sensor such as the BH1750 is used.

Why does the ESP32 ADC give incorrect readings at the extremes?▾

The ESP32's ADC is not linear near 0 V and 3.3 V. The `analogReadMilliVolts()` function returns calibrated values; for critical measurements, operating within the 0.1–3.1 V range yields the most accurate results.