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)

3 thoughts on “Raspberry Pi Pico W Deep Sleep with WiFi Radio Control

  1. Renaud F5ZR says:

    Hi,
    This is only two years old so I suppose I can ask?
    It is exactly what I need for a little project.
    I could not resist trying on a Pico2 W.
    I got this for which any comment would be gratefully received!
    Thanks fo the code.
    Renaud (F5ZR)
    MPY: soft reboot
    Connecting to Livebox-72E0…
    Connected to Livebox-72E0 (192.168.1.14)
    Disconnecting and deactivating wlan.
    Turning off wlan radio.PROBLEM IN THONNY’S BACK-END: Exception while handling ‘Run’ (ConnectionError: read failed: [Errno 6] Device not configured).
    See Thonny’s backend.log for more info.
    You may need to press “Stop/Restart” or hard-reset your MicroPython device and try again.

    Process ended with exit code 1.
    Couldn’t find the device automatically.
    Check the connection (making sure the device is not in bootloader mode) or choose
    “Configure interpreter” in the interpreter menu (bottom-right corner of the window)
    to select specific port or another interpreter.

    Process ended with exit code None.

    Reply
    1. nightowl says:

      In the end I had too many problems with trying to enter a low power mode after sending the data and then wake up again for the next update, I decided to ditch the idea and just have my device connected all of the time. It’s a shame but I just could not get it to work reliably for long term…

      Reply
  2. Renaud F5ZR says:

    Ok. Thanks anyway. And thanks for your answer.
    Good nights!
    Renaud

    Reply

Leave a Reply to Renaud F5ZR Cancel reply

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