ESP32 S3 UNO - Light Sensor Control Servo Motor

This ESP32 S3 Uno light sensor servo motor tutorial shows you how to move a servo when the light around it changes. You wire a photoresistor (LDR) or an LDR light sensor module to the ESP32 S3 Uno form board, then write Arduino code that turns the servo to 90° or back to 0° based on the light level.

In this tutorial, you will:

  1. Wire a light sensor and a servo motor to the ESP32 S3 Uno
  2. Read the light level with analogRead() and compare it to a threshold
  3. Read a digital LDR light sensor module with digitalRead()
  4. Control a servo motor with the ESP32Servo library
ESP32 S3 Uno light sensor servo motor

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×10 kΩ Resistor
1×Servo Motor
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: For controlling multiple servo motors, use the PCA9685 16 Channel PWM Servo Driver Module to save MCU pins and simplify wiring.

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 simpler wiring, use an LDR light sensor module instead. It has the resistor on board and gives you a ready-made digital output.

Overview of Servo Motor and Light Sensor

This project joins two parts that each have their own tutorial. If the servo motor or the light sensor is new to you, read those first. You will then know how each part is wired and coded, and this project will be quick to build.

ESP32 S3 Uno Pinout

The image below shows the pinout of the ESP32 S3 Uno form board. Use it to find the A0, D9 and D11 headers and their GPIO numbers when you wire the circuit.

ESP32 S3 Uno pinout diagram

Wiring Diagram

There are two ways to build this project. Pick the one that matches your light sensor. In both cases the servo signal wire goes to D9.

Wiring with a light sensor (analog)

The photoresistor and the 10 kΩ resistor make a voltage divider. Their middle point goes to A0, so the voltage on A0 changes with the light.

The wiring diagram between ESP32 S3 Uno Light Sensor Servo Motor

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 A0 (GPIO2)
10 kΩ resistor, end 1 A0 (GPIO2)
10 kΩ resistor, end 2 GND
Servo VCC (red) 5V
Servo GND (brown or black) GND
Servo Signal (orange or yellow) D9 (GPIO46)

Wiring with a light sensor module (digital)

The LDR module has a DO (digital output) pin. It goes HIGH or LOW when the light crosses the level set by the small knob on the module.

The wiring diagram between ESP32 S3 Uno Light Sensor module Servo Motor

This image is created using Fritzing. Click to enlarge image

Component Pin ESP32 S3 Uno Pin
Light sensor module VCC 3.3V
Light sensor module GND GND
Light sensor module DO D11 (GPIO11)
Servo VCC (red) 5V
Servo GND (brown or black) GND
Servo Signal (orange or yellow) D9 (GPIO46)

WARNING

D9 is GPIO46 on the ESP32 S3 Uno. It is a boot strapping pin, which the chip reads at startup to pick the boot mode. A servo signal wire is usually safe here. But if the board does not boot or the upload fails, unplug the servo signal wire from D9, upload the code, then plug it back in.

WARNING

ESP32 S3 Uno pins are NOT 5V tolerant. Power the photoresistor or the LDR module from 3.3V, not 5V, so the signal on A0 or D11 never goes above 3.3V. The servo can still take 5V for power, because its signal wire only receives the 3.3V signal from the board.

ESP32 S3 Uno Code - Analog Threshold

There are two sketches, one for each wiring. Both start with the servo at 0° and move it to 90° when the sensor says so.

Code for the light sensor (analog)

This sketch reads the light level on A0 (GPIO2) again and again. When the reading goes above the threshold of 2000, the servo on D9 (GPIO46) turns to 90°. Otherwise it goes back to 0°.

/* * 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-servo-motor */ #include <ESP32Servo.h> #define LIGHT_SENSOR_PIN 2 // ESP32 S3 Uno pin A0 (GPIO2) connected to light sensor's pin #define SERVO_PIN 46 // ESP32 S3 Uno pin D9 (GPIO46) connected to Servo Motor's pin #define ANALOG_THRESHOLD 2000 // threshold for the 12-bit ADC (0 - 4095) Servo servo; // create servo object to control a servo void setup() { // set the ADC attenuation to 11 dB (up to ~3.3V input) analogSetAttenuation(ADC_11db); servo.attach(SERVO_PIN); // attaches the servo on pin D9 (GPIO46) to the servo object servo.write(0); } void loop() { int analogValue = analogRead(LIGHT_SENSOR_PIN); // read the input on analog pin (0 - 4095) if (analogValue > ANALOG_THRESHOLD) servo.write(90); // rotate servo motor to 90 degree else servo.write(0); // rotate servo motor to 0 degree }

The ESP32 S3 Uno ADC is 12-bit, so analogRead() returns 0 to 4095 instead of 0 to 1023. That is why the threshold is 2000, close to the middle of the range. The sketch also calls analogSetAttenuation(ADC_11db) in setup(). 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 it, the reading hits 4095 too early and the servo may stay at 90° even in dim light.

Code for the light sensor module (digital)

