BLE Communication between Raspberry Pi and Raspberry Pi Pico W

This tutorial explains how to set up Bluetooth Low Energy (BLE) communication between a Raspberry Pi and a Pico W. We’ll start by covering the basics of BLE, including the roles of Central and Peripheral devices. After that, we’ll go through two simple examples where the Pico sends data to the Pi.

BLE Communication between Raspberry Pi and Raspberry Pi Pico W

New to the Raspberry Pi Pico? Learn Raspberry Pi Pico/Pico W with MicroPython​ with our eBook

This tutorial was written by Edgardo Peregrino and edited by Sara Santos.

Prerequisites

Here’s a list of prerequisites for this tutorial.

1) Raspberry Pi Board

You need a Raspberry Pi board that has Bluetooth. The following models can be used: Pi 3, 3B+, 3A+, 4, 400, 5, 500, Zero W, Zero 2W, CM4 and CM5. When using the CM4 and CM5 modules, ensure that they include the WiFi/Bluetooth module.

Raspberry Pi 5

1.1) Raspberry Pi OS

In terms of software, you can use either Raspberry Pi OS Desktop or Raspberry Pi OS Lite. We use the 64-bit version.

1.2) Terminal and SSH

You should also have some understanding of the terminal, especially since you’ll need to enable the Bluetooth service using the terminal and install essential packages.

We’ll use PuTTY software to establish an SSH connection with the RPi board to run the commands in the terminal window.

We recommend following the next tutorial if you’re not familiar with installing the Raspberry Pi OS, or establishing a connection via SSH using PuTTY:

2) Raspberry Pi Pico Board

You need a Raspberry Pi Pico board that comes with Bluetooth. You can use a Raspberry Pi Pico W or Raspberry Pi Pico 2 W.

2.1) Thonny IDE

To program the Raspberry Pi Pico, we like to use Thonny IDE. Make sure your board is running the latest version of MicroPython firmware. We recommend taking a quick look at the following guide to check how to use Thonny IDE, how to flash MicroPython firmware, and how to run and upload code to the board:

The Basics of BLE or Bluetooth Low Energy

Before we begin, we should discuss the basics of BLE or Bluetooth Low Energy. BLE is a protocol that is different from Bluetooth Classic.

Bluetooth Smart Logo

Bluetooth Classic is designed for continuous data streaming, such as playing music on a wireless speaker. In contrast, Bluetooth Low Energy (BLE) is optimized for devices and sensors, making it suitable for the Pico W and Raspberry Pi models with built-in Bluetooth.

BLE consumes significantly less power than Bluetooth Classic, making it ideal for microcontrollers and small devices, although it has a shorter range. Another key difference is how they connect: Bluetooth Classic uses Serial communication, while BLE relies on the GATT (Generic Attribute Profile) protocol.

For a more comprehensive introduction to BLE and basic concepts such as peripheral and controller, UUIDs, GATT profiles, and more, we recommend reading the introduction section of this tutorial: Raspberry Pi Pico W: Bluetooth Low Energy (BLE) with MicroPython.

Project Overview

When using Bluetooth Low Energy (BLE), it’s important to understand the roles of BLE Peripheral and BLE Controller (also referred to as the Central Device).

In this case (in the examples covered in this guide), the Raspberry Pi will be the Central device and the Pico will be the Peripheral Device.

The Pico sets up a GATT profile to allow communication with the Raspberry Pi. Once connected, it “sends” a message to the Pi, which is then displayed in the terminal. This setup can be useful for projects like using the Pico as a controller for a Raspberry Pi–powered robot.

Note: I’m putting “sends” in quotes because the Pico isn’t actually pushing data to the Pi. Instead, the Pico writes a value to a characteristic in its GATT profile. The Raspberry Pi, which is connected to the Pico over BLE, then reads that characteristic to get the data.

Below is an example of what we will be doing in this project.

Diagram showing how the Pico as a Peripheral Device communicates with the Pi as a Central BLE Device
  1. The BLE Peripheral (server) advertises its existence.
  2. The BLE Central Device (client) scans for BLE devices.
  3. When the central device finds the peripheral it is looking for, it connects to it.
  4. After connecting, it reads the GATT profile of the peripheral and searches for the service it is looking.
  5. If it finds the service, it can now interact with the characteristics. For example, reading the values.

