🔦 Level 2 – Sensors & IR Control

Project 2.2: "Ambient Light Sensor"

 

🚀 Project 2.2 – Ambient Light Sensor


🎯 What You’ll Learn

  • ✅ Goal 1: Read ambient light levels with a photoresistor.
  • ✅ Goal 2: Use thresholds to trigger LEDs.
  • ✅ Goal 3: Control motors based on light intensity.
  • ✅ Goal 4: Build a mini light station.

Key Ideas

  • Analog input: Read sensor values.
  • Logic: Compare values with thresholds.
  • Outputs: LEDs or motors respond.
  • Serial print: Monitor sensor readings.

🧱 Blocks Glossary (used in this project)

  • adcX = machine.ADC(machine.Pin(X)) → Setup analog input.
  • adcX.atten(machine.ADC.ATTN_11DB) → Configure attenuation.
  • adcX.width(machine.ADC.WIDTH_12BIT) → Configure resolution.
  • adcX.read() → Read sensor value.
  • pinX = machine.Pin(X, machine.Pin.OUT) → LED or motor output.
  • pinX.value(1) → Turn ON output.
  • pinX.value(0) → Turn OFF output.
  • time.sleep() → Delay.

🧰 What You Need

PartHow many?Pin connection
D1 R321USB cable
Photoresistor KY‑0181Pin 32 (analog input)
LED1Pin 5
Motor (optional)1Pin 12, Pin 13, Pin 14

✅ Before You Start

  • USB cable connected
  • Sensor wired correctly
  • Test print shows:
print("Ready!")  # Confirm serial is working

🎮 Microprojects (5 Mini Missions)


🎮 Microproject 2.2.1 – Ambient light reading

Blocks used: Analog input, Serial print
Block sequence:

  1. Setup photoresistor
  2. Read value
  3. Print reading

MicroPython Code:

import machine, time                          # Import modules

adc32 = machine.ADC(machine.Pin(32))          # Photoresistor on pin 32
adc32.atten(machine.ADC.ATTN_11DB)            # Configure attenuation
adc32.width(machine.ADC.WIDTH_12BIT)          # Configure resolution

while True:                                   # Infinite loop
    value = adc32.read()                      # Read sensor value
    print("Light level:", value)              # Serial log
    time.sleep(0.5)                           # Delay

Reflection: Sensor values show ambient light intensity.
Challenge: Try faster refresh (0.2s).


🎮 Microproject 2.2.2 – Automatic night light LED

Blocks used: Analog input, Digital output, Logic
Block sequence:

  1. Setup sensor + LED
  2. If light < threshold → LED ON

MicroPython Code:

import machine, time                          # Import modules

adc32 = machine.ADC(machine.Pin(32))          # Photoresistor input
adc32.atten(machine.ADC.ATTN_11DB)
adc32.width(machine.ADC.WIDTH_12BIT)

pin5 = machine.Pin(5, machine.Pin.OUT)        # LED output

while True:
    value = adc32.read()                      # Read sensor value
    print("Light level:", value)              # Serial log
    if value < 1000:                          # Threshold for darkness
        pin5.value(1)                         # LED ON
        print("Night detected: LED ON")
    else:
        pin5.value(0)                         # LED OFF
        print("Day detected: LED OFF")
    time.sleep(0.5)

Reflection: LED turns ON automatically in darkness.
Challenge: Adjust threshold for your environment.


🎮 Microproject 2.2.3 – Configurable light thresholds

Blocks used: Analog input, Logic, Serial input
Block sequence:

  1. Setup sensor
  2. Read threshold from user
  3. Compare values

MicroPython Code:

import machine, time                          # Import modules

adc32 = machine.ADC(machine.Pin(32))          # Photoresistor input
adc32.atten(machine.ADC.ATTN_11DB)
adc32.width(machine.ADC.WIDTH_12BIT)

pin5 = machine.Pin(5, machine.Pin.OUT)        # LED output

threshold = int(input("Enter threshold: "))   # User sets threshold

while True:
    value = adc32.read()                      # Read sensor value
    print("Light level:", value)
    if value < threshold:                     # Compare with threshold
        pin5.value(1)                         # LED ON
        print("LED ON")
    else:
        pin5.value(0)                         # LED OFF
        print("LED OFF")
    time.sleep(0.5)

Reflection: Threshold configurable by user.
Challenge: Try different thresholds.


🎮 Microproject 2.2.4 – Motor control by light intensity

Blocks used: Analog input, PWM, Logic
Block sequence:

  1. Setup sensor + motor
  2. Map light intensity to motor speed

MicroPython Code:

import machine, time                          # Import modules

adc32 = machine.ADC(machine.Pin(32))          # Photoresistor input
adc32.atten(machine.ADC.ATTN_11DB)
adc32.width(machine.ADC.WIDTH_12BIT)

pin12 = machine.Pin(12, machine.Pin.OUT)      # Motor IN3
pin13 = machine.Pin(13, machine.Pin.OUT)      # Motor IN4
pwm14 = machine.PWM(machine.Pin(14))          # Motor ENB PWM

pwm14.freq(2000)                              # Motor frequency
pin12.value(1); pin13.value(0)                # Motor forward

while True:
    value = adc32.read()                      # Read sensor value
    speed = int(value / 4)                    # Map 0–4095 to 0–1023
    pwm14.duty(speed)                         # Set motor speed
    print("Light:", value, "Speed:", speed)   # Serial log
    time.sleep(0.5)

Reflection: Motor speed changes with light intensity.
Challenge: Try different mapping formulas.


