Who goes where? A motion triggered night light for the Raspberry Pico

A small helper at night and a nice little excercise on the Pico: an LED that lights up when it is dark and something moves.

I used a HC-SR501 as motion sensor, light sensor with digital output, a yellow LED of my Pico project complete kit (330 Ohm resistor with it) and of course the Raspberry Pico. I already hat soldered in the header pins of the Pico and was good to go for the prototype. The light and motion sensor both run on 5V, so I connected it to the breadboard and with some Dupont and jumper cables the setup was done.
These are standard links to berrybase – no affiliation or partnership with them. I just buy my stuff there.

Please note that both sensors also have poteniometers with screwdriver holes to adjust them. Both can be adjusted for sensibility and the motion sensor also has one for trigger duration. The sensibility settings won’t interfere with the program code as they are digital and we just react when the sensor tell us it is triggered. The trigger duration of the motion sensor has a range from 5 to 200 seconds and does or at least can affect the outcome. If it is set manually to 200 seconds it won’t change it’s value when you check it mor often in the software. I prefer to set it to its minimum so that it affects the expected reaction time in the software as little as possible.

The general goal of the implementation is to wait until the light sensor says that it is dark enough to trigger the LED. Then wait for a signal of the motion sensor and turn on the LED for a specific time (default is 30 seconds). As long there is registered motion the LED is kept on and it is checked again after the trigger interval.

The LED itself influences the brightness of the surrounding (as it is expected to do!), it can also trigger the light sensor to tell us it is not dark enough to turn on the night light and switch itself off again. Therefore the light sensor acts as a precondition and is not considered when motion is registered and the LED is on.

Enough text – here are some pictures of the working prototype and the program code on github.
Have fun with your own sensor controlled night light!

https://github.com/worksonmymachine-de/pico_nightmotionlight/blob/main/sensor_night_light_vanilla.py
This is the code for the small project using just MicroPython without additional modules or classes.

from machine import Pin
import machine
from time import sleep

class SensorNightLight:

    def __init__(self, led_pin=4, light_pin=27, motion_pin=28, trigger_interval=1, trigger_duration=30):
        self.led = Pin(led_pin, Pin.OUT)
        self.light = Pin(light_pin, Pin.IN, Pin.PULL_DOWN)
        self.motion = Pin(motion_pin, Pin.IN, Pin.PULL_DOWN)
        self.trigger_interval = trigger_interval
        self.trigger_duration = trigger_duration
        self._loop()

    def _loop(self):
        while True:
            print("light sensor TRIGGERED") if self.light.value() == 1 else print("light sensor SLEEPING")
            print("motion sensor TRIGGERED") if self.motion.value() == 1 else print("motion sensor SLEEPING")
            if self.light.value() == 1:
                print("dark enough - waiting for motion")
                while self.motion.value() == 1:
                    print(f"motion sensor triggered - LED on and checking again in {self.trigger_duration}")
                    self.led.high()
                    sleep(self.trigger_duration)  
            self.led.low()
            sleep(self.trigger_interval)
    

if __name__ == "__main__":
    SensorNightLight()

As IDE I used Thonny as for all of my Pico projects until now. Check it out here: thonny.org. It’s easy to use and has sufficient functionality for small projects. You can use the Pico interpreter (among others, CircuitPython is also supported), deploy and run on the device or locally in the Thonny Python environment. You search, add and remove modules in Thonny (uses PyPi), which are deployed to device, too. It also has a dark mode for us sunglass-wearing basement vampires 😛
The thing I miss the most is jumping into other modules with [Ctrl]+[Click] when editing code directly on the Pico to see what methods do and what parameters they are expecting. Works fine when using the Thonny built-in interpreter.

Thonny IDE – edit view
Typical shell output of the script in Thonny

As I like clean, readable code very much, I played around and wrote a Led and Sensor class with more readable methods. It’s in the same github repository.

from machine import Pin
import machine
from time import sleep

class Sensor:
    def __init__(self, pin, pull_down=True):
        self._sensor = Pin(pin, Pin.IN, Pin.PULL_DOWN if pull_down else Pin.PULL_UP)

    def isTriggered(self):
        return self._sensor.value() == 1
    
    def isNotTriggered(self):
        return not self.isTriggered()
    
    
class Led:
    def __init__(self, pin, init_state_off=True, blink_delay=0.5):
        self._led = Pin(pin, Pin.OUT)
        self._blink_delay = blink_delay
        self._led.off() if init_state_off else self._led.on()

    def on(self):
        if self.isOff():
            self._led.high()

    def off(self):
        if self.isOn():
            self._led.low()

    def isOn(self):
        return self._led.value() == 1
    
    def isOff(self):
        return not self.isOn()
    
    def toggle(self):
        self._led.off() if self.isOn() else self.on()
        
    def blink(self):
        self.on()
        self._blink_delay()
        self.off()
        
    def smart_blink(self):
        self.toggle()
        self._blink_delay()
        self.toggle()
        
    def _blinkDelay(self):
        sleep(self._blink_delay)


class SensorNightLight:

    def __init__(self, led_pin=4, light_pin=27, motion_pin=28, trigger_interval=1, trigger_duration=30):
        self.led = Led(led_pin)
        self.light = Sensor(light_pin)
        self.motion = Sensor(motion_pin)
        self.trigger_interval = trigger_interval
        self.trigger_duration = trigger_duration
        self._loop()

    def _loop(self):
        while True:
            print("light sensor TRIGGERED") if self.light.isTriggered() else print("light sensor SLEEPING")
            print("motion sensor TRIGGERED") if self.motion.isTriggered() else print("motion sensor SLEEPING")
            if self.light.isTriggered():
                print("dark enough - waiting for motion")
                while self.motion.isTriggered():
                    print(f"motion sensor triggered - LED on and checking again in {self.trigger_duration}")
                    self.led.on()
                    sleep(self.trigger_duration)  
            self.led.off()
            sleep(self.trigger_interval)
    

if __name__ == "__main__":
    SensorNightLight()

I will keep you posted when I move the prototype from the breadboard to PCB with casing. Use case will probably be under the bed – let’s not wake the queen when you have to get up at night 😛 A very subtle light like this one should be enough and you dont have to turn any light on or off yourself.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.