ESP32 LDR Simulator: Wiring, Code and a Live Circuit
This is a light-dependent resistor wired to an ESP32 DevKit in a voltage divider with a 10 k resistor, read live: the serial monitor prints the raw reading, a percent and the words Dark, Dim or Bright four times a second.
- 3.3 V logic
- No library: analogRead()
- Divider on GPIO 34 (D34)
- 10 k fixed resistor
Wiring the LDR to the ESP32
Four connections: the LDR from 3V3 to GPIO 34 (D34), and the 10 k resistor from GPIO 34 (D34) to GND. In the editor, drag the light slider on the sensor and the reading follows it.
Every connection in the circuit above, with the board’s own pin names.
| LDR pin | ESP32 pin | Why |
|---|---|---|
| LDR, one leg | 3V3 | The top of the voltage divider. |
| LDR, other leg | GPIO 34 (D34) | The middle of the divider, where the reading is taken. |
| 10 k resistor, one end | The LDR leg on GPIO 34 (D34) | Joined to the same node as the analog pin. |
| 10 k resistor, other end | GND | The bottom of the divider. |
Power
The divider runs between 3V3 and GND, so the pin never sees more than 3.3 V. Do not use VIN (5 V from USB) for it: in bright light the pin would rise toward 5 V. The ESP32’s ADC is twelve bits, 0 to 4095, and at the default attenuation it saturates at about 3.1 V, so a pot across the 3.3 V rail reaches 4095 a little before the end of its travel and reads about 1890 in the middle.
Pins to leave alone on the ESP32
GPIO 34, 35, 36 (VP) and 39 (VN) are input only: they cannot drive a pin or take an internal pull-up. GPIO 0, 2, 5, 12 and 15 are strapping pins, read at power-on, and GPIO 6 to 11 are the flash chip.
On a real bench
The thirty-pin DevKit straddles a breadboard with one row of holes free on each side, which is where the LDR’s jumpers go. Many ESP32 boards are wider and cover both rows; then use two breadboards side by side. Hold BOOT while uploading if the IDE cannot connect.
The code, and what it does.
The sketch the circuit above runs. Open it in the editor, change a line and press Run: it compiles in your browser.
const int LDR_PIN = 34; // the divider's middle, GPIO 34 (D34)
void setup() {
Serial.begin(115200);
}
void loop() {
int raw = analogRead(LDR_PIN); // 0 to 4095
int percent = map(raw, 0, 4095, 0, 100);
Serial.print("Light: ");
Serial.print(raw);
Serial.print(" ");
Serial.print(percent);
Serial.print("% ");
if (percent < 25) {
Serial.println("Dark");
} else if (percent < 60) {
Serial.println("Dim");
} else {
Serial.println("Bright");
}
delay(250);
}
An LDR is a resistor whose value falls as light rises: very high in the dark, a few hundred ohms in strong light. A microcontroller reads voltage, not resistance, so the LDR is paired with a fixed 10 k resistor to make a voltage divider. More light means a lower LDR resistance, so more of the supply drops across the 10 k and the pin reads higher.
analogRead() gives 0 to 4095, and map() turns that into a percent. The three bands (under 25, under 60, above) are the sketch's guess at dark, dim and bright; the numbers depend on the LDR and the resistor, so change them to suit your room.
Serial.begin(115200) opens the serial monitor. Serial is UART0 on the USB bridge. ESP32 sketches usually run it at 115200 baud, which this one does.
Common mistakes with the LDR on the ESP32
No fixed resistor
An LDR alone is a resistor between two pins, not a voltage. With nothing from the analog pin to ground the pin floats, and the reading barely follows the light. The 10 k to GND is what makes it a divider.
Reading it backwards
With the LDR on the supply side, as here, bright light reads high. Swap the LDR and the resistor and bright reads low. Both work as long as the code agrees with the wiring.
Running the divider from VIN (5 V from USB)
In bright light the middle of the divider rises toward the supply. From VIN (5 V from USB) that is more than the ESP32 (Xtensa LX6)'s analog input can take. Use 3V3.
Questions and answers
Can I simulate an LDR with an ESP32 DevKit?
Yes. The circuit at the top of this page is an ESP32 DevKit with a light-dependent resistor, running in your browser on a simulated ESP32 (Xtensa LX6). Drag the light slider on the sensor and its resistance changes the way a real cell does, falling as the light rises. Press Run it in the editor to change the wiring or the code; it is free and needs no account.
What resistor should I use with an LDR?
One near the LDR’s resistance at the light level where you want the most sensitivity. 10 k suits indoor light and the common GL55 cells.
What does analogRead() give on the ESP32?
The ESP32’s ADC is twelve bits, 0 to 4095, and at the default attenuation it saturates at about 3.1 V, so a pot across the 3.3 V rail reaches 4095 a little before the end of its travel and reads about 1890 in the middle.
Is the reading in lux?
No. The reading is a voltage, and the link between voltage and lux depends on the cell and the resistor. For real lux readings, a BH1750 sensor measures them directly.
Build your own LDR project
Open this circuit in the editor, change the wiring or the code, and keep your version in a free account.