🎮 Microproject 2.2.5 – Ambient light station

Blocks used: Analog input, Serial print, Digital output
Block sequence:

  1. Setup sensor + LED
  2. Print readings continuously
  3. LED indicates low light

MicroPython Code:

import machine, time                          # Import modules

adc32 = machine.ADC(machine.Pin(32))          # Photoresistor input
adc32.atten(machine.ADC.ATTN_11DB)
adc32.width(machine.ADC.WIDTH_12BIT)

pin5 = machine.Pin(5, machine.Pin.OUT)        # LED output

while True:
    value = adc32.read()                      # Read sensor value
    print("Ambient light station:", value)    # Serial log
    if value < 800:                           # Threshold
        pin5.value(1)                         # LED ON
        print("Low light alert: LED ON")
    else:
        pin5.value(0)                         # LED OFF
        print("Light OK: LED OFF")
    time.sleep(1)

Reflection: Station monitors light and alerts with LED.
Challenge: Add buzzer for stronger alert.


✨ Main project – Ambient light sensor

🔧 Blocks steps (with glossary)

  • Analog input: Read photoresistor with adc32.read().
  • Logic: Compare readings with thresholds.
  • Digital output: LED ON/OFF with pin5.value(1/0).
  • PWM output: Motor speed with pwm14.duty(value).
  • Serial print: Monitor values in terminal.

🐍 MicroPython code (mirroring blocks, comentarios línea por línea)

# Project 2.2 – Ambient Light Sensor

import machine, time                          # Importa módulos: machine para pines/ADC, time para delays

adc32 = machine.ADC(machine.Pin(32))          # Configura ADC en pin 32 para el fotoresistor
adc32.atten(machine.ADC.ATTN_11DB)            # Atenuación 11 dB para rango amplio de voltaje
adc32.width(machine.ADC.WIDTH_12BIT)          # Resolución a 12 bits (0–4095)

pin5 = machine.Pin(5, machine.Pin.OUT)        # LED en pin 5 como salida digital

pin12 = machine.Pin(12, machine.Pin.OUT)      # Motor IN3 (dirección) como salida
pin13 = machine.Pin(13, machine.Pin.OUT)      # Motor IN4 (dirección) como salida
pwm14 = machine.PWM(machine.Pin(14))          # Motor ENB (velocidad) con PWM en pin 14

pwm14.freq(2000)                              # Fija frecuencia PWM a 2000 Hz
pin12.value(1)                                # Configura motor hacia adelante: IN3 HIGH
pin13.value(0)                                # Configura motor hacia adelante: IN4 LOW

dark_threshold = 900                          # Umbral para “poca luz” (ajustable)
print("Ambient Light Main Project Ready")     # Mensaje de inicio por serial

while True:                                   # Bucle infinito
    value = adc32.read()                      # Lee nivel de luz (0–4095)
    print("Light:", value)                    # Muestra el valor por serial

    if value < dark_threshold:                # Si hay poca luz según umbral
        pin5.value(1)                         # Enciende LED (luz nocturna)
        print("LED ON (night)")               # Mensaje por serial
    else:                                     # Si hay suficiente luz
        pin5.value(0)                         # Apaga LED
        print("LED OFF (day)")                # Mensaje por serial

    speed = int(value / 4)                    # Mapea 0–4095 a 0–1023 para PWM
    pwm14.duty(speed)                         # Ajusta velocidad del motor con PWM
    print("Motor speed (duty):", speed)       # Muestra velocidad por serial

    time.sleep(0.5)                           # Pequeño delay para estabilidad

📖 External explanation

Este proyecto integra lectura analógica, comparación con umbrales y control de salidas. El fotoresistor mide brillo, el LED indica noche/día y el motor ajusta su velocidad según la intensidad de luz. Con impresiones por serial, los estudiantes observan el ciclo completo de percepción y acción.


🕵️ Debugging (2 common problems)

🐞 Debugging 2.2.A – Out-of-range values

  • Problema: Lecturas solo 0 o 4095.
  • Causas: Cableado incorrecto o atenuación inadecuada.
  • Arreglo:
    adc32 = machine.ADC(machine.Pin(32))          # Verifica pin correcto
    adc32.atten(machine.ADC.ATTN_11DB)            # Usa 11 dB para rango amplio
    adc32.width(machine.ADC.WIDTH_12BIT)          # Asegura 12 bits
    
  • Por qué funciona: Rango y resolución correctos estabilizan la lectura.

🐞 Debugging 2.2.B – Slow response

  • Problema: Cambios de luz tardan en reflejarse.
  • Causas: Delay demasiado largo.
  • Arreglo:
    time.sleep(0.2)   # Reduce el delay para refresco más rápido
    
  • Por qué funciona: Mayor frecuencia de lectura mejora la sensibilidad percibida.

✅ Final checklist

  • Wiring verificado: Fotoresistor a pin 32 (ADC), LED a pin 5, motor a 12/13/14.
  • Atenuación y resolución configuradas: ATTN_11DB, WIDTH_12BIT.
  • Umbral funcional: LED responde a luz ambiental.
  • PWM activo: Motor ajusta velocidad según luz.
  • Serial útil: Lecturas y estados visibles.

📚 Extras

  • Tip estudiante: Cambia dark_threshold para adaptar el sistema a tu aula.
  • Tip docente: Muestra cómo el mapeo value/4 convierte 0–4095 a 0–1023.
  • Glosario: Analog input, threshold, PWM, duty cycle.
  • Mini tip: Prueba primero solo el ADC y print(value) antes de añadir LED/motor.
On this page