Skip to content

Instantly share code, notes, and snippets.

@ukBaz
Last active November 14, 2019 10:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ukBaz/07cb8e67c1888bdb97c3f22272b6a263 to your computer and use it in GitHub Desktop.
Save ukBaz/07cb8e67c1888bdb97c3f22272b6a263 to your computer and use it in GitHub Desktop.
Simple example of micro:bit UART
from pydbus import SystemBus
from gi.repository import GLib
import logging
import os
import sys
import tools
logging.basicConfig(level=logging.DEBUG)
# General Bluez D-Bus Object Paths
#: BlueZ DBus Service Name
BLUEZ_SERVICE_NAME = 'org.bluez'
# UART SERVICE
UART_SERIVCE = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
TX_CHARACTERISTIC = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
RX_CHARACTERISTIC = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
bus = SystemBus()
loop = GLib.MainLoop()
class MicroBit:
def __init__(self, dev_address, tx_callback):
self.address = dev_address
self.tx_callback = tx_callback
tools.check_power()
self.device = bus.get(BLUEZ_SERVICE_NAME,
tools.get_dbus_path(self.address))
self.rx = None
self.tx = None
self.io_id = None
self.pty_id = sys.stdin.fileno()
logging.debug(os.ttyname(self.pty_id))
logging.debug(self.pty_id)
self.device.onPropertiesChanged = self.device_connected
self.device.Connect()
def device_connected(self, iface, props_changed, props_invalidated):
logging.debug(props_changed)
if 'ServicesResolved' in props_changed:
if props_changed['ServicesResolved']:
self.get_gatt_details()
def get_gatt_details(self):
self.get_rx_object()
self.get_tx_object()
def get_rx_object(self):
self.rx = bus.get(BLUEZ_SERVICE_NAME,
tools.get_dbus_path(self.address,
UART_SERIVCE,
RX_CHARACTERISTIC))
self.io_id = GLib.io_add_watch(self.pty_id,
GLib.PRIORITY_DEFAULT,
GLib.IO_IN | GLib.IO_PRI,
self.input_handler)
def input_handler(self, fd, condition):
data = os.read(fd, 1024).rstrip()
data_list = []
for x in data:
data_list.append(x)
logging.debug('{}'.format(data_list))
data_list.append(35)
self.rx.WriteValue(data_list, {})
self.io_id = GLib.io_add_watch(self.pty_id,
GLib.PRIORITY_DEFAULT,
GLib.IO_IN | GLib.IO_PRI,
self.input_handler)
def get_tx_object(self):
self.tx = bus.get(BLUEZ_SERVICE_NAME,
tools.get_dbus_path(self.address,
UART_SERIVCE,
TX_CHARACTERISTIC))
self.tx.StartNotify()
self.tx.onPropertiesChanged = self.tx_callback
def my_print(iface, props, invalidated):
if 'Value' in props:
print(tools.utf8_to_txt(props['Value']))
if __name__ == '__main__':
ubit = MicroBit('D4:AE:95:4C:3E:A4', my_print)
try:
loop.run()
except KeyboardInterrupt:
ubit.device.Disconnect()
loop.quit()
from pydbus import SystemBus
# General Bluez D-Bus Object Paths
#: BlueZ DBus Service Name
BLUEZ_SERVICE_NAME = 'org.bluez'
#: BlueZ DBus adapter interface
ADAPTER_INTERFACE = 'org.bluez.Adapter1'
#: BlueZ DBus device Interface
DEVICE_INTERFACE = 'org.bluez.Device1'
# Bluez GATT D-Bus Object Paths
#: BlueZ DBus GATT manager Interface
GATT_MANAGER_IFACE = 'org.bluez.GattManager1'
#: BlueZ DBus GATT Profile Interface
GATT_PROFILE_IFACE = 'org.bluez.GattProfile1'
#: BlueZ DBus GATT Service Interface
GATT_SERVICE_IFACE = 'org.bluez.GattService1'
#: BlueZ DBus GATT Characteristic Interface
GATT_CHRC_IFACE = 'org.bluez.GattCharacteristic1'
#: BlueZ DBus GATT Descriptor Interface
GATT_DESC_IFACE = 'org.bluez.GattDescriptor1'
bus = SystemBus()
mngr = bus.get('org.bluez', '/')
def check_power():
adapter = bus.get('org.bluez', '/org/bluez/hci0')
if not adapter.Powered:
adapter.Powered = True
def _add_uuid_dashes(uuid):
return '{0}-{1}-{2}-{3}-{4}'.format(uuid[0:8], uuid[8:12],
uuid[12:16], uuid[16:20], uuid[20:])
def txt_to_utf8(letters):
return [ord(letter) for letter in letters]
def utf8_to_txt(utf8_list):
return ''.join(chr(letter) for letter in utf8_list)
def print_facing(iface, props, invalidated):
if 'Value' in props:
val = int.from_bytes(props['Value'][4:], byteorder='little', signed=True)
if val > 0:
print('Face down!')
else:
print('Face up!')
def _valid_character(char):
pass
def _valid_uuid(uuid):
if len(uuid) == 32:
return _add_uuid_dashes(uuid)
elif len(uuid) == 4:
return '0000{0}-0000-1000-8000-00805F9B34FB'.format(uuid)
else:
return uuid
def _get_dbus_path(objects, parent_path, iface_in, prop, value):
for path, iface in objects.items():
props = iface.get(iface_in)
if props is None:
continue
if props[prop].lower() == value.lower() and path.startswith(parent_path):
return path
def get_dbus_path(device=None, service=None, characteristic=None,
descriptor=None, adapter=None):
mngd_objs = mngr.GetManagedObjects()
if adapter is None:
_adt_path = '/org/bluez/hci0'
else:
_adt_path = _get_dbus_path(mngd_objs, '/org/bluez',
ADAPTER_INTERFACE, 'Address', adapter)
if device is None:
return _adt_path
else:
_dev_path = _get_dbus_path(mngd_objs, _adt_path,
DEVICE_INTERFACE, 'Address', device)
if service is None:
return _dev_path
else:
_srv_path = _get_dbus_path(mngd_objs, _dev_path,
GATT_SERVICE_IFACE, 'UUID', _valid_uuid(service))
if characteristic is None:
return _srv_path
else:
_chr_path = _get_dbus_path(mngd_objs, _srv_path,
GATT_CHRC_IFACE, 'UUID', _valid_uuid(characteristic))
if descriptor is None:
return _chr_path
else:
_dsr_path = _get_dbus_path(mngd_objs, _chr_path,
GATT_DESC_IFACE, 'UUID', _valid_uuid(descriptor))
return _dsr_path
@ukBaz
Copy link
Author

ukBaz commented Apr 29, 2017

This example requires BlueZ 5.43 or later

The micro:bit code in PXT

image

@xiaolongchengithub
Copy link

hi , this demon only can get data from the micro:bit. but how can it send data from the raspberry to the micro:bit. can you help me. thanks

@ukBaz
Copy link
Author

ukBaz commented Nov 14, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment