Raspberry Pi Companion Boards: Beginner’s Guide to Pico W and MQTT

Beginner’s Guide to Raspberry Pi Companion Boards

Last tested: MicroPython v1.23 | April 11, 2026 | Raspberry Pi Pico W with Raspberry Pi 4 as MQTT broker

Raspberry Pi companion boards let you offload specific tasks from your main Pi to a dedicated microcontroller. I use a Pico W to handle sensor reading without touching the resources on my Pi 4. The Pico W reads a DHT11, publishes the data over MQTT to a Mosquitto broker running on the Pi, and the Pi logs or visualizes it. The Pico W sits on a breadboard powered by a USB bank. No reboots, no drama, and the Pi stays free for everything else.

This guide covers what companion boards are, how to wire common sensors to the Pico W, how MQTT connects everything together, and how to build a working sensor-to-dashboard setup from scratch.

Key Takeaways

  • The Pico W is a microcontroller, not a computer. It runs MicroPython firmware and handles one job reliably without an OS.
  • MQTT separates sensor nodes from processing nodes. The Pico W publishes, the Raspberry Pi subscribes and logs.
  • The Pico W only supports 2.4GHz Wi-Fi. If your router is 5GHz only, it will not connect.
  • The onboard LED on Pico W is controlled via the CYW43 chip, not GPIO pin 25. Use machine.Pin("LED", machine.Pin.OUT).
  • Multiple Pico W boards can report to one Pi broker using distinct MQTT client IDs and structured topic paths.
Companion boards diagram - Raspberry Pi companion boards

What Is a Raspberry Pi Companion Board?

A companion board is a microcontroller that runs alongside a main Raspberry Pi, handling a specific task so the Pi does not have to. The Pico W is the most common example in the Pi ecosystem. It runs MicroPython scripts, communicates with sensors over GPIO, I2C, or SPI, and sends data wirelessly via MQTT. The Pi acts as the central hub: receiving, storing, and displaying the data the companion board collects.

This separation has practical benefits. The Pico W consumes very little power and can run continuously from a USB bank. It handles real-time sensor polling without the latency of a full Linux OS. If the Pi reboots or restarts a service, the Pico W keeps reading and publishing without interruption. For home automation, environmental monitoring, and IoT sensor networks, this division of labor keeps each device doing what it does best.

Pre-Soldered Header Raspberry Pi Pico W, Built-in WiFi Support 2.4 GHZ Wi-Fi 4, Based on Official RP2040 Dual-Core Processor,Dual-core Arm Cortex M0+…

5.0
Amazon.com

Getting Started with the Raspberry Pi Pico W

What the Pico W is

The Pico W uses the RP2040 dual-core processor and adds Wi-Fi through the Infineon CYW43439 chip. It runs MicroPython and is programmed through Thonny IDE, which connects over USB and doubles as a code editor and live terminal. It supports I2C, SPI, UART, and analog input through its GPIO header. It does not run a full OS. Scripts run directly on the hardware with no scheduler or background processes competing for resources.

Flash MicroPython firmware

  1. Hold the BOOTSEL button on the Pico W and connect it via USB to your computer
  2. It appears as a mass storage device called RPI-RP2
  3. Download the Pico W MicroPython UF2 from micropython.org
  4. Drag the UF2 file onto the RPI-RP2 drive. The board reboots automatically.
  5. Open Thonny, select MicroPython (Raspberry Pi Pico) as the interpreter, and confirm the REPL connects

Connect to Wi-Fi in MicroPython

import network
import time

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("YOUR_SSID", "YOUR_PASSWORD")

while not wlan.isconnected():
    time.sleep(0.5)

print("Connected:", wlan.ifconfig())

The Pico W only supports 2.4GHz Wi-Fi. If your router broadcasts only 5GHz or uses a combined SSID that hands out 5GHz to new devices, the Pico W will fail to connect without any helpful error message. Confirm a 2.4GHz SSID is available before debugging the script.

Connecting Sensors to the Pico W

The Pico W operates at 3.3V logic. All sensors must match this voltage or use a logic level shifter. For I2C devices, GP0 and GP1 are the default SDA and SCL pins. Analog sensors connect to GP26, GP27, or GP28, which are the ADC-capable pins.

SensorProtocolPico W pinsPower
DHT11 / DHT22DigitalAny GPIO (e.g. GP15)3.3V
BME280I2CGP0 (SDA), GP1 (SCL)3.3V
HC-SR04DigitalGP16 (TRIG), GP17 (ECHO)5V with resistor divider on ECHO
LDR (light sensor)AnalogGP26 (ADC0)3.3V
SSD1306 OLEDI2CGP0 (SDA), GP1 (SCL)3.3V

Use a breadboard and jumper wires for initial testing. The Pico W fits on a half-size breadboard with room on each side for wiring. Power sensors from the 3V3 pin and share a common GND. Keep signal wires short to reduce noise, particularly on I2C buses running multiple devices.

MQTT: How the Pico W Talks to the Pi

