ESP32 S3 UNO - Light Sensor Control LED
This ESP32 S3 Uno light sensor LED tutorial shows you how to switch an LED on and off by the amount of light in the room. You will wire a photoresistor (LDR) and an LED to the ESP32 S3 Uno form board and write Arduino code that compares the light level with a threshold. When it gets dark, the LED turns on, just like an automatic night light.
In this tutorial, you will:
- Wire a light sensor and an LED to the ESP32 S3 Uno
- Read the light level with analogRead()
- Turn the LED on when the analog value is below a threshold
- Turn the LED off when the analog value is above the threshold

Hardware Preparation
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 .
Buy Note: Use the LED Module for easier wiring. It includes an integrated resistor.
A bare LDR light sensor costs very little, but it needs an extra resistor, so the wiring takes a few more steps. If you want a simpler setup, you can use an LDR light sensor module instead. It already has the resistor on its board.
Overview of LED and Light Sensor
This project joins one input and one output. The light sensor tells the board how bright the room is, and the LED shows the result. If you have not used these parts before, it helps to try each one on its own first.
The tutorials below explain the pinout, how each part works, and how to program it:
ESP32 S3 Uno Pinout
The image below shows the pinout diagram of the ESP32 S3 Uno form board. Use it to find the Uno header pins (D3, A0, 3.3V…) and their GPIO numbers when you wire the circuit.

Wiring Diagram
The light sensor and the 10 kΩ resistor make a voltage divider, and the middle point goes to analog pin A0. The LED goes to pin D3 through a 220 ohm resistor.

This image is created using Fritzing. Click to enlarge image
| Component Pin | ESP32 S3 Uno Pin |
|---|---|
| Light Sensor Pin 1 | 3.3V |
| Light Sensor Pin 2 and 10 kΩ resistor | A0 (GPIO2) |
| Other end of 10 kΩ resistor | GND |
| LED Anode (+) via 220 ohm resistor | D3 (GPIO17) |
| LED Cathode (-) | GND |
WARNING
Connect the light sensor to the 3.3V pin, not 5V. The ESP32 S3 Uno pins are not 5V tolerant, so a 5V signal on A0 can damage the board.
ESP32 S3 Uno Code
The sketch reads the light level on A0 again and again. If the value drops below the threshold (the room is dark), it turns the LED on. If the value is above the threshold, it turns the LED off.
In setup(), the code calls analogSetAttenuation(ADC_11db). By default, the ESP32 S3 Uno ADC can only measure a small voltage. With 11 dB attenuation, the analog pin reads the full range from 0V up to about 3.3V. Without this line, the reading hits 4095 too early and the light values look wrong.
The ESP32 S3 Uno ADC gives values from 0 to 4095, so the threshold is 200. This is about the same light level as a threshold of 50 on a 0 to 1023 board. You can change ANALOG_THRESHOLD to fit your room.
Detailed Instructions
Follow these steps one by one:
- 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.

- Cover the sensor with your hand, and check that the LED turns on.
- Shine a light on the sensor, and check that the LED turns off.
- Tip: If the LED stays on or off all the time, print analogValue to the Serial Monitor, see the real values in your room, and set ANALOG_THRESHOLD between the dark and bright values.
Code Explanation
The comments in the source code explain each line. The idea is simple. analogRead() returns a bigger number when there is more light, because the LDR resistance goes down. The if statement compares this number with ANALOG_THRESHOLD and sets the LED pin HIGH or LOW.
Video Tutorial
Watch the video below to see this ESP32 S3 Uno project step by step.
FAQ
Why does the ESP32 S3 Uno read 0 to 4095 instead of 0 to 1023?
The ESP32 S3 Uno has a 12-bit ADC, so analogRead() returns a number from 0 to 4095. The UNO R4 uses 0 to 1023 by default. If you copy a threshold from code for that board, multiply it by about 4, or the LED will switch at the wrong light level.
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 reading reaches 4095 too early. The UNO R4 does not need this line, because it is only for ESP32 boards. Keep the sensor output at 3.3V or less.
Can I power the light sensor from 5V on the ESP32 S3 Uno?
No. With 5V on the divider, the voltage on A0 can go above 3.3V in bright light. The ESP32 S3 Uno pins are not 5V tolerant, so this can damage the analog pin. Use the 3.3V pin instead.
How do I choose the right threshold for the LED?
Light levels are different in every room. Add Serial.begin(9600); and Serial.println(analogValue); to the code, then check the values in the Serial Monitor when the room is dark and when it is bright. Pick a number between them for ANALOG_THRESHOLD.
Can I use the LDR light sensor module instead of a bare LDR?
Yes. Connect the module's AO pin to A0 (GPIO2), VCC to 3.3V and GND to GND. Then you do not need the 10 kΩ resistor. Some modules give a lower value in bright light, so you may need to swap the < in the if statement.
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 support I/O, PWM and analog, so they are a good choice for an extra light sensor. GPIO45 and GPIO35 to GPIO42 support I/O and PWM, so they work well for extra LEDs. GPIO47 and GPIO48 are output only with PWM, so do not use them for a sensor. Solder pin headers to these holes and write the GPIO number in code. Be careful with two things. First, GPIO47 and 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. Second, 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 in Arduino IDE | USB driver missing or charge-only cable | Install the CP210x or CH340 driver and use a USB data cable |
| Upload fails or times out | Board is not in download mode | Hold the BOOT button, press and release RESET, then upload again |
| LED does not light at all | LED is reversed or the resistor is not connected | Put the long leg (anode) toward D3 (GPIO17) and check the 220 ohm resistor |
| LED stays on all the time | Threshold is too high for your room or the 10 kΩ resistor is missing | Check the divider wiring and lower ANALOG_THRESHOLD |
| LED never turns on in the dark | Threshold is too low or the LDR and resistor are swapped | Put the LDR on 3.3V and the 10 kΩ resistor on GND, or raise ANALOG_THRESHOLD |
| Reading stays at 4095 | Attenuation line is missing or A0 gets more than 3.3V | Keep analogSetAttenuation(ADC_11db) in setup() and power the sensor from 3.3V |
| LED flickers near the threshold | Light level is very close to the threshold | Use two thresholds (one to turn on, one to turn off) or move the sensor |