How to Get Wi-Fi on Raspberry Pi Pico 2, expansion board required

 Wi-Fi on Raspberry Pi Pico 2
(Image credit: Tom's Hardware)

Just like the original Raspberry Pi Pico, the new Raspberry Pi Pico 2 has no Wi-Fi or Bluetooth connectivity. There will be a Pico 2 W, that has been confirmed by Raspberry Pi co-founder and CEO Eben Upton, but it is still a few months off yet. What can we do in the meantime? Do we have to go back to the Raspberry Pi Pico W?

Looking back through the archives we remembered our original guide to adding Wi-Fi to the Raspberry Pi Pico, all the way back in 2021! That guidance is a little outdated now, Adafruit has updated CircuitPython and its modules and now it is even easier to get online.

In this how to we will learn how to connect a Raspberry Pi Pico 2 to the Internet using an Adafruit Airlift WiFi Featherwing. This board is essentially an ESP32, an already formidable Wi-Fi enabled microcontroller. So you may be asking “Why?” Because we can and there may be an edge case that requires the power of the new RP2350 via a Wi-Fi connection.

To demonstrate how to use data from the Internet, we shall create a simple, and fun project which downloads a humorous Chuck Norris “fact” using an API (Application Programming Interface) that formats the returned data into a format called JSON.

Yes! I got Wi-Fi working on the Raspberry Pi Pico 2 and all it took was an ESP32 - YouTube Yes! I got Wi-Fi working on the Raspberry Pi Pico 2 and all it took was an ESP32 - YouTube
Watch On

For this project, you will need 

  • Raspberry Pi Pico 2 (Project will also work on Raspberry Pi Pico too)
  • Adafruit Airlift WiFi Featherwing Co-Processor
  • 8 x Male to Male jumper wires
  • Breadboard

Connecting the Raspberry Pi Pico 2 to Adafruit’s Airlift WiFi Featherwing

Adafruit’s Feather range of boards use a different pinout to the Raspberry Pi Pico 2, and so we'll need header pins soldered to the Raspberry Pi Pico 2 and to the Featherwing Airlift. As we are using both boards in a breadboard, the included male headers will suffice.

If you intend to use the Featherwing with an Adafruit Feather board, such as the Feather RP2040 then ensure that you’ll need to have female headers soldered to the top of the microcontroller. These should come with your Adafruit Airlift WiFi Featherwing. We chose to solder the female header with extra long male header pins to sit in the breadboard.

In the diagram, pay careful attention to the positions of MISO, MOSI and SCK. The pinout for the Featherwing sees more pins on one side than the other. Check and double-check before powering on.

Swipe to scroll horizontally
Raspberry Pi Pico 2Adafruit Airlift WiFi Featherwing Co-Processor
VSYSUSB
GNDAny GND pin
GPIO 10SCK
GPIO 11MOSI
GPIO 12MISO
GPIO 13ESPCS
GPIO 14ESPBUSY
GPIO 15ESPRST

Installing CircuitPython

Flashing CircuitPython to a microcontroller is easy, it was designed to be this easy. We’re going to be using an alpha release of CircuitPython for the Raspberry Pi Pico 2, there may be issues and crashes, so we wouldn’t deploy this into a mission critical project. Wait for a full release if that is the case.

1. Download the latest version of CircuitPython for the Pico 2. At the time of writing this was an alpha release, so beware the occasional crash.

2. Press and hold the BOOTSEL button on the Pico and insert a USB cable into the Pico and your computer.

3. Copy the CircuitPython UF2 file to the RP23502 drive. The drive will unmount and disappear while flashing the code. A new drive CIRCUITPY will appear, confirming that the flash was a success.

4. Download the libraries archive for the version of CircuitPython that you have downloaded. For example version 9.2.0 is only compatible with the libraries for CircuitPython 9.

5. Extract the contents of the download to a folder.

6. Copy the following files / folders to the lib folder on the CIRCUITPY drive.

/adafruit_bus_device

/adafruit_esp32spi

adafruit_requests.mpy

Writing the project code with CircuitPython

Our project is written in CircuityPython, a version of MicroPython from Adafruit. CircuitPython differs by offering an easy way to install modules of code for use with Adafruit’s range of products. We’re going to use Thonny to work with CircuitPython code that will communicate with the Adafruit Featherwing to pull data from the web.

1. Download and install Thonny.

2. Go to Tools >> Options and then select the Interpreter tab.

(Image credit: Tom's Hardware)

3. Set the Interpreter to CircuitPython (generic) and the Port to match the USB serial device (the Pico 2). Click OK. You can also try the auto port option to force Thonny to search for the port.

(Image credit: Tom's Hardware)

4.Click on STOP to force the Interpreter to connect and run the Python shell on the Raspberry Pi Pico 2.

5. Import a series of CircuitPython modules in order to create the project.

board: Basic GPIO access

busio: Used to create an SPI connection between the Pico 2 and the Adafruit board

digitalio: Used to get and set GPIO pin configurations

adafruit_connection_manager: Create network connections

adafruit_requests: Adafruit’s version of the Python requests library, used to make web requests with networked devices

adafruit_esp32spi: Used to communicate with the ESP32 on the Adafruit Featherwing

secrets: A module that stores Wi-Fi and country details, we shall create this later.

import board
import busio
from digitalio import DigitalInOut
import adafruit_connection_manager
import adafruit_requests
from adafruit_esp32spi import adafruit_esp32spi
from secrets import secrets

6. Print a message to the Python shell, telling the user what the project is about.

print("Raspberry Pi Pico 2: Chuck Norris Joke-Randomizer")

7. Create an object to store the URL of the Chuck Norris jokes. This can be the URL of any API or JSON source that you wish to use.

CHUCK_NORRIS_URL = "https://api.chucknorris.io/jokes/random"

8. Setup the GPIO pins used for making the SPI connection between the Pico 2 and the Adafruit Featherwing.

esp32_cs = DigitalInOut(board.GP13)
esp32_ready = DigitalInOut(board.GP14)
esp32_reset = DigitalInOut(board.GP15)
spi = busio.SPI(board.GP10, board.GP11, board.GP12)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

9. Setup the networking infrastructure aspect of the code. This is all the behind the scenes tech that makes the connection possible.

pool = adafruit_connection_manager.get_radio_socketpool(esp)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp)
requests = adafruit_requests.Session(pool, ssl_context)

10. Print a message to say that the project will attempt to connect to your Wi-Fi.

print("Connecting to AP...")

11. While the ESP32 in the Adafruit Featherwing is not connected, the code will try to make a connection using the Wi-Fi AP and password stored in the secrets.py file. We will make this file later.

while not esp.is_connected:
   try:
       esp.connect_AP(secrets["ssid"], secrets["password"])

12. Using these lines, handle any connection errors. If there is an error, the code will keep trying to connect.

   except OSError as e:
       print("could not connect to AP, retrying: ", e)
       continue

13. Print the connection details for a successful connection. These two lines will print the access point name, and the internal IP address of the project.

print("Connected to", esp.ap_info.ssid, "\tRSSI:", esp.ap_info.rssi)
print("My IP address is", esp.ipv4_address,"\n")

14. Print a message to announce the random Chuck Norris joke.

print("Your Random Chuck Norris joke is... ")

15. Using Adafruit’s requests, get the latest joke in a JSON format and store it inside an object called “r”.

r = requests.get(CHUCK_NORRIS_URL).json()

16. Extract the joke from the JSON object. JSON is very similar to Python’s dictionary data structure which uses “keys” to extract “values” from the object. In this case the key is called ‘value’. Not a great choice as its name could confuse, but we have no control of that.

joke = r['value']

17. Print the joke, encapsulated inside of a frame made from “-”. Using the len() command we can get the length (number of characters in the joke string) and use that to create the frame with the correct number of characters.

print("-" * len(joke))
print(joke)
print("-" * len(joke))

18. Save the code to the Raspberry Pi Pico 2 as code.py. This will overwrite the existing code.py file and each time the Pico 2 powers up, the code will autostart.

Complete Code Listing for code.py

import board
import busio
from digitalio import DigitalInOut
import adafruit_connection_manager
import adafruit_requests
from adafruit_esp32spi import adafruit_esp32spi
from secrets import secrets

print("Raspberry Pi Pico 2: Chuck Norris Joke-Randomizer")
CHUCK_NORRIS_URL = "https://api.chucknorris.io/jokes/random"

esp32_cs = DigitalInOut(board.GP13)
esp32_ready = DigitalInOut(board.GP14)
esp32_reset = DigitalInOut(board.GP15)
spi = busio.SPI(board.GP10, board.GP11, board.GP12)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
pool = adafruit_connection_manager.get_radio_socketpool(esp)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp)
requests = adafruit_requests.Session(pool, ssl_context)

print("Connecting to AP...")
while not esp.is_connected:
    try:
        esp.connect_AP(secrets["ssid"], secrets["password"])
    except OSError as e:
        print("could not connect to AP, retrying: ", e)
        continue
print("Connected to", esp.ap_info.ssid, "\tRSSI:", esp.ap_info.rssi)
print("My IP address is", esp.ipv4_address,"\n")

print("Your Random Chuck Norris joke is... ")
r = requests.get(CHUCK_NORRIS_URL).json()
joke = r['value']
print("-" * len(joke))
print(joke)
print("-" * len(joke))

Creating a Secrets File

The secrets.py file is a useful tool that stores our Wi-Fi details, along with country specific details that can be used for Wi-Fi connections. By keeping our secrets separate from the main code, we can share the code.py file without fear of sharing our secrets.

1. Create a new file on the Raspberry Pi Pico 2.

2. Create an object called “secrets” and store your Wi-Fi SSID, password and timezone inside the object. The object is a Python dictionary. The keys identify what the data stored in the values represents.

secrets = {
  'ssid' : 'YOUR SSID',
  'password' : 'YOUR PASSWORD',
  'timezone' : YOUR TIMEZONE SEE THE URL >> ', # http://worldtimeapi.org/timezones
}

3. Save the file to the Raspberry Pi Pico 2 as secrets.py.

Running the project code

(Image credit: Tom's Hardware)

We are now ready to learn some pearls of wisdom regarding Chuck Norris.

1. Go back to the code.py tab.

2. Click on Run >> Run Current Script (or press F5, or the green play button) to start the code.

The code will run in the Python Shell, and after a few moments it should connect to your Wi-Fi and download the latest Chuck Norris joke using the JSON API.

Les Pounder

Les Pounder is an associate editor at Tom's Hardware. He is a creative technologist and for seven years has created projects to educate and inspire minds both young and old. He has worked with the Raspberry Pi Foundation to write and deliver their teacher training program "Picademy".