A Python + ESP32-S3 based smart hardware controller that uses serial communication and an LDR sensor to control an LED automatically or manually.
This project combines Python, serial communication, ESP32, sensor input, and hardware control into one practical system.
- Python-based hardware control interface
- ESP32-S3 hardware controller
- Serial communication between Python and ESP32
- Manual LED ON/OFF control
- Automatic LED control based on ambient light
- LDR sensor for light detection
- Dark and bright environment detection
- Live LDR value monitoring
- Configurable light thresholds
- Terminal-based user interface
The system has two main parts.
Python provides the user interface and decision-making logic.
The user can choose:
- Automatic Mode
- Manual LED ON
- Manual LED OFF
- Exit
Python receives LDR readings from the ESP32 and decides whether the environment is dark or bright.
The ESP32-S3 reads the LDR through GPIO 4 and continuously sends the sensor readings to Python.
It also receives commands from Python and controls the built-in LED.
LDR Sensor
โ
ESP32-S3
โ
Serial Communication
โ
Python
โ
Decision / Control Logic
โ
Serial Command
โ
ESP32-S3
โ
Built-in LED
| Component | Quantity |
|---|---|
| ESP32-S3 N16R8 | 1 |
| 7mm LDR | 1 |
| Fixed resistor | 1 |
| Breadboard | 1 |
| Jumper wires | As required |
| USB-C cable | 1 |
The project uses the ESP32-S3 built-in LED, so an external LED is not required.
The LDR is connected as a voltage divider:
ESP32-S3
โ
3.3V
โ
LDR
โ
โโโโโโโโโ GPIO 4 (ADC)
โ
Fixed Resistor
โ
GND
| Component | Connection |
|---|---|
| LDR side 1 | 3.3V |
| LDR side 2 | GPIO 4 |
| Fixed resistor | GPIO 4 โ GND |
| Ground | GND |
The ESP32 firmware reads the LDR using:
int ldrValue = analogRead(4);The ESP32 sends a new LDR reading approximately every 500 ms.
ESP32 GPIO/ADC pins use 3.3V logic. Do not apply 5V directly to GPIO 4.
- Arduino IDE
- ESP32 Arduino Core
- Python 3
- PySerial
- VS Code (optional)
Arduino IDE is used to upload the ESP32 firmware. VS Code is optional for editing the Python code.
The tested setup uses:
COM Port โ COM14
Baud Rate โ 115200
The COM port is computer-specific, so another user may have a different COM port.
Python sends commands to the ESP32:
1 โ LED ON
2 โ LED OFF
The ESP32 continuously sends LDR sensor readings back to Python.
The Python controller uses two thresholds:
DARK_THRESHOLD = 80
LIGHT_THRESHOLD = 150When the LDR value falls below the dark threshold:
Environment โ DARK
LED โ ON
When the LDR value rises above the light threshold:
Environment โ BRIGHT
LED โ OFF
Two thresholds create separation between the dark and bright states, helping prevent unnecessary switching around one boundary.
The values 80 and 150 were calibrated for the tested setup.
LDR readings can change depending on:
- LDR type
- Resistor value
- Room lighting
- Sensor position
- Wiring
- ESP32 board
When reproducing this project, check your own LDR readings in both bright and dark conditions.
If your readings are different, change:
DARK_THRESHOLD = YOUR_DARK_VALUE
LIGHT_THRESHOLD = YOUR_BRIGHT_VALUEChoose the thresholds according to the actual readings from your hardware.
Select:
2. Manual LED ON
Python sends command 1 to the ESP32 and the built-in LED turns ON.
Select:
3. Manual LED OFF
Python sends command 2 to the ESP32 and the built-in LED turns OFF.
During Automatic Mode, the Python interface continuously updates:
- LDR Value
- Environment
- LED Status
- Current Mode
The dashboard updates in place instead of continuously printing new lines, keeping the terminal interface clean and readable.
SMART HARDWARE CONTROLLER
โ
โโโ Python
โ โโโ main.py
โ
โโโ ESP32
โ โโโ ESP32.ino
โ
โโโ hardware
โ โโโ circuit-diagram.png
โ
โโโ README.md
Connect the LDR voltage divider:
LDR โ GPIO 4
LDR circuit โ 3.3V
Resistor โ GND
Connect the ESP32-S3 to the computer using USB.
Open:
ESP32/ESP32.ino
in Arduino IDE.
Select the correct ESP32-S3 board and COM port, then upload the code.
Open Arduino Serial Monitor at:
115200 baud
Check that the LDR value changes when the sensor is covered and exposed to light.
Close the Serial Monitor before running Python because the same COM port cannot normally be used by both programs at the same time.
Open a terminal and run:
pip install pyserialOpen:
Python/main.py
Make sure the COM port matches the ESP32.
Example:
esp32 = serial.Serial("COM14", 115200)Replace COM14 with the COM port assigned to your ESP32.
From the Python directory:
python main.pyUse the terminal menu:
1. Automatic Mode
2. Manual LED ON
3. Manual LED OFF
4. Exit
Test the manual controls first, then test Automatic Mode by changing the room lighting.
- ESP32-S3 connected through USB
- Correct ESP32-S3 board selected
- Correct COM port selected
- LDR connected to GPIO 4
- LDR circuit powered from 3.3V
- Common GND connected
- ESP32 firmware uploaded
- LDR readings change with light
- Python 3 installed
- PySerial installed
- Correct COM port configured in Python
- Arduino Serial Monitor closed before running Python
- Manual LED ON works
- Manual LED OFF works
- Automatic Mode works
- Thresholds calibrated
Check:
- USB cable and connection
- COM port
- Baud rate
- ESP32 connection
- Arduino Serial Monitor is closed
- No other program is using the COM port
Find the correct port in:
Arduino IDE โ Tools โ Port
Then update:
esp32 = serial.Serial("YOUR_COM_PORT", 115200)Check:
- LDR wiring
- GPIO 4 connection
- 3.3V connection
- GND connection
- Fixed resistor
- Voltage-divider wiring
Check the actual LDR values and adjust:
DARK_THRESHOLD
LIGHT_THRESHOLDThe thresholds depend on the physical environment and circuit.
Increase the separation between the dark and bright thresholds.
Through this project I learned:
- Python serial communication
- Communication between software and hardware
- ESP32-S3 programming
- Analog sensor reading
- ESP32 ADC
- LDR-based light detection
- Voltage-divider circuits
- Threshold-based automation
- Controlling hardware from Python
- Sending commands from Python to an ESP32
- Receiving sensor data from an ESP32
- Designing a terminal-based control interface
- Handling serial data
- Connecting software logic with physical hardware
- Building a simple closed-loop automation system
Possible future upgrades include:
- Multiple sensors
- Multiple LEDs
- Relay-based appliance control
- Fan control
- OLED display
- Wi-Fi control
- Web-based dashboard
- Mobile application
- Data logging
- Remote monitoring
- Real-time graphs
- Multiple-room automation
- AI-based automation
- Integration with a larger smart-home system
This project is an early building block toward larger smart hardware and AI automation systems.
The goal is to gradually combine:
- Embedded Systems
- Hardware Control
- Sensors
- Automation
- Python
- AI
- IoT
- Software Interfaces
into increasingly capable real-world systems.
This project represents the transition from learning software concepts to using software to control physical hardware.
Muhammad Ahsan
Computer Engineering Student
COMSATS University Islamabad, Lahore Campus
This project is part of my Operation-1000 journey, where the goal is to continuously learn, build, experiment, document, and eventually turn technical skills into real-world products and services.
โญ More projects coming.