Skip to content

Light Sensor

Sensors Need Calibration

You read the light sensor:

>>> light_sensor.read_u16()
47832   # What does this mean?

Cover the sensor: 61234. Shine a flashlight: 8921.

The value goes DOWN when it's brighter. This isn't a bug - it's how this particular sensor works. A photoresistor in a voltage divider produces higher voltage in darkness (high resistance) and lower voltage in brightness (low resistance).

Raw values are not measurements. To use this sensor, you must:

  1. Understand the hardware: This sensor outputs high voltage for dark, low for bright
  2. Calibrate: What values correspond to your "dark" and "bright"?
  3. Normalize: Convert raw values to a useful scale (0-100%, lux, etc.)
# Calibration values (measure these for YOUR environment)
DARK_VALUE = 62000   # Covered sensor
BRIGHT_VALUE = 5000  # Direct light

def light_percent(raw):
    # Invert and scale to 0-100%
    return (DARK_VALUE - raw) / (DARK_VALUE - BRIGHT_VALUE) * 100

Without calibration, sensor readings are arbitrary numbers.


The light sensors are based on photoresistors and function as voltage dividers. Each sensor consists of a photoresistor as the lower component and a fixed-value resistor as the upper component in the voltage divider circuit. The photoresistor is sensitive to visible light, with its resistance changing depending on illumination.

In complete darkness, the photoresistor has a very high resistance in the megaohm (MΩ) range, causing the voltage divider to output approximately 3.3V. As the light intensity increases, the photoresistor’s resistance decreases to a few hundred ohms, reducing the output voltage to just a few hundred millivolts (mV).

The following diagram illustrates the sensor’s design:


Light Sensors

The light sensors are connected to the microcontroller as follows:

  • Light Sensor 1 (LIGHT_SENSE) → GP27 (ADC1 channel) via J7 jumper
  • Light Sensor 2 (LIGHT_SENSE1) → GP26 (ADC0 channel)

Important:

  • Light Sensor 1 is only available when the J7 jumper is set to the Feature Selection – Light position on the red jumpers, as shown below:


Feature Selection - J7 jumper in light position


⚡Hands-on tasks

✅ Task 1 - Reading light sensor analog values

Building on the previous example where we used the ADC to read the temperature sensor value, we will now read values from two light sensors using the ADC.

Example: Reading Light Sensor Values

from machine import Pin, ADC
import time

# --- Configuration ---

VREF = 3.3  # Referernce voltage 3.3V

adc_pin_left = Pin(26)      # light sensor on GP26
adc_pin_right = Pin(27)     # light sensor on GP27

light_sensor_left = ADC(adc_pin_left)
light_sensor_right = ADC(adc_pin_right)


while True:

    adc_light_left = light_sensor_left.read_u16()  # Read raw ADC value
    print("ADC Value left:", adc_light_left)

    adc_light_right = light_sensor_right.read_u16()  # Read raw ADC value
    print("ADC Value right:", adc_light_right)

    time.sleep(0.5)  # Wait 500ms before the next reading

🔍 Try to Define the Minimum and Maximum Values

Before converting the raw ADC values to percentages, it is important to define and adjust the minimum and maximum values for more accurate scaling. The raw ADC readings may vary based on sensor placement, ambient light conditions, and hardware variations.

Steps:

  1. Identify the minimum and maximum ADC values by observing the readings:
    • Minimum value: Cover the sensor completely (e.g., with your hand).
    • Maximum value: Shine a torch (flashlight) directly onto the sensor.
  2. Use these values to normalize the percentage calculation, ensuring that 0% represents complete darkness and 100% represents maximum brightness.

✅ Task 2 - Converting Light Sensor Values to Percentage

Instead of using raw ADC values, we will now convert the light sensor readings into a percentage (0-100%), making them easier to interpret and more useful for applications.

Objective:

  • Define minimum and maximum ADC values for better calibration.
  • Create a function that normalizes ADC values to a percentage (0-100%).
  • Print the calibrated light intensity percentage instead of raw ADC readings.
Tip

The conversion formula is: $$ \text{Light Intensity} (\%) = \frac{\text{ADC Value}}{65535} \times 100 $$

Observe how the light intensity percentage changes when shading or exposing the sensors to light.


➡ Next Steps