Pico W WiFi connection dropouts

Hi Brains Trust.

I have several Pico W’s publishing sensor data via mqtt to the io.adafruit network.

It all works well, except the WiFi connection drops out on a regular basis. Sometimes it will go for a week and other times just a day or even hours. All of the Pico W’s do the same.

I have tried on several unrelated AP’s and they all do the same.

Can additional code be inserted to automatically re-establish the connection or perhaps some form of watch dog timer to reset the connection if it fails?

Also… the last line of the code is commented out because the Pico crashes with it left in. Any ideas on that?

Code I used is below.

Kind regards

Maarten

import network
import time
from PiicoDev_TMP117 import PiicoDev_TMP117
from umqtt.simple2 import MQTTClient

# Fill in your WiFi network name (ssid) and password here:
wifi_ssid = "SSID"
wifi_password = "password"

# Connect to WiFi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(wifi_ssid, wifi_password)
while wlan.isconnected() == False:
    print('Waiting for connection...')
    time.sleep(1)
print("Connected to WiFi")

tempSensor = PiicoDev_TMP117() # initialise the sensor


# Fill in your Adafruit IO Authentication and Feed MQTT Topic details
mqtt_host = "io.adafruit.com"
mqtt_username = "username"  # Your Adafruit IO username
mqtt_password = "password"  # Adafruit IO Key
mqtt_publish_topic = "topic"  # The MQTT topic for your Adafruit IO Feed

# Enter a random ID for this MQTT Client
# It needs to be globally unique across all of Adafruit IO.
mqtt_client_id = "clientID"

# Initialize our MQTTClient and connect to the MQTT server
mqtt_client = MQTTClient(
        client_id=mqtt_client_id,
        server=mqtt_host,
        user=mqtt_username,
        password=mqtt_password)

mqtt_client.connect()

# Publish a data point to the Adafruit IO MQTT server every n seconds

try:
    while True:
               
        
        # Read and print the temperature in various units
        tempC = tempSensor.readTempC() # Celsius
        
        
            
        # Publish the data to the topic!
        print(str(tempC))
        #print(str(tempC) + " °F")
        mqtt_client.publish(mqtt_publish_topic, str(tempC))
        
        # Delay a bit to avoid hitting the rate limit
        time.sleep(300)
except Exception as e:
    print(f'Failed to publish message: {e}')
finally: tempC
         #mqtt_client.disconnect()
1 Like

Hi @Maarten51500

Welcome to the forums :slight_smile:

There surely must be a way.
If the connection fails, does does your code walk into this catch block below.
i.e. does that “Failed to publish” print line run?

except Exception as e:
    print(f'Failed to publish message: {e}')
1 Like

I found similar behavior when running mine when I started. Most of the documentation and examples I found online were similar format to the code you have posted.

In reality, the examples themselves are not suitable for anything more than a happy path, which becomes less likely to be happening the longer the device is running. Interference can bust connections even if your AP is up an singing to the world with a 100% uptime.

What is needed is more resilient solutions. Something which checks that the network connection is up and possibly, also manages the broker connection too. I am using MQTT on a Pi Zero on my local network. I am not familiar with the Adafruit offering, you will be able to tweak as needed of course.

import time
import network

# Global Wi-Fi credentials
WIFI_SSID = "ItWouldBeCreepyIfIKnewThis"
WIFI_PASSWORD = "CreepierStill12345!"

def connect_to_wifi():
    # Check if already connected
    if wifi.status() != 3:
        print("re-connecting to Wi-Fi...")
        wifi.connect(WIFI_SSID, WIFI_PASSWORD)
        
        # Wait for connection
        while not wifi.isconnected():
            pass
        
        print("Connected to Wi-Fi")

# Counter value
counter = 0

#initiaize wifi
wifi = network.WLAN(network.STA_IF)
wifi.disconnect()
wifi.active(True)
wifi.connect(WIFI_SSID, WIFI_PASSWORD)

# wifi connect or fail
max_wait = 10
while max_wait > 0:
    if wifi.status() < 0 or wifi.status() >= 3:
        break
    max_wait -= 1
    print('waiting for connection...')
    time.sleep(1)

print('Initial connection complete')
if wifi.status() != 3:
    raise RuntimeError('network connection failed.')
else:
    print("Connected to {} channel {} with address {}".format(WIFI_SSID,wifi.config('channel'), wifi.ifconfig()[0]))


try:
    while True:
        # Connect to Wi-Fi if not connected
        connect_to_wifi()
       
        try:
            print("connect to the broker")
            print("read a sensor")
            print("publish message")
            print('client.disconnect()')             

        finally:
            print("nap like a sleepy thing")
            time.sleep(5)

except Exception as e:
    print("Error:", e)


You can try the above standalone to try on your network then add the real stuff as you need. I have used this to test sending temperature data to Apple kit via HomeBridge and it worked. I’ve since shifted to a LiPo battery and a power hat. It was running like this for a good few weeks, where you need fast polling, you would need to keep something like this going I imagine.

Good Luck!

3 Likes

Hey Marten,

I’ve ran into similar issues with my Pico W’s that I’ve been using for some mini IoT projects recently. Using a try-except and calling machine.reset() to restart the Pico and re-establish the connection has been the most effective way I’ve found to deal with it.

I found the further I took the Pico from the wireless AP the more consistently it’d drop the network connection, I’d reckon the Niche™ antenna that is onboard doesn’t have much gain and isn’t very suitable for omnidirectional use. Aligning the Pico to the same plane in space as your AP’s antenna/s may help.

Unfortunately it’s one of the only parts of the board that doesn’t have open specs and datasheets:

I hope this helps!

p.s. Section 3.8 in the datasheet above provides some extra tips for more reliable wireless network connections on the Pico.

Specs for the onboard cyw43439 available below for anyone curious: