Note
Hello, welcome to the SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community on Facebook! Dive deeper into Raspberry Pi, Arduino, and ESP32 with fellow enthusiasts.
Why Join?
Expert Support: Solve post-sale issues and technical challenges with help from our community and team.
Learn & Share: Exchange tips and tutorials to enhance your skills.
Exclusive Previews: Get early access to new product announcements and sneak peeks.
Special Discounts: Enjoy exclusive discounts on our newest products.
Festive Promotions and Giveaways: Take part in giveaways and holiday promotions.
š Ready to explore and create with us? Click [here] and join today!
8.14 Bluetooth Pianoļ
The project uses a custom-built application to transform a Raspberry Pi Pico 2 W into a Bluetooth-enabled piano. The Pico 2 W runs a MicroPython script that sets up a BLE peripheral, enabling it to receive note data from a connected device. Upon receiving a note, the board processes the data and plays the corresponding frequency using a passive buzzer.
This project is a great way to explore the basics of Bluetooth Low Energy (BLE) communication, sound generation with PWM, and how to create interactive applications using Raspberry Pi Pico 2 W.
The app used in this project was developed with MIT App Inventor.
1. Build the Circuitļ
Required Components
In this project, we need the following components.
Itās definitely convenient to buy a whole kit, hereās the link:
Name |
ITEMS IN THIS KIT |
LINK |
|---|---|---|
Pico 2 W Starter Kit |
450+ |
You can also buy them separately from the links below.
SN |
COMPONENT |
QUANTITY |
LINK |
|---|---|---|---|
1 |
1 |
||
2 |
Micro USB Cable |
1 |
|
3 |
1 |
||
4 |
Several |
||
5 |
1(S8050) |
||
6 |
1(1KĪ©) |
||
7 |
Passive Buzzer |
1 |
2. Create the Android Appļ
You will develop the Android application using MIT App Inventor, a free web application ideal for beginners in Android development. It offers intuitive drag-and-drop features for creating functional applications.
Follow these steps to get started:
Go to Get Started with MIT App Inventor, and click āonline toolā to login. You will need a Google account to register with MIT App Inventor.
After logging in, navigate to Projects -> Import project (.aia) from my computer. Subsequently, upload the
ble_piano_picow.aiafile located in the following path:pico-2w-kit/micropython/iot/8.14-ble_piano.Alternatively, you can download the file directly:
ble_piano_picow.aia
Once uploaded, the app template will appear in the MIT App Inventor interface. This pre-configured template can be customized after you become familiar with the platform.
MIT App Inventor has two main sections: Designer and Blocks. You can switch between these two sections in the upper right corner of the page.
The Designer allows you to add buttons, text, screens, and modify the overall aesthetic of your app.
Next, thereās the Blocks section. This section lets you craft custom functionalities for your app, allowing you to program each component on the appās GUI to achieve desired features.
To install the app on a phone, navigate to the Build tab.
Generate a
.apkfile. After selecting this option, a page will appear allowing you to choose between downloading a.apkfile or scanning a QR code for installation. Follow the installation guide to complete the application installation.Alternatively, download our pre-compiled APK file here:
ble_piano_picow.apkIf you wish to publish this app to Google Play or another app marketplace, you can generate a
.aabfile.
3. Run the Codeļ
Open the 8.14-ble_piano.py file under the path of pico-2w-kit/micropython/iot/8.14-ble_piano, or copy this code into your IDE.
Note
This code depends on the ble_advertising.py file. Make sure to upload it to the Pico board before running the script.
import bluetooth
import random
import struct
import time
from ble_example.ble_advertising import advertising_payload
from machine import Pin, PWM
import time
from micropython import const
buzzer = PWM(Pin(15))
NOTES = {
'NOTE_C4': 262,
'NOTE_D4': 294,
'NOTE_E4': 330,
'NOTE_F4': 349,
'NOTE_G4': 392,
'NOTE_A4': 440,
'NOTE_B4': 494,
'NOTE_C5': 523
}
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_FLAG_READ = const(0x0002)
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
_FLAG_WRITE = const(0x0008)
_FLAG_NOTIFY = const(0x0010)
_PIANO_UUID = bluetooth.UUID("952cc3a7-1801-4c07-b141-e1e3964f54b5")
_NOTE_CHAR = (
bluetooth.UUID("ea30277b-d7a5-4eeb-af70-6179c45d7ee6"),
_FLAG_READ | _FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,
)
_PIANO_SERVICE = (
_PIANO_UUID,
(_NOTE_CHAR,),
)
class BLEPiano:
def __init__(self, ble, name="ble-piano"):
self._ble = ble
self._ble.active(True)
self._ble.irq(self._irq)
handles = self._ble.gatts_register_services((_PIANO_SERVICE,))
# print("Registered handles:", handles)
((self._handle_note,),) = handles
self._connections = set()
self._write_callback = None
self._payload = advertising_payload(name=name, services=[_PIANO_UUID])
self._advertise()
def _irq(self, event, data):
# Track connections so we can send notifications.
if event == _IRQ_CENTRAL_CONNECT:
conn_handle, _, _ = data
print("New connection", conn_handle)
self._connections.add(conn_handle)
elif event == _IRQ_CENTRAL_DISCONNECT:
conn_handle, _, _ = data
print("Disconnected", conn_handle)
self._connections.remove(conn_handle)
# Start advertising again to allow a new connection.
self._advertise()
elif event == _IRQ_GATTS_WRITE:
conn_handle, value_handle = data
value = self._ble.gatts_read(value_handle)
# print("Write event: conn_handle={}, value_handle={}, value={}".format(conn_handle, value_handle, value))
if value_handle == self._handle_note and self._write_callback:
self._write_callback(value)
def is_connected(self):
return len(self._connections) > 0
def _advertise(self, interval_us=500000):
print("Starting advertising")
self._ble.gap_advertise(interval_us, adv_data=self._payload)
def on_write(self, callback):
self._write_callback = callback
def note_update(data):
print("Receive:", data)
decoded_data = data.decode('utf-8').rstrip('*\x00')
buzzer.freq(NOTES[decoded_data])
buzzer.duty_u16(32768)
time.sleep(0.15)
buzzer.duty_u16(0)
def demo():
ble = bluetooth.BLE()
piano = BLEPiano(ble,"pico2w")
while True:
if piano.is_connected():
piano.on_write(note_update)
# time.sleep_ms(100)
if __name__ == "__main__":
demo()
4. App and Bluetooth Connectionļ
Ensure that the āBLE Pianoā app created earlier is installed on your phone.
Enable Bluetooth on your phone.
Open the BLE Piano app.
When you open the app for the first time, you will see two consecutive prompts requesting permissions. These permissions are required for Bluetooth functionality.
In the APP, click on Connect button to establish a connection between the APP and Pico 2 W via bluetooth.
This page displays a list of all Bluetooth devices. Choose the
xx.xx.xx.xx.xx.xx pico2woption from the list. Each device name is displayed alongside its MAC address.
If no devices appear in the list, try enabling the location feature on your phone. (On some Android versions, the location setting is linked to Bluetooth functionality.)
Once connected, the system will redirect you to the main screen. You can tap the music note button to play the corresponding note. The app sends the note data to the Pico board, which drives the buzzer to play the specified note based on the data.