In BLE, every service and characteristic must have a UUID (Universally Unique Identifier). These UUIDs act as unique addresses that the Raspberry Pi uses to find and connect to the Pico’s services. For example, if the Pico provides a service with read and write characteristics, each will have its own UUID. The Pi looks for these UUIDs to know how to and to communicate with them.

For a more comprehensive introduction to BLE and basic concepts such as peripheral and controller, UUIDs, GATT profile, and more, we recommend reading the introduction section of this tutorial: Raspberry Pi Pico W: Bluetooth Low Energy (BLE) with MicroPython.

Parts Required

Here’s a list of the parts required for this tutorial:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Preparing the Raspberry Pi

After starting with a fresh installation of Raspberry Pi OS on your RPi board, you need to follow the next instructions to enable Bluetooth on the Pi and install some essential packages.

Enabling Bluetooth on the Pi

If you are using the desktop version of Pi OS, it’s very easy to turn on Bluetooth. Go to the Bluetooth icon and click on Make Discoverable. And that’s it, you’re ready to go.

If you’re using the Lite version or if you’re in an SSH session, we will use commands to enable Bluetooth. Establish an SSH connection with your Pi.

Type the following command:

sudo systemctl start bluetooth
Raspberry Pi Enable Bluetooth on Terminal Window

After that, run the following commands in order:

sudo bluetoothctl
agent on
default-agent
Enabling Bluetooth on RPi Completed

These commands are needed to enable Bluetooth. Once it’s done, you can exit by typing exit.

exit

Installing pipgio

Since we’ll also be controlling the Pi’s GPIOs, we need a package to control them. We’ll use pigpio. Run the following commands to install it globally and enable it on boot.

sudo apt install pigpio
sudo systemctl enable pigpiod

Creating a Virtual Environment

We’ll create a virtual environment that uses the system-wide packages like the pigpio (I’m doing it this way instead of installing it inside the virtual environment because I found some issues with controlling the GPIOs this way when using a Raspberry Pi 5).

First, we recommend creating a dedicated directory so you can keep your files organized. If you’re using the Desktop, ideally, you should go into the Documents directory and create a directory in there. For example, you can call it bluetooth_samples.

If you’re on the Lite version, you can create a directory called bluetooth_samples and then enter the directory like so:

mkdir bluetooth_samples && cd bluetooth_samples

Now, you should be in the bluetooth_samples folder.

Creating and moving to the bluetooth_samples folder on a Raspberry Pi

Now, create a virtual environment called blue in that directory.

python3 -m venv blue --system-site-packages 

Activate the virtual environment like so:

source blue/bin/activate

You know it’s active because the name of the virtual environment will show up before the prompt.

Raspberry Pi Virtual Environment Active

Installing Bleak

For the Raspberry Pi, we will need to install a BLE library that will communicate with the Pico, which is called Bleak. Install the library in the virtual environment:

pip install bleak

It should be installed after a few seconds.

Installing Bleak on a Raspberry Pi - Terminal Window

Raspberry Pi Wiring Diagram

In the case of the Raspberry Pi, our example will need an LED connected to GPIO 17. You can follow the next schematic diagram.

BLE Communication between RPi and RPi Pico

Here, we’re connecting the longer leg of the LED to GPIO pin 17 and this will be our LED to test if the code is working properly. The shorter lead of the LED will connect to the resistor, and we will connect the ground wire to the negative rail of the breadboard where the resistor is placed.

The Pico will be mounted on the breadboard just for practical reasons, and that will be it for the wiring. If you prefer, you don’t need to mount the Pico on the breadboard.

Sending a Basic message from the Pico to Pi

In this section, we’ll show you a simple MicroPython code that will be used on the Pico to “send” messages to the Raspberry Pi.

You can call it ble_sample.py. Later, you can upload it to the Pico as main.py so that it runs without being connected to the computer.

New to BLE with the Raspberry Pi Pico? You can read our getting started guide: Raspberry Pi Pico W: Bluetooth Low Energy (BLE) with MicroPython.

Copy the following code to Thonny IDE.

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/ble-raspberry-pi-and-pi-pico-w/

import asyncio
import aioble
import bluetooth
from machine import Pin

# Bluetooth configuration
_SERVICE_UUID = bluetooth.UUID(0x1848)
_WRITE_CHARACTERISTIC_UUID = bluetooth.UUID(0x2A6E) # Central writes here
_READ_CHARACTERISTIC_UUID = bluetooth.UUID(0x2A6F)  # Peripheral writes message here

BLE_NAME = "Pico W Peripheral"

# Initialize LED
led = Pin("LED", Pin.OUT)

connected = False

# Register GATT server
ble_service = aioble.Service(_SERVICE_UUID)
read_characteristic = aioble.Characteristic(
    ble_service, _READ_CHARACTERISTIC_UUID, read=True, notify=True
)
aioble.register_services(ble_service)

# Helper to encode the message
def _encode_message(message):
    return message.encode('utf-8')

# Task to handle LED blinking and message sending
async def send_task():
    global connected
    message_count = 1
    while True:
        led.toggle()
        blink = 1000 if connected else 250
        if connected:
            message = f"Hello from {BLE_NAME}! Count: {message_count}"
            read_characteristic.write(_encode_message(message), send_update=True)
            message_count += 1
            print(f"Sent: {message}")
        await asyncio.sleep_ms(blink)

# Serially wait for connections
async def peripheral_task():
    global connected
    # Show MAC address once at start
    ble = bluetooth.BLE()
    _, mac_address = ble.config('mac')
    formatted_mac = ':'.join('{:02X}'.format(b) for b in mac_address)
    print(f"Bluetooth MAC Address: {formatted_mac}")
    
    while True:
        try:
            async with await aioble.advertise(
                2000, name=BLE_NAME, services=[_SERVICE_UUID], appearance=768
            ) as connection:
                connected = True
                print("Connection from", connection.device)
                await connection.disconnected()
        except Exception as e:
            print("Error in peripheral_task:", e)
        finally:
            connected = False
            print(f"{BLE_NAME} disconnected")
            await asyncio.sleep_ms(100)

# Run both tasks
async def main():
    t1 = asyncio.create_task(send_task())
    t2 = asyncio.create_task(peripheral_task())
    await asyncio.gather(t1, t2)

# Run the program
asyncio.run(main())

View raw code

How Does the Code Work?

Let’s break down this code to get a better understanding.

Importing Libraries

First we import the libraries as shown below.

import asyncio
import aioble
import bluetooth
from machine import Pin

Defining UUIDs

Next, we need to define our UUIDs for the Pico. We need UUIDs for the service, write and read characteristics.

# Bluetooth configuration
_SERVICE_UUID = bluetooth.UUID(0x1848)
_WRITE_CHARACTERISTIC_UUID = bluetooth.UUID(0x2A6E) # Central writes here
_READ_CHARACTERISTIC_UUID = bluetooth.UUID(0x2A6F)  # Peripheral writes message here

BLE Name

We define the name for our Raspberry Pi Pico BLE device. You can call it any other name.

BLE_NAME = "Pico W Peripheral"

Initializing the LED

The next line initializes the RPi Pico built-in LED as a GPIO output with the name led.

# Initialize LED
led = Pin("LED", Pin.OUT)

The connected variable

The connected variable will be used to keep track whether the Pico is connected to oher BLE device.

connected = False

Register the Service and Characteristic

Then, register the GATT service and characteristic.

# Register GATT server
ble_service = aioble.Service(_SERVICE_UUID)
read_characteristic = aioble.Characteristic(
    ble_service, _READ_CHARACTERISTIC_UUID, read=True, notify=True
)
aioble.register_services(ble_service)

Encode the BLE Message

The message to be sent via BLE will be encoded as UTF-8. The following encode_message() function does that.

# Helper to encode the message
def _encode_message(message):
    return message.encode('utf-8')

Writing to the characteristic – send_task() function

The send_task() function “sends” a message to the Raspberry Pi once connected. It will also blink the Raspberry Pi Pico built-in LED every second when connected. If not connected, the LED will blink faster, every 250 milliseconds.

async def send_task():
    global connected
    message_count = 1
    while True:
        led.toggle()
        blink = 1000 if connected else 250
        if connected:
            message = f"Hello from {BLE_NAME}! Count: {message_count}"
            read_characteristic.write(_encode_message(message), send_update=True)
            message_count += 1
            print(f"Sent: {message}")
        await asyncio.sleep_ms(blink)

A new message is sent every second. We add a counter to the message to keep track of how many messages were sent.

message = f"Hello from {BLE_NAME}! Count: {message_count}"

This is the line that “sends” a new message.

read_characteristic.write(_encode_message(message), send_update=True)

The message_count is incremented in each loop.

message_count += 1

Notice that the send_task is an asynchronous function. For BLE handling, it’s better to use asynchronous programming to avoid timing issues. If you want to learn more about asynchronous programming with the Raspberry Pi Pico using MicroPython, we recommend the following tutorial:

Advertise the Pico as a BLE Service – peripheral_task()

Besides writing to the temperature characteristic, we also need to advertise the Raspberry Pi Pico as a BLE service. For that, we use the peripheral_task() function that sets up the Pico as a peripheral device and starts advertising.

We also get and print the Pico MAC address—we’ll need it later on the Raspberry Pi side to connect to the Pico.

# Serially wait for connections
async def peripheral_task():
    global connected
    # Show MAC address once at start
    ble = bluetooth.BLE()
    _, mac_address = ble.config('mac')
    formatted_mac = ':'.join('{:02X}'.format(b) for b in mac_address)
    print(f"Bluetooth MAC Address: {formatted_mac}")
    
    while True:
        try:
            async with await aioble.advertise(
                2000, name=BLE_NAME, services=[_SERVICE_UUID], appearance=768
            ) as connection:
                connected = True
                print("Connection from", connection.device)
                await connection.disconnected()
        except Exception as e:
            print("Error in peripheral_task:", e)
        finally:
            connected = False
            print(f"{BLE_NAME} disconnected")
            await asyncio.sleep_ms(100)

Main Function

Finally, we create an asynchronou main() function, where we’ll write the base for our code. We create two asynchronous tasks: one for advertising and another to send new messages every second and blink the on-board LED. Then, we gather and run the tasks asynchronously by asynchronously calling the main() function.

# Run both tasks
async def main():
    t1 = asyncio.create_task(send_task())
    t2 = asyncio.create_task(peripheral_task())
    await asyncio.gather(t1, t2)

# Run the program
asyncio.run(main())

Running the Code

Run the code on the Pico by pressing the green play button on Thonny or we can press F5 on the keyboard. Once it’s done, it’ll display the MAC address of the Pico.

Raspberry Pi Pico . display Bluetooth MAC address

Raspberry Pi – Receive the RPi Pico Messages

On the Raspberry Pi, create a new file with the code below. You can call it pi_led_receive.py. The file should be located inside the folder we created previously called bluetooth_samples — the same place where we created our virtual environment.

There are many ways to create and run files on the Pi. I like to use Remote-SSH on VS Code. This extension allows you to establish an SSH connection with your Pi, create files, write code, and execute it directly on your Raspberry Pi board from your computer using the VS Code interface. Learn more here: Programming Raspberry Pi Remotely using VS Code (Remote-SSH).

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/ble-raspberry-pi-and-pi-pico-w/

import asyncio
from bleak import BleakClient, uuids
from gpiozero import LED 

connected = False   

led = LED(17)

# Replace with the MAC address of your Pico 
pico_address = "FF:FF:FF:FF:FF:FF"

# Service UUID (0x1848)
SERVICE_UUID = uuids.normalize_uuid_16(0x1848)
WRITE_CHARACTERISTIC_UUID = uuids.normalize_uuid_16(0x2A6E) # Central writes here
READ_CHARACTERISTIC_UUID = uuids.normalize_uuid_16(0x2A6F)  # Central reads here

async def receive_data_task(client):
    """Receive data from the peripheral device."""
    while True:
        try:
            response = await client.read_gatt_char(READ_CHARACTERISTIC_UUID)
            print(f"Central received: {response.decode('utf-8')}")
            await asyncio.sleep(1)
        except Exception as e:
            print(f"Error receiving data: {e}")
            break

async def blink_task():
    global connected 
    print("blink task started")
    while True:
        led.toggle() 
        blink = 1000  if connected else 250
        await asyncio.sleep(blink / 1000)

async def connect_and_communicate(address):
    global connected
    """Connect to the peripheral and manage data exchange."""
    print(f"Connecting to {address}...")

    async with BleakClient(address) as client:
        connected = client.is_connected
        print(f"Connected: {connected}")

        # Create tasks for sending and receiving data
        tasks = [
            asyncio.create_task(receive_data_task(client)),
            asyncio.create_task(blink_task())
        ]
        await asyncio.gather(*tasks)
    connected = False