MQTT is a lightweight publish-subscribe messaging protocol designed for constrained devices. The Pico W publishes sensor readings to a topic. A broker (Mosquitto running on the Pi) receives and holds the message. The Pi subscribes to the topic and receives the data. Neither device needs to be directly aware of the other. They only need to agree on a broker address and a topic name.

DeviceRoleAction
Pico WPublisherSends sensor data to broker topic
Mosquitto on PiBrokerReceives, stores, and forwards messages
Raspberry PiSubscriberReceives data for logging or automation

Install Mosquitto on the Raspberry Pi

sudo apt update
sudo apt install mosquitto mosquitto-clients -y
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

Test that the broker is working by subscribing in one terminal and publishing from another:

# Terminal 1 -- subscribe
mosquitto_sub -h localhost -t "test/topic"

# Terminal 2 -- publish
mosquitto_pub -h localhost -t "test/topic" -m "hello"

Build a Working Sensor Project

This project reads temperature and humidity from a DHT22 sensor on the Pico W, displays values on an SSD1306 OLED, and publishes them over MQTT to a Mosquitto broker on the Pi. Node-RED on the Pi subscribes and visualizes the data.

Parts needed

  • Raspberry Pi Pico W
  • DHT22 temperature and humidity sensor
  • SSD1306 OLED display (I2C)
  • Raspberry Pi (any model) with Mosquitto and Node-RED installed
  • Breadboard and jumper wires
  • USB power supply for the Pico W

Pin wiring

PeripheralPico W pinNotes
DHT22 VCC3V3Power
DHT22 GNDGNDGround
DHT22 DATAGP15Digital signal
OLED SDAGP0I2C data
OLED SCLGP1I2C clock
OLED VCC3V3Power
OLED GNDGNDGround

MicroPython script

import network
import time
import dht
import machine
from umqtt.simple import MQTTClient
import ssd1306

# Wi-Fi credentials
SSID = "YOUR_SSID"
PASSWORD = "YOUR_PASSWORD"

# MQTT broker address (your Pi's IP)
BROKER = "192.168.1.50"
TOPIC = b"home/livingroom/env"
CLIENT_ID = b"picow-livingroom"

# Hardware setup
sensor = dht.DHT22(machine.Pin(15))
i2c = machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

# Onboard LED -- note: use "LED" not Pin(25) on Pico W
led = machine.Pin("LED", machine.Pin.OUT)

# Connect to Wi-Fi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
    time.sleep(0.5)

# Connect to MQTT broker
client = MQTTClient(CLIENT_ID, BROKER)
client.connect()

while True:
    sensor.measure()
    temp = sensor.temperature()
    hum = sensor.humidity()

    payload = '{{"temp": {}, "humidity": {}}}'.format(temp, hum)
    client.publish(TOPIC, payload)

    oled.fill(0)
    oled.text("Temp: {}C".format(temp), 0, 0)
    oled.text("Hum:  {}%".format(hum), 0, 16)
    oled.show()

    led.toggle()
    time.sleep(30)

Save this as main.py on the Pico W so it runs automatically after every reset or power-on. The 30-second interval throttles DHT22 reads, which is important since reading DHT22 too frequently causes errors. Reduce the interval only if your application genuinely needs faster updates.

Receive and visualize on the Pi

Confirm messages are arriving on the Pi:

mosquitto_sub -h localhost -t "home/livingroom/env"

For a dashboard, install Node-RED and add an MQTT input node pointed at home/livingroom/env. Wire it to a JSON parse node and then to gauge or chart nodes. Node-RED’s dashboard module renders a live browser UI that updates as each MQTT message arrives. For home automation integration, the same MQTT topic can feed directly into Home Assistant using its MQTT integration.

Visual Feedback with Displays and LEDs

Local feedback on the Pico W confirms the script is running without needing a laptop connected. The SSD1306 OLED shows live sensor values. The onboard LED blinks on each successful MQTT publish. Together they tell you at a glance whether the sensor is reading, the Wi-Fi is connected, and data is flowing.

System eventVisual feedback
Wi-Fi connectedLED steady on
MQTT message publishedLED short blink
Sensor read successfulNew value on OLED
Broker unreachableOLED shows error text

Managing Multiple Pico W Devices

When adding more than one Pico W to a project, two rules prevent most problems. First, every device needs a unique MQTT client ID. If two clients use the same ID, the broker will disconnect one of them when the other connects. Second, topic names should follow a consistent structure that encodes location and function, such as house/kitchen/temp or house/basement/humidity. This makes automation rules in Node-RED or Home Assistant straightforward to write.

NodeClient IDTopic
Living room temppicow-livingroomhouse/livingroom/env
Kitchen humiditypicow-kitchenhouse/kitchen/humidity
Basement sensorpicow-basementhouse/basement/temp
Fan controllerpicow-fanhouse/fan/cmd (subscriber)

For I2C sensors, avoid address conflicts by using components with configurable addresses or separating them onto distinct I2C buses. The Pico W has two I2C buses (I2C0 and I2C1) that can run simultaneously. If you need multiple devices with the same fixed I2C address, use a TCA9548A multiplexer to assign each to its own channel.

