ESP32 S3 UNO - LDR Module
This ESP32 S3 Uno LDR module tutorial shows you how to connect an LDR light sensor module to the ESP32 S3 Uno form board and sense light with Arduino code. The module, also called a photoresistor module or photocell module, gives you two signals: a simple light or dark state, and a light level value you can measure.
In this tutorial, you will:
- Wire an LDR light sensor module to the ESP32 S3 Uno
- Detect light with the digital DO pin and digitalRead()
- Measure light intensity with the analog AO pin and analogRead()
- Tune the light threshold with the module's potentiometer

Hardware Preparation
| 1 | × | ESP32 S3 Uno-form Board | |
| 1 | × | USB Cable Type-A to Type-C (for USB-A PC) | |
| 1 | × | USB Cable Type-C to Type-C (for USB-C PC) | |
| 1 | × | LDR Light Sensor Module | |
| 1 | × | Jumper Wires |
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Overview of LDR Light Sensor Module
An LDR light sensor module tells your board how bright the room is. It is a small board with a light-dependent resistor, a comparator chip and a potentiometer. You can use it as an on/off light detector, as a light level meter, or as both at the same time.
Pinout
The module has four pins. Two of them power the board, and the other two carry the light signal.
| Pin | What It Does |
|---|---|
| VCC | Power input, 3.3V to 5V. Use 3.3V with the ESP32 S3 Uno |
| GND | Ground (0V) |
| DO | Digital output. HIGH when it is dark, LOW when there is light. The potentiometer sets the switch point |
| AO | Analog output. The voltage goes down when it gets brighter and goes up when it gets darker |

The module also has two small LEDs. The PWR-LED turns on when the module has power. The DO-LED follows the DO pin: it is on when the module sees light and off in the dark.
How It Works
The two outputs work in different ways, so it helps to know what each one does before you write code.
DO pin (digital)
The potentiometer on the module sets a light threshold. When the light around the sensor is brighter than this threshold, the DO pin goes LOW and the DO-LED turns off. When the light is weaker than the threshold, the DO pin goes HIGH and the DO-LED turns on.
AO pin (analog)
The AO pin gives a voltage that follows the light level. More light means a lower reading, and less light means a higher reading. The potentiometer has no effect on the AO pin. It only moves the threshold for the DO pin.
So you can tune the DO pin for a simple yes/no light check, and still read the exact light level from the AO pin.
ESP32 S3 Uno Pinout
The image below shows the pinout of the ESP32 S3 Uno form board. Use it to find the Uno header pins (D2, A0…) and their GPIO numbers while you wire the sensor.

Wiring Diagram
The module has two outputs, and you can use one of them or both. The diagram connects DO to D2 and AO to A0, so both sketches below work without changing any wire.