# Run the connection and communication
loop = asyncio.get_event_loop()
loop.run_until_complete(connect_and_communicate(pico_address))

View raw code

Before running the code, you need to modify the following line with the Bluetooth MAC address of the Pico. You should have gotten it in the previous example.

# Replace with the MAC address of your Pico 
pico_address = "2C:CF:67:B6:D7:4C"

How Does the Code Work?

Let’s now take a quick look at the code to see how it works.

First, import the required libraries. We’re including bleak for the Bluetooth functions.

import asyncio
from bleak import BleakClient, uuids
from gpiozero import LED 

We have a boolean variable to keep track of whether we’re connected to another Bluetooth peripheral or not.

connected = False

We define the service and characteristics’ UUIDs. These are the service and characteristics of the Pico that we’ll search for to read the message sent from the Pico. So, these must be the same of the Pico.

# Service UUID (0x1848)
SERVICE_UUID = uuids.normalize_uuid_16(0x1848)
WRITE_CHARACTERISTIC_UUID = uuids.normalize_uuid_16(0x2A6E) # Central writes here
READ_CHARACTERISTIC_UUID = uuids.normalize_uuid_16(0x2A6F)  # Central reads here

Then, we have an asynchronous function called receive_data_task() that waits to read the characteristic value of the peripheral device. It reads the characteristic every second.

async def receive_data_task(client):
    """Receive data from the peripheral device."""
    while True:
        try:
            response = await client.read_gatt_char(READ_CHARACTERISTIC_UUID)
            print(f"Central received: {response.decode('utf-8')}")
            await asyncio.sleep(1)
        except Exception as e:
            print(f"Error receiving data: {e}")
            break

We have another task called blink_task() that will run at the same time. This task will blink the LED connected to GPIO 17 on the Raspberry Pi. It will run every second if we are connected to the peripheral device.

async def blink_task():
    global connected 
    print("blink task started")
    while True:
        led.toggle() 
        blink = 1000  if connected else 250
        await asyncio.sleep(blink / 1000)

Finally, the connect_and_communicate() function tries to connect to the peripheral device with the MAC address we defined earlier. Once it is connected, we create and gather the tasks to receive data and blink the LED.

async def connect_and_communicate(address):
    global connected
    """Connect to the peripheral and manage data exchange."""
    print(f"Connecting to {address}...")

    async with BleakClient(address) as client:
        connected = client.is_connected
        print(f"Connected: {connected}")

        # Create tasks for sending and receiving data
        tasks = [
            asyncio.create_task(receive_data_task(client)),
            asyncio.create_task(blink_task())
        ]
        await asyncio.gather(*tasks)
    connected = False

Finally, we asynchronously run the tasks in a loop.

# Run the connection and communication
loop = asyncio.get_event_loop()
loop.run_until_complete(connect_and_communicate(pico_address))

Running the Python Code

After creating the pi_led_receive.py file with the code we’ve shared previously and inserting your Pico MAC address, you can run it on your Raspberry Pi board. We’re using the Remote-SSH extension on VS Code, but you can simply create a new file using the nano command.

After saving the file, you can run it. But first, make sure you’re in the virtual environment we created previously. If you’ve exited the virtual environment, you can activate it again like so:

source blue/bin/activate

Finally, you can run your Python program like this:

python3 pi_led_receive.py

Demonstration

The code will start running, and after a few seconds it will connect to the Raspberry Pi Pico (make sure the RPi Pico is running the code on Thonny IDE).

It will start receiving the Pico’s messages.

Raspberry Pi Receiving BLE messages from the RPi Pico - terminal window

At the same time, the LED connected to GPIO 17 will start blinking every second.

RPi to RPi Pico BLE Communication

And that’s it. Now, you have the Raspberry Pi reading data from the Raspberry Pi Pico via BLE.

You can also check the sent messages on the shell of Thonny IDE.

RPi Pico Sending Bluetooth Message to Raspberry Pi

Sending Current Time from the Pico to Pi Example

Instead of sending a message without meaning, we can easily change the code to send sensor readings or commands, for example. In this section, we’ll show you how you can easily change the previous example to send different data. In this case, we’ll send the current time from the Pico to the Pi.

The code for the Pi will remain the same. For the Pico, we need to make some slight changes. This is the code for the Pico.

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/ble-raspberry-pi-and-pi-pico-w/

