/*
* ESP32 Photoresistor Light Sensor with LED Indicator
*
* This program reads light intensity using a photoresistor (LDR - Light Dependent Resistor)
* and controls an LED based on the ambient light level.
*
* Hardware Setup for Wokwi:
* - ESP32 board
* - Photoresistor (LDR) connected to GPIO 25 (ADC pin)
* - LED connected to GPIO 12 with current limiting resistor
*
* The photoresistor forms a voltage divider circuit with a fixed resistor,
* and the ESP32's ADC reads the voltage to calculate light intensity in Lux.
*/
// Constants for LDR calculations
const float GAMMA = 0.7; // Gamma correction factor for the specific LDR type
const float RL10 = 50; // LDR resistance at 10 Lux (from datasheet)
const int LDR_PIN = 25; // Analog pin connected to photoresistor
const int LED_PIN = 12; // Digital pin connected to LED
const float THRESHOLD_LUX = 50; // Light threshold to determine bright/dark
// Variables for sensor readings
float lux = 0;
int analogValue = 0;
float voltage = 0;
float resistance = 0;
void setup() {
// Initialize serial communication at 115200 baud rate
Serial.begin(115200);
// Configure LED pin as output
pinMode(LED_PIN, OUTPUT);
// Configure ADC resolution (ESP32 default is 12-bit = 4096 levels)
analogReadResolution(12);
// Initial message
Serial.println("=== ESP32 Light Sensor Started ===");
Serial.println("Monitoring ambient light level...\n");
// Turn off LED initially
digitalWrite(LED_PIN, LOW);
}
void loop() {
// Read analog value from photoresistor (0-4095 for 12-bit ADC)
analogValue = analogRead(LDR_PIN);
// Convert ADC reading to voltage
voltage = analogValue * 5 / 4095.0;
// Calculate photoresistor resistance using voltage divider formula
// Assuming a 2kΩ pull-down resistor in the voltage divider
if (voltage > 0.1) { // Avoid division by very small numbers
resistance = 2000 * voltage / (1 - voltage / 5);
} else {
resistance = 999999; // Very high resistance (very dark)
}
// Convert resistance to Lux using the photoresistor's characteristic curve
// This formula is specific to the LDR type and may need calibration
if (resistance > 0) {
lux = pow((RL10 * 1000 * pow(10, GAMMA)) / resistance, (1.0 / GAMMA));
} else {
lux = 0;
}
// Limit unrealistic values
if (lux > 10000) lux = 10000;
if (lux < 0) lux = 0;
// Display readings on serial monitor
Serial.print("ADC Reading: ");
Serial.print(analogValue);
Serial.print(" | Voltage: ");
Serial.print(voltage, 2);
Serial.print("V | Resistance: ");
Serial.print(resistance, 0);
Serial.print("Ω | Lux: ");
Serial.print(lux, 1);
// Determine light condition and control LED
if (lux >= THRESHOLD_LUX) {
Serial.print(" | Status: Terang (Bright)");
digitalWrite(LED_PIN, LOW); // Turn OFF LED when it's bright
} else {
Serial.print(" | Status: Gelap (Dark)");
digitalWrite(LED_PIN, HIGH); // Turn ON LED when it's dark
}
Serial.println(); // New line
// Wait 500ms before next reading (reduced frequency for better readability)
delay(500);
}