Running the Raspberry Pi as a Bluetooth Peripheral
In this activity, we will set up the Raspberry pi to run a Bluetooth service as a peripheral device.
Updating and installing the packages
Update your Raspberry Pi with:
sudo apt update
And then
sudo apt upgrade
We will now install the requirements for pybluez
sudo apt install python3-pip libbluetooth-dev git
We will then install the python packages:
sudo pip3 install pybluez gpiozero
We are now going to modify the Bluetooth Service in the Raspberry Pi to turn on the Bluetooth service.
sudo nano /lib/systemd/system/bluetooth.service
Thet change the following line:
ExecStart=/usr/lib/bluetooth/bluetoothd
To
ExecStart=/usr/lib/bluetooth/bluetoothd -E
The -E flag enables experimental features. After adding the experimental flag to the raspberry pi we need to reboot the pi to enable this feature.
sudo reboot
After you have rebooted, log back into your Pi and return to the terminal.
Now we will use Git to download a package that has been written and use a modified version of one of the files to enable and disable a LED over Bluetooth.
git clone https://github.com/douglas6/cputemp.git
cd into the folder we just downloaded on git
cd cputemp
Modifying the code
Create a python3 script:
nano LEDscript.py
Then paste in the code below. Ensure you change the text "IoT Murdoch" to a service name that is unique (otherwise you might connect to someone else’s pi by accident).
#!/usr/bin/env python3 import dbus from advertisement import Advertisement from service import Application, Service, Characteristic, Descriptor from gpiozero import CPUTemperature GATT_CHRC_IFACE = "org.bluez.GattCharacteristic1" NOTIFY_TIMEOUT = 5000 class LEDControlAdvertisement(Advertisement): def __init__(self, index): Advertisement.__init__(self, index, "peripheral") self.add_local_name("IoT Murdoch") self.include_tx_power = True class BLEService(Service): MAIN_SVC_UUID = "00000001-710e-4a5b-8d75-3e5b444bc3cf" def __init__(self, index): Service.__init__(self, index, self.MAIN_SVC_UUID, True) self.add_characteristic(LEDControl(self)) class LEDControl(Characteristic): UNIT_CHARACTERISTIC_UUID = "00000002-710e-4a5b-8d75-3e5b444bc3cf" def __init__(self, service): Characteristic.__init__( self, self.UNIT_CHARACTERISTIC_UUID, ["write"], service) #self.add_descriptor(UnitDescriptor(self)) def WriteValue(self, value, options): output = bytes(value).decode() if output == "0": print('turning LED off') elif output == "1": print('turning LED on') else: print('try again') print(output) app = Application() app.add_service(BLEService(0)) app.register() adv = LEDControlAdvertisement(0) adv.register() try: app.run() except KeyboardInterrupt: app.quit()
The UUID which reads "00000001-710e-4a5b-8d75-3e5b444bc3cf" is a random identifier that you can generate here https://www.uuidgenerator.net/ general practice is for each characteristic under it to change the service UUID up by one.
128 bit identifiers are able to be used by anyone, you may see shorter ones on other devices these are locked to a specific vendor or a specific service e.g battery levels are 0x180F
Read more here https://www.bluetooth.com/specifications/gatt/services/
Now run the script
sudo python3 LEDscript.py
To connect we will use our mobile phone, download the app nRF Connect
Images
Once open, search for the name you selected within the green text below its called IoT Murdoch it will ask you to pair, swipe across to services in the app, then click the up arrow under your service
Then write into the service ensuring you select UTF-8 at the top, 1 means LED on, 0 means led off
You should then see the command line tell you that the LED is enabled, and it switch on