Turn on LED in Low Light with Pico

In this exercise, we'll control an LED based on ambient light levels using an LDR. The goal is to automatically turn on the LED in low light conditions - creating an automatic night light.

Hardware Requirements

Circuit Connection

LDR Circuit:

  1. One side of the LDR connects to AGND (Analog Ground)
  2. The other side connects to GPIO26 (ADC0)
  3. A 10kΩ resistor connects between GPIO26 and ADC_VREF (3.3V)

LED Circuit:

Pico 2 W Note: GPIO 23, 24, 25, and 29 are reserved for wireless. Don't use GPIO25 for the LED like on standard Pico 2.

Code Implementation

rust
use embassy_rp::adc::{Adc, Channel};
use embassy_rp::gpio::{Level, Output, Pull};
use embassy_time::Timer;

const LIGHT_THRESHOLD: u16 = 3800;

#[embassy_executor::main]
async fn main(_spawner: Spawner) {
    let p = embassy_rp::init(Default::default());
    
    // Initialize ADC for LDR
    let mut adc = Adc::new(p.ADC, Irqs, Config::default());
    let mut p26 = Channel::new_pin(p.PIN_26, Pull::None);
    
    // Initialize LED
    let mut led = Output::new(p.PIN_15, Level::Low);
    
    loop {
        // Read light level
        let level = adc.read(&mut p26).await.unwrap();
        
        // Turn on LED in darkness
        if level > LIGHT_THRESHOLD {
            led.set_high();
        } else {
            led.set_low();
        }
        
        Timer::after_secs(1).await;
    }
}

How It Works

The code reads the ADC value from the LDR every second. When the ADC value exceeds the threshold (indicating low light), the LED turns on. In bright conditions, the LED stays off. You may need to adjust the LIGHT_THRESHOLD value based on your room lighting and specific LDR.

Testing

Try this in a room by turning lights on and off. Cover the LDR with your hand to simulate darkness - the LED should turn on. Uncover it, and the LED should turn off. Adjust the threshold value if needed for better sensitivity.