Give your Raspberry Pi Pico a WiFi upgrade with the ESP32 WiFi co-processor and get connected with this CircuitPython setup guide. With an example of sending data with MQTT.

 The Raspberry Pi Pico RP2040 micro controller is a good option for projects but if you need wifi connectivity you will need to use a different micro controller with WiFi or you can make you project with a Raspberry Pi Zero or RPi4.

The other option is to get a ESP32 WiFi co-processor. The ESP32 is a complete module which handles all the wifi connectivity leaving the Pico just to handle the data that is being transmitted. 

I have the ESP32spi which can communicate with WiFi or Bluetooth and uses a SPI connection to connect to the Pico. For this guide I will go through how to setup the Pico with a WiFi connection using CircuitPython. 

ESP32 WiFi RaspberryPi Pico


For writing scripts in Python the Pico can use either Micropython or CircuitPython. These are both supplied in firmware that is installed to the Pico which means you have to set the Pico up with one or the other language.

For Python programs the Pico can be setup with Micropython or CircuitPython. The firmware needs to be installed to use the chosen version so the Pico can only be setup with one or the other.

I'm using CircuitPython, you can find the firmware for the Pico here

In addition the libraries will need to be downloaded to a computer which you use to transfer the required libraries to the Pico as you need them.

Once the Pico has the firmware installed and a usb cable is plugged into a computer, there will be a new drive on your computer called CIRCUITPY. This is where you create your program. Any required libraries should be copied to the lib folder.

Setting up the ESP32 WiFi

The ESP32spi has 12 connections. For this guide these are the connections to the Pico.

  • Vin 3.3v - 5v - 250ma required for WiFi use. (Pin Position 40)
  • 3v Out - upto 50ma for other devices (not used)
  • GND - Ground (Pin Position 13)
  • SCK - GP10
  • MISO (RX) - GP12
  • MOSI (TX) - GP11
  • CS - GP13
  • BUSY - GP8
  • RST - GP9
  • GP0 - Not needed - used for Bootloading and Blutooth
  • RXI - Not needed for Wifi - Used for Blutooth 
  • TXO - Not needed for Wifi - Used for Blutooth

RaspberryPi Pico GPIO 600

The first task is to copy the required libraries from the CircuitPython folder stored on a computer to the lib folder on the CIRCUITPY drive.

For the ESP32 the following library folders and .mpy files are required:

  • adafruit_bus_device
  • adafruit_esp32spi
  • adafruit_requests.mpy

Then create the with either Thonny or Mu as they both support CircuitPython and will interact with the Pico while writing the script.

I'm using thonny. The first few lines of are to import the required libraries.


import board
import busio
from digitalio import DigitalInOut
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from time import sleep

 For the wifi connection to your chosen wifi network a secrets file can be used to store all the connection details. We will create this later but the code to use it is:

    from secrets import secrets
except ImportError:
    print("Wifi details not found, update")

Now we need to setup the SPI connection between the ESP32 and the Pico. For the wiring setup from earlier this is the commands.

#ESP32 Setup on Pico:
esp32_cs = DigitalInOut(board.GP13)
esp32_ready = DigitalInOut(board.GP8)
esp32_reset = DigitalInOut(board.GP9)
spi = busio.SPI(board.GP10, board.GP11, board.GP12)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

 This line enables the WiFi manager with the secrets file.

wifi = adafruit_esp32spi_wifimanager.ESPSPI_WiFiManager(esp, secrets)

 So that's the initial setup ready for writing a script to use it. Before we continue we need to setup the secrets file with the SSID and Password to your WiFi network. Save the file for now and create a new file called

This is saved to the CIRCUITPY drive with the file.

The file should look like this;

secrets = {
    'ssid' : 'YourSSID',
    'password' : 'YourPassword'

Replace YourSSID and YourPassword with the required connection details.

Back in we can enter the code to connect to your WiFi network.

While trying out the WiFi setup on the Pico I found that the WiFi connection often dropped out, causing the script to fail. So I use a functions to check regularly if the connection is still active and if not then it resets the connection and keeps things working.

def esp32():
        s = esp.status
        if s == 0:
    except RuntimeError:

The main part of the program is a loop that checks there is a connection with the esp32() function. It then prints the firmware and mac address of the ESP32 and then scans your local networks and shows which one you are connect to.

while 1:
    print("\nFirmware vers.", esp.firmware_version)
    print("MAC addr:", [hex(i) for i in esp.MAC_address])
    for ap in esp.scan_networks():
        print("\t%s" % (str(ap['ssid'], 'utf-8')))
    print("Connected to", str(esp.ssid, "utf-8"))
    print("My IP address is", esp.pretty_ip(esp.ip_address))

You now have a basic WiFi setup for the Raspberry Pi Pico. The whole script is available HERE

 (This guide is based on the example code for the ESP32spi at Adafruit

The Raspberry Pi 4 and Pico play a game together

As the Pico only has 264kb of memory you're not going to be doing any web browser or streaming a 4k video but what is a good option is passing data between the Pico and a computer. One method of this which is popular with Internet of Things (IoT) setups is to broadcast sensor data using Mosquitto (MQTT). 

The idea is a device broadcast data to a specific group through a server, known as a broker. Then devices connected to the same sever , that are subscribed to the same group, can receive this data.

For example you could have a Pico broadcasting the current outside temperature every second to a group called outside/temp. Then indoors, you could have a Raspberry Pi that is listening on the group outside/temp.  Once every minute the Raspberry Pi can read the current temperature and display it on a screen.

There is no confirmation that the data sent has been received so it is not useful for two way communications.

I have not used MQTT before and wanted to give it a try. So I took absolutely no notice that it is not two way communication and decided to write a basic guessing game for a Raspberry Pi 4 and a Pico to play.

Trying out Mosquitto to send Data between devices

If you would like to try a MQTT setup between a Pico and Raspberry Pi then you can try these examples to get you started.

These two scripts will send random numbers out and receive the random number from the other device.  I have tested this with a Raspberry Pi 4 and a Pico but it should work with a computer instead of a Raspberry Pi.

To start with the Mosquitto (MQTT) server needs to be installed on the Raspberry Pi. MQTT servers are also available as online services so instead of sending the data to a local device you can send it round the world. For this example the server will be on my home network. Use the command:

sudo apt install mosquitto

After a reboot the Mosquitto broker will be available from start up. If you don't want it running all the time then disable the service

sudo systemctl disable mosquitto

then to start the Mosquitto broker on demand just type mosquitto into a terminal

The Raspberry Pi will also need paho-mqtt installed via apt or pip

sudo apt install python3-paho-mqtt
sudo pip3 install paho-mqtt

The Pico will need the adafruit MQTT libraries added to the lib folder; adafruit_minimqtt

On the Raspberry Pi run this script in python HERE

On the Pico use this script HERE. Rename it to to run it automatically or use Thonny to run it on demand. You will need a screen connected to the Pico or the Thonny output shell to see the messages.

With the MQTT broker running set off both python scripts and watch the random numbers being passed between the devices.

 Though data can be sent in various formats I have put the results in a dictionary and used the json format to send the messages. Json is a useful format for sending multiple sets of sensor results and readings through MQTT allowing the receiving device to easily extract any single reading.



Add comment