{"id":170547,"date":"2025-08-07T14:03:22","date_gmt":"2025-08-07T14:03:22","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=170547"},"modified":"2025-08-07T14:03:25","modified_gmt":"2025-08-07T14:03:25","slug":"raspberry-pi-pico-w-bluetooth-low-energy-micropython","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-bluetooth-low-energy-micropython\/","title":{"rendered":"Raspberry Pi Pico W: Bluetooth Low Energy (BLE) with MicroPython"},"content":{"rendered":"\n<p>The Raspberry Pi Pico W (and 2 W) supports Bluetooth Low Energy, which can be useful in several IoT and automation projects. This article is a getting-started guide on how to use Bluetooth Low Energy with the Raspberry Pi Pico. We&#8217;ll cover how to set the Raspberry Pi Pico as a BLE peripheral and as a BLE central device.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/Raspberry-Pi-Pico-BLE-Getting-Started.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico W: Getting Started with Bluetooth Low Energy BLE MicroPython\" class=\"wp-image-170628\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/Raspberry-Pi-Pico-BLE-Getting-Started.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/Raspberry-Pi-Pico-BLE-Getting-Started.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/Raspberry-Pi-Pico-BLE-Getting-Started.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/Raspberry-Pi-Pico-BLE-Getting-Started.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/Raspberry-Pi-Pico-BLE-Getting-Started.jpg?resize=1536%2C864&amp;quality=100&amp;strip=all&amp;ssl=1 1536w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>New to the Raspberry Pi Pico? Check out our eBook: <strong><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-micropython-ebook\/\">Learn Raspberry Pi Pico\/Pico W with MicroPython<\/a><\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites \u2013 MicroPython Firmware<\/h2>\n\n\n\n<p>To follow this tutorial, you need MicroPython firmware installed on your Raspberry Pi Pico board. You also need an IDE to write and upload the code to your board.<\/p>\n\n\n\n<p>The recommended MicroPython IDE for the Raspberry Pi Pico is Thonny IDE. Follow the next tutorial to learn how to install Thonny IDE, flash MicroPython firmware, and upload code to the board.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-raspberry-pi-pico-w\/#install-thonny-ide\">Programming Raspberry Pi Pico using MicroPython<\/a><\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Bluetooth with the Raspberry Pi Pico W<\/h1>\n\n\n\n<p>The Raspberry Pi Pico W and Raspberry Pi Pico 2 W come with an Infineon CYW43439 chip that adds  Wi-Fi and Bluetooth support.<\/p>\n\n\n\n<p>This tutorial is only compatible with the W versions of the Raspberry Pi Pico:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/raspberry-pi-pico-w\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Raspberry Pi Pico W<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/raspberry-pi-pico-2-w\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Raspberry Pi Pico 2 W<\/a><\/li>\n<\/ul>\n\n\n\n<p>The documentation mentions it supports both Bluetooth Classic and Bluetooth Low Energy. However, I couldn&#8217;t find examples for Bluetooth Classic with MicroPython at the moment. So, our examples will be focusing on Bluetooth Low Energy.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-2-Blink-LED-OFF.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico W onboard LED off\" class=\"wp-image-169993\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-2-Blink-LED-OFF.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-2-Blink-LED-OFF.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><figcaption class=\"wp-element-caption\">Raspberry Pi Pico 2 W<\/figcaption><\/figure><\/div>\n\n\n<p>MicroPython support for Bluetooth with the Pico W is relatively recent, so there is still little support in terms of examples, libraries, documentation, and functionality. Additionally, some libraries are still in beta version, and either they don&#8217;t have all their methods developed, or they don&#8217;t provide examples or documentation, or have bugs or issues. So, at the moment, take that into account when dealing with Bluetooth on the Raspberry Pi Pico. Nonetheless, we&#8217;ll provide you with some essential information and basic working examples that we could run and test that will help you get started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is Bluetooth Low Energy?<\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"400\" height=\"129\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/03\/Bluetooth-low-energy.png?resize=400%2C129&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Bluetooth Low Energy\" class=\"wp-image-95092\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/03\/Bluetooth-low-energy.png?w=400&amp;quality=100&amp;strip=all&amp;ssl=1 400w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/03\/Bluetooth-low-energy.png?resize=300%2C97&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/figure><\/div>\n\n\n<p>Bluetooth Low Energy, BLE for short (also called Bluetooth Smart), is a power\u2011conserving variant of Bluetooth. BLE\u2019s primary application is short-distance transmission of small amounts of data (low bandwidth). Unlike Bluetooth, which is always on, BLE remains in sleep mode constantly except for when a connection is initiated. This makes it consume very little power. BLE consumes approximately 100x less power than Bluetooth (depending on the use case).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bluetooth Low Energy Basic Concepts<\/h2>\n\n\n\n<p>Before proceeding, it\u2019s important to get familiar with some basic BLE concepts<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">BLE Peripheral and Controller (Central Device)<\/h3>\n\n\n\n<p>When using Bluetooth Low Energy (BLE), it\u2019s important to understand the roles of BLE Peripheral and BLE Controller (also referred to as the Central Device).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"459\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Peripheral-and-controler-RPi-PicoW.png?resize=750%2C459&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BLE Peripheral and Controller - Example with a RPi Pico as BLE Peripheral\" class=\"wp-image-170567\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Peripheral-and-controler-RPi-PicoW.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Peripheral-and-controler-RPi-PicoW.png?resize=300%2C184&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The Pico W can act either as a Peripheral or as a central device. When it acts as a peripheral it sets up a GATT profile and advertises its service with characteristics that the central devices can read. On the other hand, when it is set as a central device, it can connect to other BLE devices to read or interact with their profiles and read their characteristics.<\/p>\n\n\n\n<p>In the above diagram, the Pico takes the role of the BLE Peripheral, serving as the device that provides data or services. Your smartphone or computer acts as the BLE Controller, managing the connection and communication with the Pico.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">BLE Server and Client<\/h3>\n\n\n\n<p>With Bluetooth Low Energy, there are two types of devices: the server and the client. The Pico can act either as a client or as a server. In the picture below it acts as a server, exposing its GATT structure containing data. The BLE Server acts as a provider of data or services, while the BLE Client consumes or uses these services.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"307\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Server-Client-RPi-Pico.png?resize=750%2C307&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BLE Server and Client- RPi Pico W as the server\" class=\"wp-image-170568\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Server-Client-RPi-Pico.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Server-Client-RPi-Pico.png?resize=300%2C123&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The server advertises its existence, so it can be found by other devices and contains data that the client can read or interact with. The client scans the nearby devices, and when it finds the server, it is looking for, it establishes a connection and can interact with that device by reading or writing to its&nbsp;characteristics.<\/p>\n\n\n\n<p>The BLE server is basically the BLE peripheral before establishing a connection. The BLE Client is the BLE controller before establishing a connection. Many times, these terms are used interchangeably.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">GATT<\/h3>\n\n\n\n<p>GATT, which stands for Generic Attribute Profile, is a fundamental concept in Bluetooth Low Energy (BLE) technology. Essentially, it serves as a blueprint for how BLE devices communicate with each other. Think of it as a structured language that two BLE devices use to exchange information seamlessly.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"466\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-GATT-structure.png?resize=750%2C466&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BLE GATT Structure\" class=\"wp-image-170569\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-GATT-structure.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-GATT-structure.png?resize=300%2C186&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Profile:<\/strong> standard collection of services for a specific use case;<\/li>\n\n\n\n<li><strong>Service:<\/strong> collection of related information, like sensor readings, battery level, heart rate, etc.;<\/li>\n\n\n\n<li><strong>Characteristic:<\/strong> it is where the actual data is saved on the hierarchy (value);<\/li>\n\n\n\n<li><strong>Descriptor:<\/strong> metadata about the data;<\/li>\n\n\n\n<li><strong>Properties:<\/strong> describe how the characteristic value can be interacted with. For example: read, write, notify, broadcast, indicate, etc.<\/li>\n<\/ul>\n\n\n\n<p>Let\u2019s take a more in-depth look at the BLE Service and Characteristics.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">BLE Service<\/h4>\n\n\n\n<p>The top level of the hierarchy is a profile, which is composed of one or more services. Usually, a BLE device contains more than one service, like the battery service and the heart rate service.<\/p>\n\n\n\n<p>Every service contains at least one characteristic. There are predefined services for several types of data defined by the SIG (Bluetooth Special Interest Group) like: Battery Level, Blood Pressure, Heart Rate, Weight Scale, Environmental Sensing, etc. You can check the following link for predefined services:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.bluetooth.com\/specifications\/assigned-numbers\/\" target=\"_blank\" rel=\"noopener\" title=\"\">bluetooth.com\/specifications\/assigned-numbers\/<\/a><\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">UUID<\/h4>\n\n\n\n<p>A UUID is a unique digital identifier used in BLE and GATT to distinguish and locate services, characteristics, and descriptors. It\u2019s like a distinct label that ensures every component in a Bluetooth device has a unique name.<\/p>\n\n\n\n<p>Each service, characteristic, and descriptor has a UUID (Universally Unique Identifier). A UUID is a unique 128-bit (16 bytes) number. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>55072829-bc9e-4c53-938a-74a6d4c78776<\/code><\/pre>\n\n\n\n<p>There are shortened and default UUIDs for services and characteristics specified in the&nbsp;SIG (Bluetooth Special Interest Group). This means that if you have a BLE device that uses the default UUIDs for its services and characteristics, you\u2019ll know exactly how to interact with that device to get or interact with the information you\u2019re looking for.<\/p>\n\n\n\n<p>You can also generate your own custom UUIDs if you don\u2019t want to stick with predefined values or if the data you\u2019re exchanging doesn\u2019t fit in any of the categories.<\/p>\n\n\n\n<p>You can generate custom UUIDs using this&nbsp;<a href=\"https:\/\/www.uuidgenerator.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">UUID generator website<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Communication between BLE Devices<\/h2>\n\n\n\n<p>Here are the usual steps that describe the communication between BLE Devices.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"761\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-Communication-bwtween-BLE-devices.png?resize=750%2C761&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RPi Pico Communication between BLE Devices\" class=\"wp-image-170570\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-Communication-bwtween-BLE-devices.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-Communication-bwtween-BLE-devices.png?resize=296%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 296w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<ol class=\"wp-block-list\">\n<li>The BLE Peripheral (server) advertises its existence.<\/li>\n\n\n\n<li>The BLE Central Device (client) scans for BLE devices.<\/li>\n\n\n\n<li>When the central device finds the peripheral it is looking for, it connects to it.<\/li>\n\n\n\n<li>After connecting, it reads the GATT profile of the peripheral and searches for the service it is looking for (for example: <em>environmental sensing<\/em>).<\/li>\n\n\n\n<li>If it finds the service, it can now interact with the characteristics. For example, reading the temperature value.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Installing the <em>aioble <\/em>Package<\/h2>\n\n\n\n<p>To write code to use Bluetooth with the Raspberry Pi Pico, we\u2019ll install the <span class=\"rnthl rntliteral\">aioble<\/span> package\u2014that\u2019s currently the recommended library to use for BLE communication. Before proceeding to the actual examples, you need to install it on your board.<\/p>\n\n\n\n<p><strong>1) <\/strong>Connect the board to your computer and connect it to Thonny IDE.<\/p>\n\n\n\n<p><strong>2)<\/strong> On Thonny IDE, go to <strong>Tools <\/strong>&gt; <strong>Manage Packages\u2026<\/strong><\/p>\n\n\n\n<p><strong>3) <\/strong>Search for <em>aioble<\/em> and click on the <span class=\"rnthl rntliteral\">aioble<\/span> option.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"464\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/aioble-package-rpi-pico-thonny-ide.png?resize=644%2C464&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install aioble package Thonny ide\" class=\"wp-image-170571\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/aioble-package-rpi-pico-thonny-ide.png?w=644&amp;quality=100&amp;strip=all&amp;ssl=1 644w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/aioble-package-rpi-pico-thonny-ide.png?resize=300%2C216&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/figure><\/div>\n\n\n<p><strong>4)<\/strong> Finally, click the <strong>Install<\/strong> button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"464\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/aioble-package-rpi-pico-thonny-ide-2.png?resize=644%2C464&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install aioble package Thonny ide\" class=\"wp-image-170572\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/aioble-package-rpi-pico-thonny-ide-2.png?w=644&amp;quality=100&amp;strip=all&amp;ssl=1 644w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/aioble-package-rpi-pico-thonny-ide-2.png?resize=300%2C216&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/figure><\/div>\n\n\n<p><strong>5) <\/strong>Wait a few seconds while it installs.<\/p>\n\n\n\n<p>That&#8217;s it. Now you can use the <span class=\"rnthl rntliteral\">aioble<\/span> functions to program the Raspberry Pi Pico.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Raspberry Pi Pico BLE Peripheral and Central Device &#8211; Communication Between Two Boards<\/h2>\n\n\n\n<p>For this example, you need two Raspberry Pi Pico W or 2W boards. We\u2019ll set one board as a BLE peripheral and another as a BLE Central device. You\u2019ll learn how the peripheral device advertises data and how the central device can read data from the peripheral device.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"307\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Server-Client-RPi-Pico.png?resize=750%2C307&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BLE Server and Client- RPi Pico W as the server\" class=\"wp-image-170568\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Server-Client-RPi-Pico.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-Server-Client-RPi-Pico.png?resize=300%2C123&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p><strong>Only have one Raspberry Pi Pico W Board?<\/strong><\/p>\n\n\n\n<p>If you only have one Raspberry Pi Pico W board, you can only test and follow the peripheral device example, but you have to skip the central device.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">BLE Peripheral<\/h3>\n\n\n\n<p>In this example, we\u2019ll create a BLE peripheral with the <em>Environmental Sensing Service<\/em> (a service defined by the SIG) with one characteristic for the <em>temperature<\/em>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Service:<\/strong><em>Environmental Sensing Service<\/em>\n<ul class=\"wp-block-list\">\n<li><strong>Characteristic:<\/strong> <em>Temperature<\/em><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>We\u2019re going to use the default UUIDs for the Environmental Sensing Service and the Temperature characteristic.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Finding the Default UUIDs<\/h3>\n\n\n\n<p><a href=\"https:\/\/www.bluetooth.com\/specifications\/assigned-numbers\/\" target=\"_blank\" rel=\"noreferrer noopener\">If you go to this page<\/a>&nbsp;and open the&nbsp;<a href=\"https:\/\/btprodspecificationrefs.blob.core.windows.net\/assigned-numbers\/Assigned%20Number%20Types\/Assigned_Numbers.pdf\" target=\"_blank\" rel=\"noreferrer noopener\">Assigned Numbers Document (PDF)<\/a>, you\u2019ll find all the default assigned UUID numbers. If you search for the&nbsp;<em>Environmental Sensing Service<\/em>, you\u2019ll find all the permitted characteristics that you can use with that service. You can see that it supports temperature.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"608\" height=\"633\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/environmental-sensing-service-and-characteristics-SIG.png?resize=608%2C633&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Characteristics supported by the environmental sensing service\" class=\"wp-image-170573\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/environmental-sensing-service-and-characteristics-SIG.png?w=608&amp;quality=100&amp;strip=all&amp;ssl=1 608w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/environmental-sensing-service-and-characteristics-SIG.png?resize=288%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 288w\" sizes=\"(max-width: 608px) 100vw, 608px\" \/><\/figure><\/div>\n\n\n<p>There\u2019s a table with the UUIDs for all services. You can see that the UUID for the Environmental Sensing service is&nbsp;<strong>0x181A<\/strong>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"612\" height=\"76\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/environmental-sensing-service-uuid.png?resize=612%2C76&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BLE environmental sensing service UUID\" class=\"wp-image-170574\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/environmental-sensing-service-uuid.png?w=612&amp;quality=100&amp;strip=all&amp;ssl=1 612w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/environmental-sensing-service-uuid.png?resize=300%2C37&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 612px) 100vw, 612px\" \/><\/figure><\/div>\n\n\n<p>Then, search for the temperature characteristic UUIDs. You\u2019ll find a table with the values for all characteristics. The UUID for the temperature is&nbsp;<strong>0x2A6E<\/strong>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"618\" height=\"115\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-temperature-uuid.png?resize=618%2C115&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BLE temperature uuid\" class=\"wp-image-170575\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-temperature-uuid.png?w=618&amp;quality=100&amp;strip=all&amp;ssl=1 618w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/BLE-temperature-uuid.png?resize=300%2C56&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 618px) 100vw, 618px\" \/><\/figure><\/div>\n\n\n<p>In summary, the UUIDs are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Environmental Sensing Service: <strong>0x181A<\/strong>\n<ul class=\"wp-block-list\">\n<li>Temperature Characteristic: <strong>0x2A6E<\/strong><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Code &#8211; Raspberry Pi Pico W as a BLE Peripheral<\/h2>\n\n\n\n<p>The following code sets the Raspberry Pi Pico W or 2 W as a BLE peripheral with the <em>Environmental Sensing Service<\/em> and the <em>Temperature characteristic<\/em>. The BLE device will be writing on the <em>Temperature<\/em> characteristic continuously to update it with the latest temperature and will be advertising its service and characteristic. We\u2019ll get the temperature from the Raspberry Pi Pico on-board temperature sensor (<strong><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-internal-temperature-micropython\/\" title=\"\">you need the picozero package installed<\/a><\/strong>).<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n# Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-w-bluetooth-low-energy-micropython\/\n\nfrom micropython import const\nimport asyncio\nimport aioble\nimport bluetooth\nimport struct\nfrom picozero import pico_temp_sensor\n\n#org.bluetooth.service.environmental_sensing\n_ENV_SENSE_UUID = bluetooth.UUID(0x181A)\n# org.bluetooth.characteristic.temperature\n_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)\n# org.bluetooth.characteristic.gap.appearance.xml\n_ADV_APPEARANCE_GENERIC_THERMOMETER = const(768)\n# How frequently to send advertising beacons.\n_ADV_INTERVAL_MS = 250_000\n\n# Register GATT server.\ntemp_service = aioble.Service(_ENV_SENSE_UUID)\ntemp_characteristic = aioble.Characteristic(\ntemp_service, _ENV_SENSE_TEMP_UUID, read=True, notify=True)\naioble.register_services(temp_service)\n\n# Helper to encode the temperature characteristic encoding\n# (sint16, hundredths of a degree).\ndef _encode_temperature(temp_deg_c):\n    return struct.pack(&quot;&lt;h&quot;, int(temp_deg_c * 100))\n\n# Get temperature and update characteristic\nasync def sensor_task():\n    while True:\n        temperature = pico_temp_sensor.temp\n        temp_characteristic.write(_encode_temperature(temperature), send_update=True)\n        print(temperature)\n        await asyncio.sleep_ms(1000)\n        \n# Serially wait for connections. Don't advertise while a central is connected.\nasync def peripheral_task():\n    while True:\n        try:\n            async with await aioble.advertise(\n                _ADV_INTERVAL_MS,\n                name=&quot;RPi-Pico&quot;,\n                services=[_ENV_SENSE_UUID],\n                appearance=_ADV_APPEARANCE_GENERIC_THERMOMETER,\n                ) as connection:\n                    print(&quot;Connection from&quot;, connection.device)\n                    await connection.disconnected()\n        except asyncio.CancelledError:\n            # Catch the CancelledError\n            print(&quot;Peripheral task cancelled&quot;)\n        except Exception as e:\n            print(&quot;Error in peripheral_task:&quot;, e)\n        finally:\n            # Ensure the loop continues to the next iteration\n            await asyncio.sleep_ms(100)\n\n# Run both tasks\nasync def main():\n    t1 = asyncio.create_task(sensor_task())\n    t2 = asyncio.create_task(peripheral_task())\n    await asyncio.gather(t1, t2)\n    \nasyncio.run(main())\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/BLE_Peripheral.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>This example is based on the <span class=\"rnthl rntliteral\">aioble<\/span> example that you can find <a href=\"https:\/\/github.com\/micropython\/micropython-lib\/tree\/master\/micropython\/bluetooth\/aioble\" target=\"_blank\" rel=\"noopener\" title=\"\">here<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>Let\u2019s take a quick look at the relevant parts of the code for this example.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Include Libraries<\/h4>\n\n\n\n<p>You need to include the <span class=\"rnthl rntliteral\">aioble<\/span> and the <span class=\"rnthl rntliteral\">bluetooth<\/span> libraries to use Bluetooth with the Pico.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>import aioble\nimport bluetooth<\/code><\/pre>\n\n\n\n<p>Our code will be asynchronous. For that, we\u2019ll use the <span class=\"rnthl rntliteral\">asyncio<\/span> library. We recommend following this tutorial to get familiar with asynchronous programming: <a href=\"https:\/\/randomnerdtutorials.com\/micropython-raspberry-pi-pico-asynchronous-programming\/\">Raspberry Pi Pico Asynchronous Programming \u2013 Run Multiple Tasks (MicroPython)<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>import asyncio<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Define UUIDs and Register the GATT Service and Characteristic<\/h4>\n\n\n\n<p>We define the UUIDs for the environmental sensing service and for the temperature characteristic.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># org.bluetooth.service.environmental_sensing\n_ENV_SENSE_UUID = bluetooth.UUID(0x181A)\n\n# org.bluetooth.characteristic.temperature\n_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)<\/code><\/pre>\n\n\n\n<p>Then, register the GATT service and characteristic.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Register GATT server.\ntemp_service = aioble.Service(_ENV_SENSE_UUID)\ntemp_characteristic = aioble.Characteristic(\n    temp_service, _ENV_SENSE_TEMP_UUID, read=True, notify=True\n)\naioble.register_services(temp_service)<\/code><\/pre>\n\n\n\n<p>When setting the characteristic, we set the <span class=\"rnthl rntliteral\"><em>read <\/em>and <em>notify<\/em><\/span> arguments to <span class=\"rnthl rntliteral\">True<\/span>. This defines the way that the central device can interact with the characteristic. It can read the characteristic and be notified when it changes.<\/p>\n\n\n\n<p>To write the actual temperature value to the temperature characteristic, it needs to be in a specific format. The <span class=\"rnthl rntliteral\">_encode_temperature()<\/span> function does that.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>def _encode_temperature(temp_deg_c):\n&nbsp; &nbsp; return struct.pack(\"&lt;h\", int(temp_deg_c * 100))<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Get Temperature and Write on Characteristic<\/h4>\n\n\n\n<p>We have an asynchronous function that gets temperature from the internal temperature sensor and writes to the temperature characteristic using the <span class=\"rnthl rntliteral\">write()<\/span> method on the <span class=\"rnthl rntliteral\">temp_characteristic<\/span>. This task is repeated continuously every second. You can adjust the delay time as needed.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Get temperature and update characteristic\nasync def sensor_task():\n    while True:\n        temperature = pico_temp_sensor.temp\n        temp_characteristic.write(_encode_temperature(temperature), send_update=True)\n        print(temperature)\n        await asyncio.sleep_ms(1000)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Advertising<\/h4>\n\n\n\n<p>Besides writing to the temperature characteristic, we also need to advertise the Raspberry Pi Pico as a BLE service. For that, we use the <span class=\"rnthl rntliteral\">peripheral_task()<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Serially wait for connections. Don't advertise while a central is connected.\nasync def peripheral_task():\n    while True:\n        try:\n            async with await aioble.advertise(\n                _ADV_INTERVAL_MS,\n                name=\"RPi-Pico\",\n                services=&#091;_ENV_SENSE_UUID],\n                appearance=_ADV_APPEARANCE_GENERIC_THERMOMETER,\n            ) as connection:\n                print(\"Connection from\", connection.device)\n                await connection.disconnected()\n        except asyncio.CancelledError:\n            # Catch the CancelledError\n            print(\"Peripheral task cancelled\")\n        except Exception as e:\n            print(\"Error in peripheral_task:\", e)\n        finally:\n            # Ensure the loop continues to the next iteration\n            await asyncio.sleep_ms(100)<\/code><\/pre>\n\n\n\n<p>In that function, we define the BLE device name. <\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>name=\"RPi-Pico\",<\/code><\/pre>\n\n\n\n<p>You can change its name if you want to. In the next example, we\u2019ll connect to this device by referring to its name, so you\u2019ll need to make sure you use the same name in both codes, as we\u2019ll see later.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Main Function<\/h4>\n\n\n\n<p>Finally, we create an asynchronous <span class=\"rnthl rntliteral\">main()<\/span> function, where we\u2019ll write the base for our code. We create two asynchronous tasks: one for advertising and another to write on the temperature characteristic.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Run both tasks.\nasync def main():\n    t1 = asyncio.create_task(sensor_task())\n    t2 = asyncio.create_task(peripheral_task())\n\n    await asyncio.gather(t1, t2)\n\nasyncio.run(main())<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Testing the Code<\/h3>\n\n\n\n<p>Run the previous code on your Raspberry Pi Pico. It will start writing the temperature on the temperature characteristic and will advertise its service.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"674\" height=\"262\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-advertising-BLE-service-thonny-IDE.png?resize=674%2C262&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RPi Pico BLE - start advertising\" class=\"wp-image-170578\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-advertising-BLE-service-thonny-IDE.png?w=674&amp;quality=100&amp;strip=all&amp;ssl=1 674w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-advertising-BLE-service-thonny-IDE.png?resize=300%2C117&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 674px) 100vw, 674px\" \/><\/figure><\/div>\n\n\n<p>To connect to this peripheral, and read its characteristic we\u2019ll create a BLE Central device on another Raspberry Pi Pico board.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">nRF Connect App<\/h4>\n\n\n\n<p>Before proceeding, you can use an app like <strong><em>nRF Connect<\/em><\/strong> to search for BLE devices and read their characteristics.<\/p>\n\n\n\n<p>The <em>nRF Connect<\/em> app from Nordic works on Android (Google Play Store) and iOS (App Store). Go to Google Play Store or App Store, search for \u201c<strong>nRF Connect for Mobile<\/strong>\u201d and install the app on your smartphone.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"541\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/nRF-connect-app-test-BLE-devices.png?resize=250%2C541&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"nRF Connect for Mobile App\" class=\"wp-image-170579\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/nRF-connect-app-test-BLE-devices.png?w=250&amp;quality=100&amp;strip=all&amp;ssl=1 250w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/nRF-connect-app-test-BLE-devices.png?resize=139%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 139w\" sizes=\"(max-width: 250px) 100vw, 250px\" \/><\/figure><\/div>\n\n\n<p>Go to your smartphone, open the <em>nRF Connect app from Nordic<\/em>, and start scanning for new devices. You should find a device called&nbsp;<strong>RPi-Pico<\/strong>\u2014this is the BLE server name you defined earlier.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"541\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/scanning-rpi-pico-BLE-device.png?resize=250%2C541&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Scanning the RPi Pico - BLE Device NRF Connect App\" class=\"wp-image-170605\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/scanning-rpi-pico-BLE-device.png?w=250&amp;quality=100&amp;strip=all&amp;ssl=1 250w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/scanning-rpi-pico-BLE-device.png?resize=139%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 139w\" sizes=\"(max-width: 250px) 100vw, 250px\" \/><\/figure><\/div>\n\n\n<p>Connect to it. You\u2019ll see that it displays the <strong><em>Environmental Sensing<\/em><\/strong> service with the <strong><em>temperature <\/em><\/strong>characteristic. Click on the arrows to read the characteristic and activate the notifications.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"250\" height=\"541\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/rpi-pico-read-characteristic-on-nrf-connect-app.png?resize=250%2C541&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RPi Pico as BLE Device- Read Temperature characteristic on nRF connect app\" class=\"wp-image-170606\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/rpi-pico-read-characteristic-on-nrf-connect-app.png?w=250&amp;quality=100&amp;strip=all&amp;ssl=1 250w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/rpi-pico-read-characteristic-on-nrf-connect-app.png?resize=139%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 139w\" sizes=\"(max-width: 250px) 100vw, 250px\" \/><\/figure><\/div>\n\n\n<p>Then, click on the second icon on the left to change the format (this option may only be available for iPhone, and it will automatically display the temperature in the correct format).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"60\" height=\"60\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/nrf-connect-change-format-icon.png?resize=60%2C60&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"nRF connect app - change format icon\" class=\"wp-image-170608\"\/><\/figure><\/div>\n\n\n<p>You can change the format to Unsigned Int.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"89\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/nrf-connect-change-data-format-unsigned-int.png?resize=500%2C89&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"nRF-connect-change-data-to-unsigned-int\n\" class=\"wp-image-170607\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/nrf-connect-change-data-format-unsigned-int.png?w=500&amp;quality=100&amp;strip=all&amp;ssl=1 500w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/nrf-connect-change-data-format-unsigned-int.png?resize=300%2C53&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/figure>\n\n\n\n<p>You\u2019ll start seeing the temperature values being reported every 10 seconds. It will display the temperature in Celsius multiplied by 100 (on the iPhone).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"659\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-as-bLE-device-read-temperature-value.png?resize=500%2C659&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RPi Pico as a BLE device - read temperature from nRF connect app\" class=\"wp-image-170609\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-as-bLE-device-read-temperature-value.png?w=500&amp;quality=100&amp;strip=all&amp;ssl=1 500w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-as-bLE-device-read-temperature-value.png?resize=228%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 228w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/figure><\/div>\n\n\n<p>Now that we know that our BLE peripheral is working as expected, we can program another Raspberry Pi Pico board as a BLE Central device to read the temperature characteristic from this board.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Code &#8211; Raspberry Pi Pico as a BLE Central Device (BLE Client)<\/h2>\n\n\n\n<p>The following code should be run on another Raspberry Pi Pico board. We\u2019ll set it as a BLE Central device that will look for the <strong>RPi-Pico<\/strong> device, search for the <em>environmental sensing service<\/em>, and read the <em>temperature <\/em>from the characteristic.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n# Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-w-bluetooth-low-energy-micropython\/\n\nfrom micropython import const\nimport uasyncio as asyncio\nimport aioble\nimport bluetooth\nimport struct\n\n# org.bluetooth.service.environmental_sensing\n_ENV_SENSE_UUID = bluetooth.UUID(0x181A)\n# org.bluetooth.characteristic.temperature\n_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)\n\n# Name of the peripheral you want to connect\nperipheral_name=&quot;RPi-Pico&quot;\n\n# Helper to decode the temperature characteristic encoding (sint16, hundredths of a degree).\ndef _decode_temperature(data):\n    try:\n        if data is not None:\n            return struct.unpack(&quot;&lt;h&quot;, data)[0] \/ 100\n    except Exception as e:\n        print(&quot;Error decoding temperature:&quot;, e)\n    return None\n\nasync def find_temp_sensor():\n    # Scan for 5 seconds, in active mode, with a very low interval\/window (to\n    # maximize detection rate).\n    async with aioble.scan(5000, interval_us=30000, window_us=30000, active=True) as scanner:\n        async for result in scanner:\n            print(result.name())\n            # See if it matches our name and the environmental sensing service.\n            if result.name() == peripheral_name and _ENV_SENSE_UUID in result.services():\n                return result.device\n    return None\n\nasync def main():\n    while True:\n        device = await find_temp_sensor()\n        if not device:\n            print(&quot;Temperature sensor not found. Retrying...&quot;)\n            await asyncio.sleep_ms(5000)  # Wait for 5 seconds before retrying\n            continue\n\n        try:\n            print(&quot;Connecting to&quot;, device)\n            connection = await device.connect()\n        except asyncio.TimeoutError:\n            print(&quot;Timeout during connection. Retrying...&quot;)\n            await asyncio.sleep_ms(5000)  # Wait for 5 seconds before retrying\n            continue\n\n        async with connection:\n            try:\n                temp_service = await connection.service(_ENV_SENSE_UUID)\n                temp_characteristic = await temp_service.characteristic(_ENV_SENSE_TEMP_UUID)\n            except asyncio.TimeoutError:\n                print(&quot;Timeout discovering services\/characteristics. Retrying...&quot;)\n                await asyncio.sleep_ms(5000)  # Wait for 5 seconds before retrying\n                continue\n\n            while True:\n                try:\n                    temp_data = await temp_characteristic.read()\n                    if temp_data is not None:\n                        temp_deg_c = _decode_temperature(temp_data)\n                        if temp_deg_c is not None:\n                            print(&quot;Temperature: {:.2f}&quot;.format(temp_deg_c))\n                        else:\n                            print(&quot;Invalid temperature data&quot;)\n                    else:\n                        print(&quot;Error reading temperature: None&quot;)\n                except Exception as e:\n                    print(&quot;Error in main loop:&quot;, e)\n                    break  # Break out of the inner loop and attempt to reconnect\n\n                await asyncio.sleep_ms(1000)\n\n# Create an Event Loop\nloop = asyncio.get_event_loop()\n# Create a task to run the main function\nloop.create_task(main())\n\ntry:\n    # Run the event loop indefinitely\n    loop.run_forever()\nexcept Exception as e:\n    print('Error occurred: ', e)\nexcept KeyboardInterrupt:\n    print('Program Interrupted by the user')\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/BLE_Client.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>This example is based on the <span class=\"rnthl rntliteral\">aioble<\/span> example that you can find <a href=\"https:\/\/github.com\/micropython\/micropython-lib\/tree\/master\/micropython\/bluetooth\/aioble\" target=\"_blank\" rel=\"noopener\" title=\"\">here<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How the Code Works<\/h2>\n\n\n\n<p>Let\u2019s take a quick look at the relevant parts of the code for this example.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Include Libraries<\/h4>\n\n\n\n<p>You need to include the <span class=\"rnthl rntliteral\">aioble<\/span> and the <span class=\"rnthl rntliteral\">bluetooth<\/span> libraries to use Bluetooth with the Pico.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>import aioble\nimport bluetooth<\/code><\/pre>\n\n\n\n<p>Our code will be asynchronous. For that, we\u2019ll use the <span class=\"rnthl rntliteral\">asyncio<\/span> library. We recommend following this tutorial to get familiar with asynchronous programming: <a href=\"https:\/\/randomnerdtutorials.com\/micropython-raspberry-pi-pico-asynchronous-programming\/\">Raspberry Pi Pico Asynchronous Programming \u2013 Run Multiple Tasks (MicroPython)<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>import asyncio<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Define UUIDs<\/h4>\n\n\n\n<p>We define the UUIDs for the environmental sensing service and for the temperature characteristic that we want to read.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted language-python\"># org.bluetooth.service.environmental_sensing\n_ENV_SENSE_UUID = bluetooth.UUID(0x181A)\n\n# org.bluetooth.characteristic.temperature\n_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">BLE Device Name We Want to Connect To<\/h4>\n\n\n\n<p>Then, we define the name of the BLE device that we want to connect to. It must be the name of the BLE peripheral you set up previously, in our case <strong>RPi-Pico<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Name of the peripheral you want to connect\nperipheral_name=\"RPi-Pico\"<\/code><\/pre>\n\n\n\n<p>The temperature is saved on a characteristic in a specific format. To help us transform that value into a value that we can read, we use the <span class=\"rnthl rntliteral\">_decode_temperature()<\/span> function.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Helper to decode the temperature characteristic encoding\n# (sint16, hundredths of a degree).\ndef _decode_temperature(data):\n&nbsp; &nbsp; try:\n&nbsp; &nbsp; &nbsp; &nbsp; if data is not None:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return struct.unpack(\"&lt;h\", data)&#091;0] \/ 100\n&nbsp; &nbsp; except Exception as e:\n&nbsp; &nbsp; &nbsp; &nbsp; print(\"Error decoding temperature:\", e)\n&nbsp; &nbsp; return None<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Scanning and Searching for BLE Devices<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">find_temp_sensor()<\/span> function will scan for nearby BLE devices and when it finds the BLE device with the name we\u2019ve defined previously, it returns that BLE device with <span class=\"rnthl rntliteral\">result.device<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>async def find_temp_sensor():\n&nbsp; &nbsp; # Scan for 5 seconds, in active mode, with a very low interval\/window\n&nbsp;&nbsp;&nbsp; # (to maximize detection rate)\n&nbsp; &nbsp; async with aioble.scan(5000, interval_us=30000, window_us=30000, active=True) as scanner:\n&nbsp; &nbsp; &nbsp; &nbsp; async for result in scanner:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(result.name())\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # See if it matches our name and the environmental sensing service.\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if result.name() == peripheral_name and _ENV_SENSE_UUID in result.services():\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return result.device\n&nbsp; &nbsp; return None<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Main Function<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">main()<\/span> async function, we first try to find the BLE device we\u2019re looking for by calling the <span class=\"rnthl rntliteral\">find_temp_sensor()<\/span>. We save the BLE device on the <span class=\"rnthl rntliteral\">device<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>device = await find_temp_sensor()<\/code><\/pre>\n\n\n\n<p>Then, we try to connect to that device:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>try:\n&nbsp;&nbsp;&nbsp; print(\"Connecting to\", device)\n&nbsp; &nbsp; connection = await device.connect()<\/code><\/pre>\n\n\n\n<p>After getting a successful connection, we get the temperature service on the <span class=\"rnthl rntliteral\">temp_service<\/span> variable. After that, we use that service to get the characteristic we\u2019re looking for and save it on the <span class=\"rnthl rntliteral\">temp_characteristic<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>async with connection:\n&nbsp;&nbsp;&nbsp; try:\n&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;temp_service = await connection.service(_ENV_SENSE_UUID)\n&nbsp; &nbsp; &nbsp; &nbsp; temp_characteristic = await temp_service.characteristic(_ENV_SENSE_TEMP_UUID)<\/code><\/pre>\n\n\n\n<p>Finally, we can get the temperature value by reading the characteristic <span class=\"rnthl rntliteral\">temp_characteristic.read()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>while True:\n&nbsp;&nbsp;&nbsp; try:\n&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;temp_data = await temp_characteristic.read()\n&nbsp; &nbsp; &nbsp; &nbsp; if temp_data is not None:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;temp_deg_c = _decode_temperature(temp_data)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if temp_deg_c is not None:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(\"Temperature: {:.2f}\".format(temp_deg_c))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;print(\"Invalid temperature data\")\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else:\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;print(\"Error reading temperature: None\")\n&nbsp; &nbsp; &nbsp; except Exception as e:\n&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;print(\"Error in main loop:\", e)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break &nbsp;# Break out of the inner loop and attempt to reconnect\n&nbsp; &nbsp; &nbsp;await asyncio.sleep_ms(1000)<\/code><\/pre>\n\n\n\n<p>We create an event loop and associate the <span class=\"rnthl rntliteral\">main()<\/span> task to that event.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Create an Event Loop\nloop = asyncio.get_event_loop()\n# Create a task to run the main function\nloop.create_task(main())<\/code><\/pre>\n\n\n\n<p>Finally, we run the event loop to keep our code running.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Run the event loop indefinitely\nloop.run_forever()<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Testing the Code<\/h3>\n\n\n\n<p>For testing this code, it will be useful to have two instances of Thonny IDE running so that we can run code on both devices and see the console for both connections.<\/p>\n\n\n\n<p>To activate multiple instances of Thonny IDE, go to <strong>Tools<\/strong> &gt; <strong>Options<\/strong> and <u>untick<\/u> the <em>Allow only single Thonny instance<\/em> option.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"561\" height=\"558\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/thonny-ide-allow-multiple-instances.png?resize=561%2C558&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Thonny IDE allow multiple instances\" class=\"wp-image-170610\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/thonny-ide-allow-multiple-instances.png?w=561&amp;quality=100&amp;strip=all&amp;ssl=1 561w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/thonny-ide-allow-multiple-instances.png?resize=300%2C298&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/thonny-ide-allow-multiple-instances.png?resize=150%2C150&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 561px) 100vw, 561px\" \/><\/figure><\/div>\n\n\n<p>Close Thonny for the changes to take effect. Then, simply open Thonny IDE on your computer twice to open two windows.<\/p>\n\n\n\n<p>Make sure you have each window connected to the right board. You can select the COM port at the bottom right corner.<\/p>\n\n\n\n<p>After having the BLE peripheral device running (make sure it is advertising the temperature), copy the code provided in this section to the other Thonny IDE instance (make sure it is connected to the right COM port). Then, run it on this new board.<\/p>\n\n\n\n<p>It will start scanning for BLE devices. When it finds the <strong>RPi-Pico <\/strong>device, it will connect to it and display the temperature values sent by the other board on the Shell.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"752\" height=\"607\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-BLE-Client-Reading-Characteristic-Thonny-IDE.png?resize=752%2C607&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RPi Pico as a BLE Client Reading BLE Characteristic and displaying it on the Thonny IDE shell\" class=\"wp-image-170611\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-BLE-Client-Reading-Characteristic-Thonny-IDE.png?w=752&amp;quality=100&amp;strip=all&amp;ssl=1 752w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/RPi-Pico-BLE-Client-Reading-Characteristic-Thonny-IDE.png?resize=300%2C242&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 752px) 100vw, 752px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you learned the basics of Bluetooth Low Energy with the Raspberry Pi Pico when programmed with MicroPython. You learned how to set the Pico as a BLE Central Device and as a BLE Peripheral Device. You learned how to set and read characteristic values.<\/p>\n\n\n\n<p>To <span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">fu<\/span>rther develop this project, you can add a&nbsp;BME280&nbsp;or&nbsp;another sensor&nbsp;of your choice and display temperature, humidity, and pressure characteristics. You can also add an <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-ssd1306-oled-micropython\/\" title=\"\">OLED <\/a>or <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-i2c-lcd-display-micropython\/\" title=\"\">LCD<\/a> to the BLE Central device to display the readings from the other board.<\/p>\n\n\n\n<p><strong>More BLE Resources<\/strong><\/p>\n\n\n\n<p>To explore more about Bluetooth, you can take a look at the following resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bluetooth Documentation for MicroPython (low-level functions):\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.micropython.org\/en\/latest\/library\/bluetooth.html\" target=\"_blank\" rel=\"noopener\" title=\"\">docs.micropython.org\/en\/latest\/library\/bluetooth.html<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>MicroPython Bluetooth examples (low-level functions):\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/micropython\/micropython\/tree\/master\/examples\/bluetooth\" target=\"_blank\" rel=\"noopener\" title=\"\">github.com\/micropython\/micropython\/tree\/master\/examples\/bluetooth<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><span class=\"rnthl rntliteral\">aioble<\/span> library page with examples:<ul class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/micropython\/micropython-lib\/tree\/master\/micropython\/bluetooth\/aioble\" target=\"_blank\" rel=\"noopener\" title=\"\">github.com\/micropython\/micropython-lib\/tree\/master\/micropython\/bluetooth\/aioble<\/a><\/li><\/ul><\/li>\n<\/ul>\n\n\n\n<p>If you want to learn more about the Raspberry Pi Pico, check out our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-micropython-ebook\/\">Learn Raspberry Pi Pico\/Pico W with MicroPython<\/a>&nbsp;(eBook)<\/strong><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-raspberry-pi-pico\/\">Free Raspberry Pi Pico projects and tutorials<\/a><\/li>\n<\/ul>\n\n\n\n<p>We hope you&#8217;ve found this guide useful. We have similar guides for the ESP32 boards:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-esp32-bluetooth-low-energy-ble\/\">MicroPython: ESP32 \u2013 Getting Started with Bluetooth Low Energy (BLE)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-bluetooth-low-energy-ble-arduino-ide\/\">Getting Started with ESP32 Bluetooth Low Energy (BLE) on Arduino IDE<\/a><\/li>\n<\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Raspberry Pi Pico W (and 2 W) supports Bluetooth Low Energy, which can be useful in several IoT and automation projects. This article is a getting-started guide on how &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Raspberry Pi Pico W: Bluetooth Low Energy (BLE) with MicroPython\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-bluetooth-low-energy-micropython\/#more-170547\" aria-label=\"Read more about Raspberry Pi Pico W: Bluetooth Low Energy (BLE) with MicroPython\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":170628,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[324,326],"tags":[],"class_list":["post-170547","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi-pico","category-raspberry-pi-pico-micropython"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/05\/Raspberry-Pi-Pico-BLE-Getting-Started.jpg?fit=1920%2C1080&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/170547","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=170547"}],"version-history":[{"count":8,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/170547\/revisions"}],"predecessor-version":[{"id":175219,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/170547\/revisions\/175219"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/170628"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=170547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=170547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=170547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}