import asyncio
import aioble
import bluetooth
from machine import Pin
import time

# Bluetooth configuration
_SERVICE_UUID = bluetooth.UUID(0x1848)
_WRITE_CHARACTERISTIC_UUID = bluetooth.UUID(0x2A6E) # Central writes here
_READ_CHARACTERISTIC_UUID = bluetooth.UUID(0x2A6F)  # Peripheral writes message here

BLE_NAME = "Pico W Peripheral"

# Initialize LED
led = Pin("LED", Pin.OUT)

connected = False

# Register GATT server
ble_service = aioble.Service(_SERVICE_UUID)
read_characteristic = aioble.Characteristic(
    ble_service, _READ_CHARACTERISTIC_UUID, read=True, notify=True
)
aioble.register_services(ble_service)

# Helper to encode the message
def _encode_message(message):
    return message.encode('utf-8')

# Task to handle LED blinking and message sending
async def send_task():
    global connected
    while True:
        led.toggle()
        blink = 1000 if connected else 250
        if connected:
            today = time.localtime()  # get the current time
            message = f"{today}"
            read_characteristic.write(_encode_message(message), send_update=True)
            print(f"Sent: {message}")
        await asyncio.sleep_ms(blink)

# Serially wait for connections
async def peripheral_task():
    global connected
    # Show MAC address once at start
    ble = bluetooth.BLE()
    _, mac_address = ble.config('mac')
    formatted_mac = ':'.join('{:02X}'.format(b) for b in mac_address)
    print(f"Bluetooth MAC Address: {formatted_mac}")
    
    while True:
        try:
            async with await aioble.advertise(
                2000, name=BLE_NAME, services=[_SERVICE_UUID], appearance=768
            ) as connection:
                connected = True
                print("Connection from", connection.device)
                await connection.disconnected()
        except Exception as e:
            print("Error in peripheral_task:", e)
        finally:
            connected = False
            print(f"{BLE_NAME} disconnected")
            await asyncio.sleep_ms(100)

# Run both tasks
async def main():
    t1 = asyncio.create_task(send_task())
    t2 = asyncio.create_task(peripheral_task())
    await asyncio.gather(t1, t2)

# Run the program
asyncio.run(main())

View raw code

First, we will have to add the library for time.

import time

Then, we need to modify the send_task() function. Basically, once connected, we get the current time and save it in the today message.

today = time.localtime()

The local time will be our message.

message = f"{today}"

Then, we simply need to write the current time on the characteristic like so:

read_characteristic.write(encode_message(message), send_update=True)

Now, it’s easy to understand that you can easily modify the code to send any other useful data like sensor readings or commands to control outputs, for example.

Demonstration

On the Raspberry Pi side, it should have disconnected from the Pico when you run this new code. You need to run the Python code on the Raspberry Pi again right after running the code on the Pico.

After a while, it will be connected and start sending the messages.

On the Raspberry Pi side, it will receive the time sent from the Pico. The timestamp should be printed in the terminal window.

RPi Receive Time From Pico via BLE

Wrapping up

In this tutorial, we learned the basics of BLE and how to set up the Pi to interact with the Pico.

We’re planning to create more tutorials about this subject. Specifically, cover bidirectional communication so that both devices can send and receive data at the same time.

Meanwhile, here are some challenges if you’d like to take this example further:

  • Have the Pi read the values of the Pico’s internal temperature sensor.
  • Add an external temperature sensor like the BME280 to the Pico and have the Pi read back the temperature values.
  • For an added challenge, add an I2C-based LCD screen on the Pi to display the temperatures rather than simply printing the values in the terminal.

We hope you’ve found this tutorial useful.

Special thanks to our reader Edgardo Peregrino, who created and wrote the layout for this tutorial as well as the example codes.

Edgardo Peregrino is the author of “Programming Raspberry Pi in 30 Days” and “Cloud Powered Robotics with Raspberry Pi” and writer of several articles especially in Servo Magazine. You can check his work here on its GitHub page or YouTube channel (LinuxRobotGeek).

Learn more about the Raspberry Pi Pico and the Raspberry Pi:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

1 thought on “BLE Communication between Raspberry Pi and Raspberry Pi Pico W”

  1. Hello, a very good tutorial, works perfectly, a question, how to control the LED of my PI with an android application and BLE, using python? Thank you

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.