Maketober Day 11: PIR controlled ESP32

PIR light.png

I’ve been playing with PIR sensors. In this crazy world you can pick up five of them for around ten pounds. You can see one in the picture above. It’s the half bubble right in the middle of the frame. These trigger when they see something warm blooded walk past. They are used in burglar alarms and the like. I bought a bunch to play with. I want to make a PIR controlled nightlight that comes on when you walk past it. I’m going to use Neopixels as the light source.

The PIR sensor has an output pin that goes high when it sees someone go past. You can use the little orange trimmers on the device to adjust the sensitivity of the detector and how long it stays on once it has been triggered. You can also make the output signal a pulse or stay high as long as it detects something by moving the yellow jumper on the board.

I’d really like the whole thing to be battery powered. According to its data sheet the PIR sensor only sips tiny amounts of current, but this is not true for the ESP32 I’m using to control everything. The good news is that the ESP32 can be made to go into “deep sleep” mode in which most of the processor shuts down. We can use the trigger signal to wake up the processor when it sees someone. The ESP32 can then turn the light on and even log the detection over the network using MQTT or whatever. I’ve been playing with some code to make this work and I’ve come up with the following:

def startup():
    global np,pin,n
    if machine.reset_cause() == machine.DEEPSLEEP_RESET:
        # we can do stuff here when the PIR was triggered
        print('woke from a deep sleep')
    else:
        print('not been sleeping')
    # PIR on GPIO 4
    pin = machine.Pin(4, machine.Pin.IN)
    # configure to wake up ESP32 when the PIR is triggered
    esp32.wake_on_ext0(pin,esp32.WAKEUP_ANY_HIGH)
    # put the ESP32 to sleep
    print("Going to sleep")
    machine.deepsleep()

This MicroPython function can be added to a program that runs when the device is booted. In other words, you could put a call of startup() into the file boot.py

It checks to see if the ESP32 was woken from a deep sleep (i.e. the PIR triggered the restart. You can put whatever code you want to run in that part of the code. Then it configures pin GPIO4 as an input and tells the ESP32 to wake when this input goes high. Then it puts the ESP 32 into deep sleep.

I’ve tested it and it seems to work. The only problem is that not all ESP32 devices are equal as far as deep sleep power consumption is concerned. The DOIT board that I’m using leaves all the USB hardware switched on when it goes to sleep, which means that it still consumes quite a bit of power. If you want to do this kind of thing with an ESP32 I strongly recommend the DFRobot FireBeetle which only takes tiny amounts of power in sleep mode. Once I’ve made the code work I’ll move onto that platform.