This sketch reads the DO pin of the module on D11 (GPIO11). When the pin is HIGH (no light), the servo turns to 90°. When it is LOW (light), the servo returns to 0°. It also prints the light state to the Serial Monitor.

/* * 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-servo-motor */ #include <ESP32Servo.h> #define LIGHT_SENSOR_PIN 11 // ESP32 S3 Uno pin D11 (GPIO11) connected to light sensor's pin #define SERVO_PIN 46 // ESP32 S3 Uno pin D9 (GPIO46) connected to Servo Motor's pin Servo servo; // create servo object to control a servo void setup() { Serial.begin(9600); // initialize serial communication pinMode(LIGHT_SENSOR_PIN, INPUT); // initialize the ESP32 S3 Uno's pin as an input servo.attach(SERVO_PIN); // attaches the servo on pin D9 (GPIO46) to the servo object servo.write(0); } void loop() { int light_state = digitalRead(LIGHT_SENSOR_PIN); if (light_state == HIGH) { Serial.println("The light is NOT present"); servo.write(90); // rotate servo motor to 90 degree } else { Serial.println("The light is present"); servo.write(0); // rotate servo motor to 0 degree } }

Both sketches use ESP32Servo.h instead of Servo.h, because the standard Servo library does not support ESP32 boards.

Detailed Instructions

  1. New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
  2. Wire it up as shown in the diagram for your sensor.
  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. Install the library. Open the Library Manager, search for ESP32Servo, and install the one by Kevin Harrington.
  6. Copy the code that matches your wiring and paste it into the Arduino IDE.
  7. Upload the code. Click the Upload button to send the sketch to the ESP32 S3 Uno.
  8. Change the light. Cover the light sensor with your hand, then shine a light on it.
  9. Watch the servo turn between 0° and 90°. With the module sketch, open the Serial Monitor at 9600 baud to see the light state.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
The light is present The light is present The light is NOT present The light is NOT present The light is present
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2
  1. Tip: If the servo switches at the wrong light level, change ANALOG_THRESHOLD in the analog sketch, or turn the small knob on the LDR module.

Video Tutorial

Watch the video below to see this ESP32 S3 Uno project step by step.

Function References

These pages explain the functions used in this project. The Servo functions work the same way with the ESP32Servo library.

FAQ

How do I choose the right threshold for the light sensor?

Print analogValue to the Serial Monitor and check the numbers in bright light and in the dark. Pick a value between the two. On the ESP32 S3 Uno the reading goes from 0 to 4095, so a threshold of 500 from an UNO R4 sketch is much too low here.

Can I use the normal Servo library with the ESP32 S3 Uno?

No. The standard Servo.h library does not support ESP32 boards. Install the ESP32Servo library by Kevin Harrington and include ESP32Servo.h. The functions attach() and write() work the same way.

Should I power the light sensor from 3.3V or 5V?

Use 3.3V. The ESP32 S3 Uno pins are not 5V tolerant. On 5V, the voltage on A0 or D11 can go above 3.3V in bright light and damage the pin.

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 saturates early. The UNO R4 does not need this line, it is for ESP32 boards only. Keep the sensor output at 3.3V or less.

Why is the servo on D9, which is a warning pin?

D9 is GPIO46, a boot strapping pin. The wiring keeps the same D9 position as the UNO version of this project. A servo signal input usually does not disturb booting. If you have upload or boot problems, unplug the signal wire during upload, or move the servo to another PWM pin like D7 (GPIO14) and change SERVO_PIN in the code.

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 are I/O, PWM and analog. GPIO45 and GPIO35 to GPIO42 are I/O and PWM. GPIO47 and GPIO48 are output only, with PWM. Solder pin headers to use them and write the GPIO number in code. For this project, a second LDR fits GPIO15 or GPIO16, an LDR module or extra servos fit GPIO35 to GPIO42. Do not use GPIO47 or GPIO48 for sensor inputs. 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 in Arduino IDE Missing USB driver or board not in upload mode Install the CP210x or CH340 driver, try another cable, or hold BOOT while pressing RESET
Upload fails or board does not boot Servo signal on D9 (GPIO46) affects the boot strapping pin Unplug the servo signal wire during upload, then plug it back in
Compile error about Servo.h The standard Servo library does not support the ESP32 S3 Uno Install ESP32Servo by Kevin Harrington and include ESP32Servo.h
Servo never moves with the analog sketch Threshold does not fit your light level Print the reading and set ANALOG_THRESHOLD between the dark and bright values
Servo stays at 90 degrees in dim light ADC attenuation not set or sensor powered from 5V Keep analogSetAttenuation(ADC_11db) in setup() and power the sensor from 3.3V
Servo does not move at all Signal wire on the wrong pin or no common ground Check the signal wire is on D9 and the servo GND is tied to the board GND
Board resets when the servo moves Servo draws too much current from the board Use an external 5V supply for the servo and share GND with the board
LDR module output never changes Sensitivity knob set too far Turn the knob on the module until its LED switches with the light

※ 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!