Raspberry Pi Pico W (dan Pico 2 W) telah dilengkapi dukungan Bluetooth Low Energy (BLE), sehingga sangat cocok digunakan pada berbagai aplikasi Internet of Things (IoT) dan sistem otomasi. Artikel ini menyajikan panduan dasar mengenai implementasi BLE pada Raspberry Pi Pico, termasuk cara mengonfigurasikan perangkat sebagai BLE peripheral maupun BLE central.
Firmware MicroPython
Sebelum memulai, pastikan Raspberry Pi Pico Anda telah terpasang firmware MicroPython. Anda juga memerlukan sebuah Integrated Development Environment (IDE) untuk menulis, menjalankan, dan mengunggah program ke papan tersebut.
Untuk pengembangan berbasis MicroPython pada Raspberry Pi Pico, Thonny IDE merupakan pilihan yang paling direkomendasikan. Pada bagian selanjutnya, Anda akan mempelajari langkah-langkah instalasi Thonny IDE, proses flashing firmware MicroPython, serta cara mengunggah kode ke perangkat secara tepat.
Bluetooth dengan Raspberry Pi Pico W
Dukungan MicroPython terhadap fitur Bluetooth pada Raspberry Pi Pico W masih tergolong baru, sehingga ketersediaan contoh implementasi, pustaka pendukung, dokumentasi, dan stabilitas fungsionalitas masih terbatas. Beberapa pustaka yang tersedia juga berada pada tahap beta, dengan metode yang belum sepenuhnya matang, minim dokumentasi atau contoh penggunaan, serta berpotensi mengandung bug. Oleh karena itu, aspek-aspek tersebut perlu diperhatikan saat mengembangkan aplikasi berbasis Bluetooth pada Raspberry Pi Pico. Meskipun demikian, artikel ini tetap menyajikan informasi dasar dan contoh implementasi yang telah diuji untuk membantu Anda memulai pengembangan.
Apa itu Bluetooth Hemat Energi?
Gambar Bluetooth Hemat Energi
Bluetooth Low Energy (BLE), atau sering disebut Bluetooth Smart, merupakan varian Bluetooth yang dirancang untuk operasi berdaya rendah. BLE dioptimalkan untuk pertukaran data jarak dekat dengan ukuran dan throughput yang minimal. Berbeda dengan Bluetooth klasik yang beroperasi secara kontinu, BLE mempertahankan perangkat dalam keadaan sleep mode dan hanya aktif saat proses komunikasi diperlukan. Mekanisme ini memungkinkan konsumsi daya yang sangat efisien, bahkan dapat mencapai hingga 100 kali lebih rendah dibandingkan Bluetooth konvensional, bergantung pada skenario penggunaan.
Konsep Dasar Bluetooth Hemat Energi
Sebelum melanjutkan, penting untuk memahami beberapa konsep dasar BLE.
Periferal dan Pengontrol BLE (Perangkat Pusat)
Saat menggunakan Bluetooth Hemat Energi (BLE), penting untuk memahami peran Periferal BLE dan Pengontrol BLE (juga disebut sebagai Perangkat Pusat).
Raspberry Pi Pico W dapat beroperasi sebagai BLE Peripheral maupun BLE Central. Dalam mode Peripheral, perangkat bertugas menyediakan profil GATT, mengiklankan layanan (services) beserta karakteristiknya (characteristics), dan menunggu perangkat Central untuk melakukan koneksi serta membaca data. Sebaliknya, ketika berfungsi sebagai Central, Pico W dapat memindai, terhubung, dan berinteraksi dengan perangkat BLE lain untuk mengakses profil dan karakteristik yang mereka sediakan.
Pada ilustrasi di atas, Pico W dikonfigurasikan sebagai BLE Peripheral, sehingga bertindak sebagai penyedia data atau layanan. Sementara itu, ponsel atau komputer Anda berperan sebagai BLE Central, yang menginisiasi koneksi serta mengelola komunikasi dengan perangkat Pico.
Server dan Klien BLE
Dalam arsitektur Bluetooth Low Energy, terdapat dua peran utama perangkat: GATT Server dan GATT Client. Raspberry Pi Pico W dapat dikonfigurasi untuk menjalankan salah satu dari kedua peran tersebut. Pada ilustrasi berikut, Pico berfungsi sebagai GATT Server, yang menyediakan struktur GATT berisi layanan (services) dan karakteristik (characteristics) sebagai sumber data. Sementara itu, GATT Client bertugas mengakses, membaca, atau memanfaatkan layanan yang dipublikasikan oleh server.
Perangkat GATT Server melakukan proses advertising untuk mengumumkan keberadaannya sehingga dapat dideteksi oleh perangkat lain, serta menyediakan layanan dan karakteristik yang dapat diakses atau diinteraksikan oleh klien. Sementara itu, GATT Client melakukan scanning untuk mencari perangkat di sekitarnya, dan ketika menemukan server yang sesuai, klien akan membangun koneksi dan berinteraksi dengan server melalui operasi pembacaan (read) atau penulisan (write) pada karakteristik yang tersedia.
Pada praktiknya, BLE Peripheral umumnya berperan sebagai GATT Server sebelum koneksi terjalin, sedangkan BLE Central biasanya bertindak sebagai GATT Client. Kedua istilah tersebut sering digunakan secara bergantian bergantung pada konteks implementasi.
GATT
GATT (Generic Attribute Profile) merupakan kerangka dasar dalam arsitektur Bluetooth Low Energy (BLE) yang mendefinisikan tata cara pertukaran data antarperangkat. Secara fundamental, GATT menetapkan struktur, format, serta prosedur komunikasi yang memungkinkan dua perangkat BLE berinteraksi secara terorganisasi. Dengan demikian, GATT berfungsi sebagai protokol atribut terstruktur yang menjadi acuan utama dalam proses transmisi data di lingkungan BLE.
- Profil: kumpulan layanan standar untuk kasus penggunaan tertentu;
- Layanan: kumpulan informasi terkait, seperti pembacaan sensor, level baterai, detak jantung, dll.;
- Karakteristik: tempat data aktual disimpan dalam hierarki (nilai);
- Deskriptor: metadata tentang data;
- Properti: menjelaskan bagaimana nilai karakteristik dapat berinteraksi. Misalnya: membaca, menulis, memberi tahu, menyiarkan, menunjukkan, dll.
1. Layanan BLE
Pada tingkat hierarki tertinggi terdapat profile, yang merupakan kumpulan dari satu atau lebih services. Sebuah perangkat BLE umumnya mengimplementasikan beberapa services sekaligus, misalnya Battery Service atau Heart Rate Service. Setiap service terdiri atas setidaknya satu characteristic. Sejumlah services telah distandardisasi oleh Bluetooth Special Interest Group (SIG), mencakup berbagai kategori data seperti Battery Level, Blood Pressure, Heart Rate, Weight Scale, Environmental Sensing, dan lain-lain. Daftar lengkap standardized services dapat diakses melalui referensi resmi yang disediakan oleh Bluetooth SIG.
- bluetooth.com/specifications/assigned-numbers/
2. UUID
UUID (Universally Unique Identifier) merupakan identifikasi digital unik yang digunakan dalam arsitektur BLE dan GATT untuk membedakan setiap service, characteristic, maupun descriptor. UUID berfungsi sebagai label identitas yang memastikan setiap elemen dalam struktur BLE memiliki penanda yang benar-benar unik. Setiap service, characteristic, dan descriptor wajib memiliki UUID. Secara standar, UUID direpresentasikan sebagai nilai 128-bit (16 byte) yang menjamin tingkat keunikan tinggi. Contoh representasi UUID adalah sebagai berikut:
55072829-bc9e-4c53-938a-74a6d4c78776
Terdapat UUID standar yang telah ditetapkan oleh Bluetooth Special Interest Group (SIG) untuk berbagai services dan characteristics. Dengan menggunakan UUID standar tersebut, perangkat BLE dapat berinteroperasi secara konsisten, karena mekanisme akses serta format datanya telah didefinisikan secara jelas. Selain itu, pengembang juga dapat membuat UUID kustom apabila data atau layanan yang diimplementasikan tidak sesuai dengan kategori yang tersedia dalam standar SIG, atau ketika diperlukan identifikasi yang lebih spesifik. Pembuatan UUID kustom dapat dilakukan menggunakan berbagai UUID generator yang tersedia secara daring.
Komunikasi Antarperangkat BLE
Berikut ini adalah tahapan umum yang menggambarkan proses komunikasi antara perangkat Bluetooth Low Energy:
1. BLE Peripheral (bertindak sebagai GATT Server) melakukan advertising untuk mengumumkan keberadaannya.
2. BLE Central (bertindak sebagai GATT Client) melakukan scanning untuk mendeteksi perangkat BLE di sekitarnya.
3. Setelah Central menemukan Peripheral yang sesuai, ia membangun koneksi (connection establishment).
4. Setelah koneksi terbentuk, Central melakukan pembacaan struktur GATT yang dimiliki Peripheral untuk mengidentifikasi layanan yang relevan (misalnya Environmental Sensing Service).
5. Jika layanan yang diinginkan tersedia, Central dapat melakukan operasi pada karakteristik terkait, seperti membaca nilai suhu atau parameter sensor lainnya.
Memasang Paket aioble
Untuk mengimplementasikan fungsionalitas Bluetooth pada Raspberry Pi Pico, diperlukan instalasi paket aioble, yaitu pustaka MicroPython yang direkomendasikan untuk komunikasi BLE. Sebelum menjalankan contoh kode, pastikan pustaka tersebut telah terpasang pada papan Anda.
1. Hubungkan Raspberry Pi Pico ke komputer dan buka sesi pengembangan melalui Thonny IDE.
2. Pada Thonny, navigasikan ke Tools > Manage Packages….
3. Lakukan pencarian kata kunci aioble, kemudian pilih entri pustaka aioble dari daftar hasil.
Gambar
4. Klik tombol Install untuk memulai proses instalasi.
Gambar
5. Tunggu hingga proses instalasi selesai dan pustaka berhasil ditambahkan ke sistem.
Setelah instalasi selesai, Anda dapat mulai memanfaatkan fungsi dan modul yang disediakan oleh aioble untuk merancang program BLE pada Raspberry Pi Pico.
Periferal dan Perangkat Sentral BLE Raspberry Pi Pico – Komunikasi Antar Dua Papan
Untuk demonstrasi ini, diperlukan dua unit Raspberry Pi Pico W atau Pico 2 W. Satu perangkat akan dikonfigurasi sebagai BLE Peripheral, sementara perangkat lainnya berfungsi sebagai BLE Central. Melalui contoh ini, Anda akan mempelajari mekanisme pengiriman data dari Peripheral serta proses pembacaan data oleh Central dari perangkat tersebut.
Hanya memiliki satu Raspberry Pi Pico W?
Apabila Anda hanya memiliki satu unit Raspberry Pi Pico W, Anda tetap dapat menjalankan dan menguji contoh untuk konfigurasi Peripheral. Namun, bagian yang terkait dengan implementasi Central tidak dapat dieksekusi dan perlu dilewati.
Periferal BLE
Pada contoh ini, akan dikonfigurasikan sebuah BLE Peripheral yang menyediakan Environmental Sensing Service (ESS), yaitu salah satu layanan standar yang ditetapkan oleh Bluetooth SIG. Di dalam layanan tersebut, kita mendefinisikan satu characteristic untuk parameter suhu.
- Service: Environmental Sensing Service (ESS)
- Characteristic: Temperature
Implementasi ini akan memanfaatkan UUID standar yang telah ditetapkan oleh SIG untuk layanan ESS dan karakteristik suhu.
Menemukan UUID Default
Dengan membuka dokumen Assigned Numbers yang diterbitkan oleh Bluetooth SIG, Anda dapat melihat daftar lengkap UUID standar yang telah ditetapkan. Pada bagian Environmental Sensing Service (ESS), ditampilkan seluruh karakteristik yang didukung oleh layanan tersebut, termasuk karakteristik untuk parameter suhu.
Gambar
Pada tabel Assigned Services, layanan Environmental Sensing tercatat memiliki UUID 0x181A.
Gambar
Selanjutnya, pada tabel Assigned Characteristics, karakteristik suhu (*Temperature*) ditetapkan dengan UUID 0x2A6E.
Gambar
Ringkasan UUID:
- Environmental Sensing Service: 0x181A
- Temperature Characteristic: 0x2A6E
Kode – Raspberry Pi Pico W sebagai Periferal BLE
Kode berikut mengonfigurasi Raspberry Pi Pico W atau Pico 2 W sebagai BLE Peripheral yang menyediakan Environmental Sensing Service beserta Temperature Characteristic. Perangkat akan melakukan pembaruan nilai pada karakteristik suhu secara kontinu, kemudian mengiklankan (advertise) layanan dan karakteristik tersebut agar dapat diakses oleh perangkat Central. Nilai suhu diperoleh dari sensor suhu internal Raspberry Pi Pico, yang memerlukan instalasi pustaka `picozero`.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-w-bluetooth-low-energy-micropython/
from micropython import const
import asyncio
import aioble
import bluetooth
import struct
from picozero import pico_temp_sensor
#org.bluetooth.service.environmental_sensing
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
# org.bluetooth.characteristic.temperature
_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)
# org.bluetooth.characteristic.gap.appearance.xml
_ADV_APPEARANCE_GENERIC_THERMOMETER = const(768)
# How frequently to send advertising beacons.
_ADV_INTERVAL_MS = 250_000
# Register GATT server.
temp_service = aioble.Service(_ENV_SENSE_UUID)
temp_characteristic = aioble.Characteristic(
temp_service, _ENV_SENSE_TEMP_UUID, read=True, notify=True)
aioble.register_services(temp_service)
# Helper to encode the temperature characteristic encoding
# (sint16, hundredths of a degree).
def _encode_temperature(temp_deg_c):
return struct.pack("<h", int(temp_deg_c * 100))
# Get temperature and update characteristic
async def sensor_task():
while True:
temperature = pico_temp_sensor.temp
temp_characteristic.write(_encode_temperature(temperature), send_update=True)
print(temperature)
await asyncio.sleep_ms(1000)
# Serially wait for connections. Don't advertise while a central is connected.
async def peripheral_task():
while True:
try:
async with await aioble.advertise(
_ADV_INTERVAL_MS,
name="RPi-Pico",
services=[_ENV_SENSE_UUID],
appearance=_ADV_APPEARANCE_GENERIC_THERMOMETER,
) as connection:
print("Connection from", connection.device)
await connection.disconnected()
except asyncio.CancelledError:
# Catch the CancelledError
print("Peripheral task cancelled")
except Exception as e:
print("Error in peripheral_task:", e)
finally:
# Ensure the loop continues to the next iteration
await asyncio.sleep_ms(100)
# Run both tasks
async def main():
t1 = asyncio.create_task(sensor_task())
t2 = asyncio.create_task(peripheral_task())
await asyncio.gather(t1, t2)
asyncio.run(main())
Cara Kerja Kode
Bagian berikut memberikan penjelasan ringkas mengenai komponen utama dari contoh program.
Import Pustaka
Untuk memungkinkan pemrosesan Bluetooth pada Raspberry Pi Pico, diperlukan impor pustaka `aioble` dan modul `bluetooth`, yang menyediakan antarmuka dan fungsi inti untuk komunikasi BLE.
import aioble
import bluetooth
Program akan dijalankan menggunakan paradigma pemrograman asinkron. Untuk mendukung mekanisme tersebut, modul `asyncio` digunakan sebagai kerangka pengelolaan coroutines dan tugas-tugas non-blocking. Disarankan untuk mempelajari dasar-dasar pemrograman asinkron melalui panduan berikut: Pemrograman Asinkron Raspberry Pi Pico – Menjalankan Beberapa Tugas (MicroPython).
import asyncio
Penentuan UUID serta Registrasi Layanan dan Karakteristik GATT
Pada tahap ini, UUID untuk Environmental Sensing Service dan Temperature Characteristic didefinisikan, kemudian diregistrasikan dalam struktur GATT sebagai elemen layanan dan karakteristik yang akan diekspos oleh perangkat BLE Peripheral.
# org.bluetooth.service.environmental_sensing
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
# org.bluetooth.characteristic.temperature
_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)
Kemudian, daftarkan layanan dan karakteristik GATT.
# Register GATT server.
temp_service = aioble.Service(_ENV_SENSE_UUID)
temp_characteristic = aioble.Characteristic(
temp_service, _ENV_SENSE_TEMP_UUID, read=True, notify=True
)
aioble.register_services(temp_service)
Pada saat konfigurasi karakteristik, parameter `read` dan `notify` diaktifkan. Pengaturan ini mendefinisikan metode interaksi yang diizinkan bagi perangkat BLE Central, yaitu melakukan operasi pembacaan terhadap karakteristik serta menerima notifikasi ketika nilai karakteristik mengalami perubahan.
Untuk memperbarui nilai suhu pada Temperature Characteristic, data harus dikonversi ke format yang sesuai dengan spesifikasi GATT. Proses encoding tersebut ditangani oleh fungsi `_encode_temperature()`.
def _encode_temperature(suhu_derajat_c):
return struct.pack("<h", int(suhu_derajat_c * 100))
Pengambilan Suhu dan Pembaruan Nilai Karakteristik
Sebuah fungsi asinkron digunakan untuk membaca nilai suhu dari sensor internal Raspberry Pi Pico dan memperbarui Temperature Characteristic melalui metode `write()` pada objek `temp_characteristic`. Proses ini dieksekusi secara periodik dengan interval satu detik, yang dapat disesuaikan sesuai kebutuhan aplikasi.
# Get temperature and update characteristic
async def sensor_task():
while True:
temperature = pico_temp_sensor.temp
temp_characteristic.write(_encode_temperature(temperature), send_update=True)
print(temperature)
await asyncio.sleep_ms(1000)
Proses Advertising
Selain melakukan pembaruan nilai pada Temperature Characteristic, perangkat juga harus melakukan advertising agar Raspberry Pi Pico dapat terdeteksi sebagai penyedia layanan BLE. Untuk tujuan tersebut, fungsi `peripheral_task()` digunakan sebagai mekanisme yang mengelola proses advertising perangkat beserta layanan yang dieksposnya.
# Serially wait for connections. Don't advertise while a central is connected.
async def peripheral_task():
while True:
try:
async with await aioble.advertise(
_ADV_INTERVAL_MS,
name="RPi-Pico",
services=[_ENV_SENSE_UUID],
appearance=_ADV_APPEARANCE_GENERIC_THERMOMETER,
) as connection:
print("Connection from", connection.device)
await connection.disconnected()
except asyncio.CancelledError:
# Catch the CancelledError
print("Peripheral task cancelled")
except Exception as e:
print("Error in peripheral_task:", e)
finally:
# Ensure the loop continues to the next iteration
await asyncio.sleep_ms(100);
Di dalam fungsi tersebut, parameter identitas perangkat ditetapkan dengan mendefinisikan BLE device name, yang akan disertakan dalam paket advertising sehingga dapat dikenali oleh perangkat Central.
name="RPi-Pico",
Nama perangkat BLE dapat dimodifikasi sesuai kebutuhan. Pada contoh selanjutnya, perangkat Central akan melakukan koneksi berdasarkan device name, sehingga penamaan harus konsisten pada kedua sisi implementasi.
Fungsi Utama
Pada tahap akhir, didefinisikan fungsi asinkron `main()` sebagai titik eksekusi utama program. Di dalamnya dibuat dua asynchronous tasks: satu bertugas menangani proses advertising, dan satu lagi menjalankan pembaruan nilai pada Temperature Characteristic.
# Run both tasks. async def main(): t1 = asyncio.create_task(sensor_task()) t2 = asyncio.create_task(peripheral_task()) await asyncio.gather(t1, t2) asyncio.run(main())
Menguji Kode
Unggah dan jalankan kode sebelumnya pada Raspberry Pi Pico Anda. Setelah dieksekusi, perangkat akan mulai memperbarui nilai suhu pada Temperature Characteristic serta melakukan advertising terhadap layanan BLE yang disediakannya.
Gambar
Untuk melakukan koneksi ke Peripheral tersebut dan mengakses karakteristiknya, kita akan mengonfigurasi perangkat Raspberry Pi Pico lainnya sebagai BLE Central.
Aplikasi nRF Connect
Sebelum melanjutkan ke implementasi perangkat BLE Central, Anda dapat memverifikasi operasi Peripheral menggunakan aplikasi pemindaian BLE seperti nRF Connect. Aplikasi nRF Connect for Mobile dari Nordic Semiconductor tersedia untuk Android (Google Play Store) dan iOS (App Store). Unduh dan instal aplikasi tersebut pada ponsel cerdas Anda.
Gambar
Setelah aplikasi dijalankan, lakukan proses scanning. Perangkat BLE bernama RPi-Pico sesuai device name yang telah didefinisikan sebelumnya akan muncul dalam daftar hasil.
Gambar
Setelah melakukan koneksi, Anda akan melihat Environmental Sensing Service beserta Temperature Characteristic-nya. Anda dapat membuka karakteristik tersebut, melakukan pembacaan (read), serta mengaktifkan notifikasi.
Gambar
Pada beberapa perangkat (terutama iPhone), ikon pengaturan format data dapat digunakan untuk mengonversi nilai menjadi format yang sesuai, misalnya Unsigned Int. Aplikasi kemudian akan menampilkan pembaruan nilai suhu secara berkala. Nilai biasanya ditampilkan dalam satuan derajat Celsius dikalikan 100, sesuai spesifikasi karakteristik suhu BLE.
Gambar
Setelah memastikan bahwa BLE Peripheral berfungsi dengan benar, langkah berikutnya adalah memprogram Raspberry Pi Pico kedua sebagai BLE Central untuk membaca nilai suhu dari perangkat Peripheral tersebut.
Kode – Raspberry Pi Pico sebagai Perangkat BLE Central (Client BLE)
Potongan kode berikut dijalankan pada unit Raspberry Pi Pico kedua. Papan ini dikonfigurasikan untuk beroperasi sebagai BLE Central device yang bertugas melakukan proses scanning, mengidentifikasi perangkat dengan nama RPi-Pico, menemukan Environmental Sensing Service, serta melakukan pembacaan nilai suhu dari karakteristik yang terkait.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-w-bluetooth-low-energy-micropython/
from micropython import const
import uasyncio as asyncio
import aioble
import bluetooth
import struct
# org.bluetooth.service.environmental_sensing
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
# org.bluetooth.characteristic.temperature
_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)
# Name of the peripheral you want to connect
peripheral_name="RPi-Pico"
# Helper to decode the temperature characteristic encoding (sint16, hundredths of a degree).
def _decode_temperature(data):
try:
if data is not None:
return struct.unpack("<h", data)[0] / 100
except Exception as e:
print("Error decoding temperature:", e)
return None
async def find_temp_sensor():
# Scan for 5 seconds, in active mode, with a very low interval/window (to
# maximize detection rate).
async with aioble.scan(5000, interval_us=30000, window_us=30000, active=True) as scanner:
async for result in scanner:
print(result.name())
# See if it matches our name and the environmental sensing service.
if result.name() == peripheral_name and _ENV_SENSE_UUID in result.services():
return result.device
return None
async def main():
while True:
device = await find_temp_sensor()
if not device:
print("Temperature sensor not found. Retrying...")
await asyncio.sleep_ms(5000) # Wait for 5 seconds before retrying
continue
try:
print("Connecting to", device)
connection = await device.connect()
except asyncio.TimeoutError:
print("Timeout during connection. Retrying...")
await asyncio.sleep_ms(5000) # Wait for 5 seconds before retrying
continue
async with connection:
try:
temp_service = await connection.service(_ENV_SENSE_UUID)
temp_characteristic = await temp_service.characteristic(_ENV_SENSE_TEMP_UUID)
except asyncio.TimeoutError:
print("Timeout discovering services/characteristics. Retrying...")
await asyncio.sleep_ms(5000) # Wait for 5 seconds before retrying
continue
while True:
try:
temp_data = await temp_characteristic.read()
if temp_data is not None:
temp_deg_c = _decode_temperature(temp_data)
if temp_deg_c is not None:
print("Temperature: {:.2f}".format(temp_deg_c))
else:
print("Invalid temperature data")
else:
print("Error reading temperature: None")
except Exception as e:
print("Error in main loop:", e)
break # Break out of the inner loop and attempt to reconnect
await asyncio.sleep_ms(1000)
# Create an Event Loop
loop = asyncio.get_event_loop()
# Create a task to run the main function
loop.create_task(main())
try:
# Run the event loop indefinitely
loop.run_forever()
except Exception as e:
print('Error occurred: ', e)
except KeyboardInterrupt:
print('Program Interrupted by the user')
Cara Kerja Kode
Import Pustaka
Pustaka `aioble` dan `bluetooth` harus di-import sebagai dependensi utama untuk mengaktifkan fungsionalitas Bluetooth Low Energy (BLE) pada platform Raspberry Pi Pico.
import aioble
import bluetooth
Kode yang akan diimplementasikan menggunakan paradigma asynchronous programming. Oleh karena itu, pustaka `asyncio` diperlukan sebagai event loop utama untuk mengelola tugas-tugas non-blocking. Untuk pemahaman yang lebih komprehensif mengenai arsitektur eksekusi asinkron pada Raspberry Pi Pico, disarankan merujuk pada panduan Asynchronous Programming Raspberry Pi Pico – Running Multiple Tasks (MicroPython).
import asyncio
Deklarasikan UUID
Pada tahap ini, kita mendefinisikan UUID khusus yang merepresentasikan Environmental Sensing Service serta UUID terpisah untuk temperature characteristic yang akan diakses oleh perangkat BLE Central.
# org.bluetooth.service.environmental_sensing
_ENV_SENSE_UUID = bluetooth.UUID(0x181A)
# org.bluetooth.characteristic.temperature
_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)
Identifikasi Target Perangkat BLE
Selanjutnya, tentukan device name dari periferal BLE yang akan menjadi target koneksi. Parameter ini harus konsisten dengan nama perangkat yang telah dikonfigurasikan pada sisi server BLE—dalam contoh ini, RPi-Pico.
# Name of the peripheral you want to connect
peripheral_name="RPi-Pico"
Nilai suhu dikodekan sesuai format data yang ditentukan oleh karakteristik BLE. Untuk melakukan parsing dan konversi ke nilai temperatur yang dapat diinterpretasikan secara langsung, digunakan fungsi utilitas `_decode_temperature()`.
# Helper to decode the temperature characteristic encoding
# (sint16, hundredths of a degree).
def _decode_temperature(data):
try:
if data is not None:
return struct.unpack("<h", data)[0] / 100
except Exception as e:
print("Error decoding temperature:", e)
return None
Memindai dan Mengidentifikasi Perangkat BLE
Fungsi `find_temp_sensor()` melakukan proses BLE scanning untuk mendeteksi perangkat di sekitar. Ketika ditemukan perangkat dengan advertised name yang sesuai dengan konfigurasi sebelumnya, fungsi tersebut mengembalikan objek perangkat yang terdeteksi melalui `result.device`
async def find_temp_sensor():
# Scan for 5 seconds, in active mode, with a very low interval/window
# (to maximize detection rate)
async with aioble.scan(5000, interval_us=30000, window_us=30000, active=True) as scanner:
async for result in scanner:
print(result.name())
# See if it matches our name and the environmental sensing service.
if result.name() == peripheral_name and _ENV_SENSE_UUID in result.services():
return result.device
return None
Fungsi Utama
Di dalam fungsi `async main()`, langkah awal adalah melakukan proses akuisisi perangkat BLE target dengan memanggil fungsi `find_temp_sensor()`. Objek perangkat BLE yang berhasil diidentifikasi kemudian disimpan dalam variabel `device` untuk digunakan pada tahap koneksi dan operasi GATT selanjutnya.
device = await find_temp_sensor()
Selanjutnya, sistem melakukan inisiasi prosedur koneksi (connection establishment) terhadap perangkat tersebut:
try:
print("Connecting to", device)
connection = await device.connect()
Setelah koneksi berhasil diinisialisasi, sistem melakukan resolusi dan akuisisi GATT service yang memuat karakteristik suhu, lalu mereferensikannya ke dalam variabel `temp_service`. Berdasarkan service tersebut, modul kemudian melakukan enumerasi GATT characteristic yang relevan dan memetakkannya ke variabel `temp_characteristic` untuk operasi pembacaan selanjutnya.
async with connection:
try:
temp_service = await connection.service(_ENV_SENSE_UUID)
temp_characteristic = await temp_service.characteristic(_ENV_SENSE_TEMP_UUID)
Pada tahap akhir, sistem mengeksekusi operasi GATT Characteristic Read terhadap objek `temp_characteristic` melalui pemanggilan metode `.read()`, sehingga nilai suhu terkini dapat diakuisisi dari periferal BLE.
while True:
try:
temp_data = await temp_characteristic.read()
if temp_data is not None:
temp_deg_c = _decode_temperature(temp_data)
if temp_deg_c is not None:
print("Temperature: {:.2f}".format(temp_deg_c))
else:
print("Invalid temperature data")
else:
print("Error reading temperature: None")
except Exception as e:
print("Error in main loop:", e)
break # Break out of the inner loop and attempt to reconnect
await asyncio.sleep_ms(1000)
Sistem menginisialisasi event loop dan meregistrasikan coroutine `main()` sebagai task yang dieksekusi dalam konteks loop tersebut.
# Create an Event Loop
loop = asyncio.get_event_loop()
# Create a task to run the main function
loop.create_task(main()
Sebagai langkah final, event loop dieksekusi secara kontinu guna mempertahankan lifecycle program dan memastikan seluruh task asinkron tetap aktif.
# Run the event loop indefinitely
loop.run_forever()
Menguji Kode
Untuk melakukan pengujian secara paralel, disarankan menjalankan dua instans Thonny IDE sehingga masing-masing perangkat dapat dieksekusi dan dimonitor melalui konsol independen.
Untuk mengaktifkan eksekusi multi-instans Thonny, buka menu Tools > Options, kemudian nonaktifkan parameter Allow only a single Thonny instance.
Gambar
- Tutup Thonny agar konfigurasi baru diterapkan. Setelah itu, jalankan Thonny IDE dua kali untuk membuka dua instans independen.
- Pastikan setiap instans terhubung ke papan target yang benar dengan memilih port COM yang sesuai pada bagian kanan bawah antarmuka.
- Setelah perangkat BLE periferal aktif dan mempublikasikan nilai suhu, salin kode pada bagian ini ke instans Thonny kedua (yang telah terhubung ke port COM papan BLE Central). Jalankan kode tersebut pada papan kedua.
- Proses pemindaian BLE akan dimulai. Setelah perangkat RPi-Pico terdeteksi, sistem akan melakukan proses koneksi otomatis dan menampilkan nilai suhu yang diterima dari papan BLE periferal pada jendela Shell.
Gambar
Pada tutorial ini, Anda telah mempelajari konsep fundamental Bluetooth Low Energy (BLE) pada Raspberry Pi Pico yang dikonfigurasi menggunakan MicroPython. Anda telah memahami prosedur konfigurasi Pico sebagai BLE Central Device maupun BLE Peripheral Device, serta mekanisme definisi, publikasi, dan pembacaan karakteristik GATT.
Untuk pengembangan lanjutan, Anda dapat mengintegrasikan sensor lingkungan seperti BME280 atau sensor lain yang relevan untuk mengekspose karakteristik suhu, kelembaban, dan tekanan melalui layanan BLE. Selain itu, modul tampilan seperti OLED atau LCD dapat ditambahkan pada perangkat BLE Central untuk menampilkan data karakteristik yang diterima dari perangkat periferal.
Siap Untuk Membuat Proyek Impianmu Menjadi Kenyataan?
Klik di sini untuk chat langsung via WhatsApp dan dapatkan dukungan langsung dari tim ahli kami!
