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:

  1. Wire a light sensor and an LED to the ESP32 S3 Uno
  2. Read the light level with analogRead()
  3. Turn the LED on when the analog value is below a threshold
  4. Turn the LED off when the analog value is above the threshold
ESP32 S3 Uno light sensor LED

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×Light Sensor
1×LED Kit
1×LED (red)
1×LED Module
1×Alternatively, Button and LED Kit
1×220Ω Resistor
1×10 kΩ Resistor
1×Breadboard
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
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.

ESP32 S3 Uno pinout diagram

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.

The wiring diagram between ESP32 S3 Uno Light Sensor LED

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.

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-light-sensor-controls-led */ #define LIGHT_SENSOR_PIN 2 // ESP32 S3 Uno pin GPIO2 (A0) connected to light sensor's pin #define LED_PIN 17 // ESP32 S3 Uno pin GPIO17 (D3) connected to LED's pin #define ANALOG_THRESHOLD 200 // 0 to 4095 range (12-bit ADC) // variables will change: int analogValue; void setup() { // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); pinMode(LED_PIN, OUTPUT); // set ESP32 S3 Uno pin to output mode } void loop() { analogValue = analogRead(LIGHT_SENSOR_PIN); // read the input on analog pin (value between 0 and 4095) if(analogValue < ANALOG_THRESHOLD) digitalWrite(LED_PIN, HIGH); // turn on LED else digitalWrite(LED_PIN, LOW); // turn off LED }

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:

  1. New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
  2. Wire it up as shown in the diagram.
  3. Connect the board to your computer with a USB Type-C cable.
  4. Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
  5. Copy the code above and paste it into Arduino IDE.
  6. Upload the code by clicking the Upload button.
Arduino IDE Upload Code
  1. Cover the sensor with your hand, and check that the LED turns on.
  2. Shine a light on the sensor, and check that the LED turns off.
  3. 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

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!