A photosensor is an electronic component that detects electromagnetic radiation (light) and converts it into an electrical signal—either a changing resistance, a current, or a digital data stream. In embedded systems, we use them to measure ambient light levels (illuminance in Lux), detect object presence via beam breaks, or trigger automation based on daylight. The direct answer to 'what is a photosensor' depends on the specific chemistry: it is either a passive resistor that reacts to photons (like an LDR) or an active semiconductor that generates a digital output (like the BH1750).
The Physics: How Photosensors Detect Light
At the bench level, photosensors rely on the internal photoelectric effect. In passive components like Cadmium Sulfide (CdS) Light Dependent Resistors (LDRs), incoming photons strike the semiconductor lattice and excite bound electrons into the conduction band. This increases the number of charge carriers, effectively lowering the electrical resistance of the material. The brighter the light, the lower the resistance, allowing more current to flow through a bias circuit.
Active digital sensors, such as the ROHM BH1750FVI or the Vishay TEMT6000, use photodiodes operating in photovoltaic or photoconductive mode. Here, photons striking the PN junction generate a tiny photocurrent directly proportional to the irradiance. An integrated transimpedance amplifier and an Analog-to-Digital Converter (ADC) inside the IC package scale this micro-current into a clean, calibrated digital I2C payload, bypassing the messy analog physics you have to manage manually with an LDR.
Analog vs. Digital: Choosing Your Sensor Module
When builders ask what the output of a photosensor actually is, the answer splits into two distinct categories. Conflating these is the most common cause of failed IoT light-meter projects.
- Analog Output (LDR / GL5528): The output is a voltage between 0V and VCC. An LDR alone cannot output voltage; it must be paired with a fixed resistor to form a voltage divider. The microcontroller reads this analog voltage via its ADC. Cost: ~$0.10 per unit.
- Analog Output (Phototransistor / TEMT6000): The output is a current that is converted to a voltage via an onboard pull-down resistor on the breakout board. It is faster and more linear than an LDR but still requires an ADC. Cost: ~$1.50.
- Digital Output (BH1750FVI): The output is a digital I2C data stream. The sensor handles the ADC conversion internally and outputs a 16-bit integer representing Lux. Cost: ~$2.50.
Wiring and Pinout Reference
Below is the standard wiring matrix for interfacing the most common hobbyist photosensors with an ESP32 DevKit V1. Always verify the voltage regulator on your specific breakout board; some cheap TEMT6000 boards lack a regulator and will fry at 5V.
| Sensor Module | Supply Range (VCC) | Output Type | ESP32 Pin Connection | Required External Components |
|---|---|---|---|---|
| GL5528 LDR (Bare) | 3.3V or 5V | Analog Voltage | GPIO 34 (ADC1_CH6) | 10kΩ pull-down resistor |
| TEMT6000 Breakout | 3.3V to 5.0V | Analog Voltage | GPIO 35 (ADC1_CH7) | None (onboard 10kΩ) |
| BH1750FVI (GY-302) | 3.0V to 5.0V | Digital I2C | GPIO 21 (SDA), GPIO 22 (SCL) | 4.7kΩ I2C pull-ups (usually onboard) |
Output Signal Math: Converting Raw Readings to Lux
Raw sensor data is useless for physical automation until you map it to a standard unit like Lux (lumens per square meter). Here is the exact math for both analog and digital interfaces.
1. Analog LDR (GL5528) Raw-to-Lux Math
The ESP32's 12-bit ADC returns a raw integer between 0 and 4095. Because the ESP32 ADC is notoriously non-linear at the extremes, keep your voltage divider midpoint near 1.65V for best accuracy.
- Convert Raw ADC to Voltage:
V_out = (ADC_raw / 4095.0) * 3.3 - Calculate LDR Resistance: Assuming a 10,000Ω (10kΩ) fixed pull-down resistor to GND, and the LDR connected to 3.3V:
R_ldr = 10000 * ((3.3 / V_out) - 1) - Calculate Lux: The GL5528 follows a log-log resistance curve. Using the standard datasheet approximation (where resistance at 10 Lux is ~50kΩ and gamma is ~0.79):
Lux = pow(10, (log10(R_ldr / 50000) / -0.79))
2. Digital BH1750FVI Raw-to-Lux Math
The BH1750 is vastly simpler. It outputs a 16-bit unsigned integer over I2C. According to the ROHM Semiconductor datasheet, the resolution in continuous high-resolution mode is 1 Lux, but the raw payload requires a scaling factor.
- Math:
Lux = Raw_16bit_Value / 1.2 - Example: If the I2C read returns
360, the ambient light is360 / 1.2 = 300 Lux(typical office lighting).
Calibration, Scaling, and Interference Sources
Even with perfect math, environmental interference will corrupt your readings if you do not design for it. Here is what you must account for on the bench.
Common Interference Sources
- AC Mains Flicker (100Hz/120Hz): Incandescent and cheap LED bulbs pulse at twice the AC line frequency. If your ESP32 samples the ADC at 150Hz, you will see massive sine-wave noise in your Lux readings. Fix: Add a 10µF electrolytic capacitor in parallel with the LDR's fixed resistor to create a low-pass hardware filter, or average 50 rapid software samples.
- Infrared (IR) Bleed: Bare CdS LDRs are highly sensitive to IR radiation. An LDR placed near a heat source or in direct sunlight will read artificially high Lux values because it is 'seeing' heat, not just visible light. Fix: Use a BH1750, which has an integrated IR-cut filter designed to match the human eye's photopic response curve.
- Temperature Drift: LDR resistance shifts with ambient temperature. If your sensor is inside a sealed outdoor enclosure that heats up to 50°C in the sun, your baseline dark-resistance will drift. Digital sensors like the BH1750 have internal temperature compensation and are immune to this.
For deep-dive ADC calibration techniques specific to the ESP32's non-linear curve, refer to the Espressif ADC Oneshot Driver Documentation, which details how to use the eFuse calibration values stored in the chip.
Frequently Asked Questions
What is a photosensor used for in home automation?
In home automation, photosensors are primarily used for daylight harvesting and circadian lighting control. An ESP32 reading a BH1750 can trigger motorized blinds to close when direct sunlight exceeds 10,000 Lux, or gradually ramp up warm-white LED strips as the ambient room light drops below 50 Lux at dusk. They are also used in security systems to distinguish between a shadow and a genuine beam-break event.
What is the difference between a photosensor and a photodiode?
'Photosensor' is a broad umbrella term for any device that detects light, including LDRs, phototransistors, and digital ICs. A 'photodiode' is a specific type of semiconductor component that operates in reverse-bias to generate a highly linear, ultra-fast micro-current when struck by photons. While all photodiodes are photosensors, not all photosensors are photodiodes. Photodiodes are used in high-speed fiber optics and medical pulse oximeters, whereas LDRs are used for slow, basic ambient light detection.
Why is my ESP32 photosensor reading fluctuating wildly?
Wild fluctuations on an ESP32 analog photosensor are almost always caused by the ESP32's internal ADC noise or 50/60Hz AC flicker from room lighting. The ESP32's SAR ADC is noisy by default. To fix this, first add a 0.1µF ceramic capacitor directly across the ADC input pin and GND. Second, implement a software moving-average filter in your Arduino code, discarding the top and bottom 10% of a 20-sample window before calculating the final Lux value. If using I2C (BH1750), fluctuations usually indicate missing pull-up resistors on the SDA/SCL lines or a loose breadboard connection.






