Wireless Communication Between Two Raspberry Pi Pico W Boards

Wireless Communication Between Two Raspberry Pi Pico W Boards

In this tutorial we are going to make one Raspberry Pi Pico W send random RGB (red, green, blue) values to another Pico W board! This is a very simple project to introduce WiFi communication with MicroPython and could form a basis for a wide variety of projects.

The project connects both Pico W boards to your home WiFi network with one acting as a server and the other as a client.

Tony came up with this tutorial after tinkering with his Pico W boards soon after the launch of the new wireless Pico, and we couldn't help think "...the computers are talking to each other...how long before SkyNet!".


A quick note - this probably isn't the ideal first project if you haven't used a Pico before. For a little warm up and introduction, Raspberry Pi have a great Getting Started Guide here, or the Get started with MicroPython on Raspberry Pi Pico book is a good option too!


What you'll need

The proposed system

In a nutshell

  • Both Pico W boards connect to your WiFi network
  • Pico W #1 runs a little web server that receives requests and sends replies to Pico W #2
  • Pico W #2 continually sends requests to Pico W #1's web server, and receives replies back from it

How does it work?

Both Pico boards are given your WiFi network's SSID and password. We set up a very simple web server on the first Pico W which waits for requests from the second Pico W. For simplicity we do not decode the requests but treat them all in the same way. We just generate three values, between 0 and 255 inclusive, to represent the red, green and blue components of a colour.

The first Pico packs them into a string, separated by commas, and sends that as the reply to the second Pico W. The program prints out its local address once it has connected to our network. We need to note this address as it is used by the second Pico W to request data..

The second Pico W repeatedly sends requests to the web server and receives back the data string, which is then unpacked into the three colour values and displayed.

For security we save the SSID and password in a separate library file so that it is not visible in the program.

Setup

1. Install the Pico W UF2 File

First you'll need to make sure you have the latest Raspberry Pi MicroPython UF2 file (the Pico W specific version) on both of your Pico boards. The UF2 files are available here.

To install this to your Pico, hold down the BOOTSEL button while plugging the board into a USB port. Your Pico should then show as a mass storage device (like a drive), then just drag over the UF2 file. This will install the firmware on to your board. Once complete the Pico will automatically reset and be ready for use.

For now, disconnect both boards and read on.Pico UF2

2. Prepare Thonny

To make things a little easier, we can configure Thonny to allow you to open two Thonny Windows (instances) at the same time, enabling you to have a separate Thonny window for each Pico.

To do this, open up Thonny and head to Tools > Options > General and untick 'Allow only single Thonny instance'.Thonny Multiple InstancesNow restart Thonny and connect both of your Pico W boards. Select Run > Select Interpreter and choose the first available COM port.Thonny COM portNext, open a second Thonny instance (just open the program again from your usual menu). Follow the same process and select the other COM port.

You're now running two Thonny windows, one for each Pico W!

3. Install PyStone Lowmem

We now have to install some packages to both boards.

First, the micropython-pystone_lowmem package. In Thonny navigate to Tools > Manage Packages and search for micropython-pystone_lowmem.

Click on the top result as shown below and install it.Pystone lowmem

Then we need to install urequests with the same method as above (ignore any warning):

urequests

Now in Thonny's REPL (Read Evaluate Print Loop) window, try the following at the prompt (you'll need to save it first, which it will prompt you to do):

import pystone_lowmem
pystone_lowmem.main()

You should see something like this:

pystone output

Now follow the same steps for your other Pico in the other Thonny window, as both boards need to be set up in the same way for this project to work.

4. Create the Secret library

Create a new program window in both Thonny windows and copy the following lines:

ssid = 'SSID'
password = 'PASSWORD'

Insert your own WiFi network values between the single quotes and save the program in both boards calling it secret.py