The retain flag in MQTT tells the broker to store the last message on a topic so new subscribers receive the most recent value immediately on connection. Add retain=True to client.publish() calls for sensor readings that need to survive broker restarts or Pi reboots.

Troubleshooting

Pico W will not connect to Wi-Fi

The most common cause is a 5GHz-only SSID. Confirm a 2.4GHz network is available and that the SSID and password in the script match exactly, including case. Use print(wlan.status()) to get a numeric status code if wlan.isconnected() stays False. A status of 3 means connected, anything else indicates the failure mode.

MQTT messages not arriving on the Pi

SymptomLikely causeFix
No messages on subscriberTopic name mismatchMatch topic strings exactly on publisher and subscriber
Connection refused errorBroker IP wrong or Mosquitto not runningPing broker from Pi, check systemctl status mosquitto
Client keeps disconnectingDuplicate client IDAssign a unique client_id to each Pico W
Works once then stopsNo reconnect logic in scriptAdd try/except around publish and reconnect on failure

Sensor returns errors or bad values

DHT sensors need at least 2 seconds between reads. Reading faster than this causes OSError exceptions. Wrap the sensor.measure() call in a try/except block and log the error rather than crashing the loop. For I2C devices, confirm the address with:

import machine
i2c = machine.I2C(0, sda=machine.Pin(0), scl=machine.Pin(1))
print(i2c.scan())   # should show a list containing the device address

Onboard LED not working

On the Pico W, the onboard LED is routed through the CYW43439 Wi-Fi chip rather than directly to GPIO pin 25. Using machine.Pin(25, machine.Pin.OUT) will not work reliably. Use machine.Pin("LED", machine.Pin.OUT) instead. This is a common point of confusion for anyone following tutorials written for the original Pico rather than the Pico W.

Useful Tools

Development tools

Thonny IDE is the standard tool for writing and uploading MicroPython to the Pico W. It shows the REPL output live, which is the fastest way to debug sensor readings and Wi-Fi connection issues. For command-line workflows, mpremote (the official MicroPython remote tool) handles file transfers and REPL access without a GUI.

MQTT tools

MQTT Explorer is a desktop application that connects to your broker and shows all active topics, their payloads, and message history. It is the fastest way to confirm that the Pico W is actually publishing and that topic names are correct. On the Pi itself, mosquitto_sub -h localhost -t "#" -v shows all messages on all topics in real time.

Dashboard and automation

Node-RED runs on the Raspberry Pi and connects MQTT inputs to dashboard outputs through a visual flow editor. It handles JSON parsing, conditional logic, and data storage without writing server-side code. Home Assistant’s MQTT integration can consume the same topics directly, turning sensor readings into entities for dashboards and automations.

FAQ

What is the difference between the Pico W and a Raspberry Pi?

The Pico W is a microcontroller. It runs a single MicroPython script directly on hardware with no OS, no file system beyond a small flash storage, and no background processes. A Raspberry Pi is a single-board computer running a full Linux operating system. The Pico W handles real-time sensor tasks efficiently. The Pi handles storage, networking services, dashboards, and anything that needs a proper OS.

Can I use 5V sensors with the Pico W?

Not directly. The Pico W operates at 3.3V logic and its GPIO pins are not 5V tolerant. Connecting a 5V signal directly will damage the chip. Use a logic level shifter between a 5V sensor output and a Pico W GPIO input. The HC-SR04 ultrasonic sensor is the most common example of this. Its ECHO pin outputs 5V and needs a voltage divider or level shifter before connecting to GP17.

What MQTT broker should beginners use?

Mosquitto running on a Raspberry Pi is the standard choice. It is lightweight, well-documented, and keeps everything on the local network. Adafruit IO is a cloud-based alternative that provides a hosted broker and built-in dashboard, which is useful if you want to skip self-hosting. For anything beyond a small home network, consider adding basic Mosquitto authentication via a password file.

What happens if Wi-Fi drops during publishing?

The MQTT publish call will throw an exception. Without error handling, the script crashes and the Pico W stops sending data. Add a try/except block around both the Wi-Fi connection and the MQTT publish calls, with reconnect logic in the except clause. A watchdog timer (machine.WDT) can also reset the board automatically if the main loop stops progressing.

Why is my OLED display not working?

Confirm GP0 is SDA and GP1 is SCL with correct wiring. Run i2c.scan() to check the display is detected. It should return [60] which is 0x3C in decimal. If the scan returns an empty list, check the wiring and confirm the display is powered. Also confirm the ssd1306.py driver file is uploaded to the Pico W’s filesystem alongside your main script.

References


About the Author

Chuck Wilson has been programming and building with computers since the Tandy 1000 era. His professional background includes CAD drafting, manufacturing line programming, and custom computer design. He runs PidiyLab in retirement, documenting Raspberry Pi and homelab projects that he actually deploys and maintains on real hardware. Every article on this site reflects hands-on testing on specific hardware and OS versions, not theoretical walkthroughs.

Last tested hardware: Raspberry Pi Pico W with Raspberry Pi 4 as MQTT broker. Last tested firmware: MicroPython v1.23.

Was this helpful?

Yes
No
Thanks for your feedback!