This image is created using Fritzing. Click to enlarge image
| LDR Module Pin | ESP32 S3 Uno Pin |
|---|---|
| VCC | 3.3V |
| GND | GND |
| DO | D2 (GPIO18) |
| AO | A0 (GPIO2) |
WARNING
ESP32 S3 Uno pins are NOT 5V tolerant. If you power the module from 5V, the DO pin and the AO pin can reach 5V and may damage the board. Power the module from the 3.3V pin, so both outputs stay between 0V and 3.3V. The module works fine at 3.3V.
ESP32 S3 Uno Code - Read value from DO pin
This sketch reads the DO pin on D2 (GPIO18) many times per second. It prints whether light is present or not to the Serial Monitor.
Detailed Instructions
Do these steps in order:
- New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
- Wire it up as shown in the diagram.
- Connect the board to your computer with a USB Type-C cable.
- Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
- Copy the code above and paste it into Arduino IDE.
- Upload the code by clicking the Upload button.
- Test the sensor by covering the LDR with your hand, then taking your hand away.
- Open the Serial Monitor and check the result.
- Tip: If the DO-LED stays on all the time, or stays off even in bright light, turn the potentiometer slowly until the LED changes state at the light level you want.
Now you have a working light detector. You can change the code to turn on an LED or a lamp when it gets dark, or to move a servo motor. The related tutorials at the end of this page show you how.
ESP32 S3 Uno Code - Read value from AO pin
This sketch reads the AO pin on A0 (GPIO2) and prints the raw light value. On the ESP32 S3 Uno the value goes from 0 to 4095, because the ADC is 12-bit. A small number means bright light, and a big number means dark.
The sketch calls analogSetAttenuation(ADC_11db) in setup(). By default, the ESP32 S3 Uno ADC can only measure a small voltage. The 11 dB setting lets the analog pin read the full range, from 0V up to about 3.3V. Without it, the reading hits 4095 too early and the light values look wrong.
Detailed Instructions
- Copy the code above and open it in Arduino IDE.
- Upload the code by clicking the Upload button.
- Cover and uncover the LDR with your hand or an object.
- Open the Serial Monitor and watch the numbers change.
- Tip: Write down the values you get in your room, both bright and dark. Use them later as thresholds in your own code.
Video Tutorial
Watch the video below to see this ESP32 S3 Uno project step by step.
The demo in the video uses the code below. It reads the AO pin, smooths the value with a simple filter (EMA), and fades an extra LED on D9 (GPIO46) brighter as the room gets darker. The thresholds are set for the 12-bit ADC (0 to 4095).
WARNING
The demo LED is on D9, which is GPIO46 on the ESP32 S3 Uno. GPIO46 is a boot strapping pin. If the LED circuit pulls this pin HIGH while the board starts, the board may not boot or may fail to upload code. Connect the LED through a resistor to GND (not to 3.3V). If you have boot or upload problems, unplug the LED wire and try again.
Function References
FAQ
Can I power the LDR module from 5V on the ESP32 S3 Uno?
The module itself works at 5V, but its DO and AO outputs then swing up to 5V. ESP32 S3 Uno pins are 3.3V only and are not 5V tolerant. Power the module from the 3.3V pin, and both outputs stay in a safe range.
Why do I get values up to 4095 instead of 1023?
The ESP32 S3 Uno has a 12-bit ADC, so analogRead() returns 0 to 4095. Boards like the UNO R4 use 10-bit by default and return 0 to 1023. If you copy thresholds from an UNO R4 project, multiply them by about 4.
Why does the code call analogSetAttenuation(ADC_11db)?
It sets the ESP32 S3 Uno ADC input range to about 0V to 3.3V, so the full light sensor signal maps to 0 to 4095. Without it the range is smaller, and the readings jump to 4095 even in normal room light. The UNO R4 does not need this line, because it is ESP32-only. Keep the AO voltage at 3.3V or less.
Should I use the DO pin or the AO pin?
Use the DO pin when you only need to know "light or dark", for example for a night light. Use the AO pin when you want a light level number, for example to dim an LED step by step. You can wire both at the same time.
Is the LDR module accurate enough to measure lux?
No. An LDR gives a relative value that depends on the part, the temperature and the supply voltage. It is great for detecting light and dark. For real lux values, use a digital light sensor such as the BH1750.
What if my project needs more pins than the Uno headers give?
The ESP32 S3 Uno has two extra rows of holes with more GPIOs: GPIO15 and GPIO16 (I/O, PWM, analog), GPIO45 and GPIO35 to GPIO42 (I/O, PWM), and GPIO47/GPIO48 (output only, PWM). Solder pin headers to use them and write the GPIO number in your code. For a second LDR module, use GPIO15 or GPIO16 for the AO pin, and GPIO35 to GPIO42 for the DO pin. Do not use GPIO47/GPIO48 as sensor inputs. Two warnings: (1) GPIO47/GPIO48 may run at 1.8V instead of 3.3V on some modules (especially ones with "V" in the name, like R8V or R16V), so 3.3V devices can be damaged or act strangely. (2) GPIO0, GPIO3 (D6), GPIO45 and GPIO46 (D9) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code. Use the other extra pins first.
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No COM port shows up in Arduino IDE | USB driver missing or board not in upload mode | Install the CP210x or CH340 driver, use a data USB cable, or hold BOOT while you press RESET |
| DO always prints the same message | Potentiometer threshold set too high or too low | Turn the potentiometer slowly until the DO-LED changes when you cover the sensor |
| Analog value stays at 4095 | Attenuation not set, or AO wired to the wrong pin | Keep analogSetAttenuation(ADC_11db) in setup() and check that AO goes to A0 (GPIO2) |
| Analog value stays at 0 or does not change | Loose wire or no power on the module | Check that the PWR-LED is on and that VCC, GND and AO are firmly connected |
| Readings jump a lot | Electrical noise or flickering room light | Average several readings or use the EMA filter from the demo code |
| Board does not boot or upload with the demo LED | LED on D9 (GPIO46) pulls a boot strapping pin | Wire the LED to GND through a resistor, or unplug it while uploading |
| Serial Monitor shows strange characters | Baud rate does not match the code | Set the Serial Monitor to 9600 baud for the DO and AO sketches and 115200 baud for the demo |
| Board resets or gets hot | Module powered from 5V sends 5V into a GPIO | Move the module VCC wire to the 3.3V pin |