Raspberry Pi Pico W Deep Sleep with WiFi Radio Control

Last Updated on 4th October 2023 by nightowl

I’ve recently started messing about with a new to me Raspberry Pi Pico W instead of my usual go to Arduinos. My first project is a portable wireless temperature and humidity sensor that can send its data to a time series database over WiFi. It will only do so every minute or so it doesn’t make sense to have everything draining the batteries all the time.

This presented a challenge a lot of people seem to have struggled with: How to power down the WLAN radio with MicroPython. I spent hours trying out different suggestions I found online but none of them seemed to quite work. Some more tinkering and hacking on my own I finally have something I could call a success.

As I said in the beginning I’m pretty new to the Pico W so what works for me, might not work for you. Thought I’d share my solution here anyway.

The Code

Here’s what my test code does:

  • Grab the GPIO23 pin as an output and set it high. This is internally connected to the WL_ON signal.
  • Blink the built-in led rapidly a few times to indicate start of the program
  • Connect to WLAN
  • Blink the built-in led slowly a few times to indicate successful WLAN connection
  • Disconnect and deactivate WLAN and wait for a few seconds for it to happen!
  • Set the GPIO23 pin low to turn off the WLAN radio.
  • Enter deep sleep mode for 60s.

This seems to give me a sleep mode with power consumption of only a couple of mA. I tried using the wlan.deinit() method that supposedly powers down the WLAN radio but for me it messed up the deep sleep and caused it to wake up immediately. Same also happened if I didn’t add wait after the disconnect/deactivate as well.

Here’s the full test code:

import machine
import utime
import network

ssid = 'YOUR-SSID'
password = 'YOUR-WLAN-PASSWORD'

def connet_wlan():
    wlan_en = machine.Pin(23, machine.Pin.OUT)  # Pico W WiFi enable pin
    wlan_en.value(True)                         # Turn WiFi on

    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)

    max_wait = 10
    while max_wait > 0:
        if wlan.status() < 0 or wlan.status() >= 3:
            break
        max_wait -= 1
        print('Connecting to %s...' % ssid)
        utime.sleep(3)

    if wlan.status() != 3:
        print('WLAN connection failed')
        dsleep(60000, wlan, wlan_en)
    else:
        status = wlan.ifconfig()
        print('Connected to %s (%s)' % (ssid, status[0]))

    return wlan, wlan_en

def dsleep(time_ms, wlan, wlan_en):
    if wlan != None:
        print("Disconnecting and deactivating wlan.")
        wlan.disconnect()
        wlan.active(False)
        utime.sleep(5)
        # wlan.deinit() # causes deepsleep to wake up immediately!
        if wlan_en != None:
            print("Turning off wlan radio.")
            wlan_en.value(False)

    print("Sleeping for %d ms." % time_ms)
    machine.deepsleep(time_ms)

if __name__ == "__main__":
    led = machine.Pin('LED', machine.Pin.OUT)

    for i in range(3):
        led.value(True)
        utime.sleep(.1)
        led.value(False)
        utime.sleep(.1)

    wlan, wlan_en = connet_wlan()
    for i in range(3):
        led.value(True)
        utime.sleep(1)
        led.value(False)
        utime.sleep(1)

    dsleep(60000, wlan, wlan_en)

Leave a Reply

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