Creating the Web Server (Pico #1)

This program sets up a simple web server (on Pico #1) which generates RGB values and sends them when requested.

Copy the code below to a new Thonny window on your first Pico W board, then save it as server.py.

# Webserver to send RGB data
# Tony Goodhew 5 July 2022
import network
import socket
import time
from machine import Pin, ADC
from secret import ssid,password
import random
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
       
# Wait for connect or fail
max_wait = 10
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    max_wait -= 1
    print('waiting for connection...')
    time.sleep(1)

# Handle connection error
if wlan.status() != 3:
    raise RuntimeError('network connection failed')
else:
    print('connected')
    status = wlan.ifconfig()
    print( 'ip = ' + status[0] )

# Open socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(addr)
s.listen(1)

print('listening on', addr)

# Listen for connections
while True:
    try:
        cl, addr = s.accept()
        print('client connected from', addr)
        request = cl.recv(1024)
        print(request)
        # Do not unpack request
        # We reply to any request the same way
        # Generate 3 values to send back
        r = random.randint(0,255)
        g = random.randint(0,255)
        b = random.randint(0,255)
        # Join to make a simple string with commas as separators
        rgb = str(r) + "," + str(g) + ","+str(b)
        
        response = rgb # This is what we send in reply

        cl.send(response)
        print("Sent:" + rgb)
        cl.close()

    except OSError as e:
        cl.close()
        print('connection closed')

Now run the program in Thonny and it will show you it's IP address. Make a note of this then move over to Pico #2 to configure the Client program.

Server IP address

Creating the Client Program (Pico #2)

This client program requests data from the web server, unpacks it into the three component parts and prints them.

Copy the code below to a new Thonny window on your second Pico W board, but before saving it, update the IP address with the IP from your Pico #1 server. Look for the line below and change it to reflect the correct IP address:

ai = socket.getaddrinfo("192.168.1.27", 80) # Address of Web Server

Once updated, save it as client.py on the Pico.

# Program to read RGB values from a local Pico Web Server
# Tony Goodhew 5th July 2022
# Connect to network
import network
import time
from secret import ssid, password
import socket

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while not wlan.isconnected() and wlan.status() >= 0:
    print("Waiting to connect:")
    time.sleep(1)
 
# Should be connected and have an IP address
wlan.status() # 3 == success
wlan.ifconfig()
print(wlan.ifconfig())

while True:
    ai = socket.getaddrinfo("192.168.0.15", 80) # Address of Web Server
    addr = ai[0][-1]

    # Create a socket and make a HTTP request
    s = socket.socket() # Open socket
    s.connect(addr)
    s.send(b"GET Data") # Send request
    ss=str(s.recv(512)) # Store reply
    # Print what we received
    print(ss)
    # Split into RGB components
    l = len(ss)
    ss = ss[2:l-1]     # Strip to essentials  
    p = ss.find(",")   # Find first comma
    r = int(ss[0:p])   # Extract RED value
    ss = ss[p+1:]      # Remove red part
    p = ss.find(",")   # Find comma separator
    g = int(ss[0:p])   # Extract GREEN value
    b = int(ss[p+1:])  # Extract BLUE value
    print(r,g,b)       # Print RGB values
    print()
    # Set RGB LED here
    s.close()          # Close socket
    time.sleep(0.2)    # wait

Run the project!

Your server on Pico #1 should already be running, so now run the client file on your Pico #2 board.

You should see output similar to the example below on your Client Pico, with RGB values provided one after the other:

Client output on Thonny

We started these scripts manually, but as an example, you could save the web server program to the first Pico W calling it main.py so that it executes on power up.

Things to try

  • Put 3 potentiometers on the Web Server to supply the data
  • Control 3 LEDS or an RGB LED with the data received by the client
  • Send a sensor data (temperature and humidity for example) from the server to the client
  • Move the Picos apart to see how far the WiFi connection is effective

If you enjoyed this tutorial and make something cool based on the instructions here, show us on Twitter!

About the Author

This article was written by Tony Goodhew. Tony is a retired teacher of computing who starting writing code back in 1968 when it was called programming - he started with FORTRAN IV on an IBM 1130! An active Raspberry Pi community member, his main interests now are coding in MicroPython, travelling and photography.

Featured Products

Raspberry PiRaspberry Pi Pico W
Sale priceFrom £5.40 incl. VAT excl. VAT
The Pi HutEssential Raspberry Pi Pico Kit
Sale price £6 incl. VAT excl. VAT

1 comment

Bruce Blake

Bruce Blake

Tony,
I like your project. It looks like something I may want to build on.
Why not put the server IP address in the client’s secrets.py file?
Server = “192.168.1.27”
Is there a reason a Pico W can’t be a server and a client?
Pull time or weather as a client and then serve a pretty web page.
Bruce

Tony,
I like your project. It looks like something I may want to build on.
Why not put the server IP address in the client’s secrets.py file?
Server = “192.168.1.27”
Is there a reason a Pico W can’t be a server and a client?
Pull time or weather as a client and then serve a pretty web page.
Bruce

Leave a comment

All comments are moderated before being published.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.