-
-
Save ukBaz/07cb8e67c1888bdb97c3f22272b6a263 to your computer and use it in GitHub Desktop.
Simple example of micro:bit UART
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
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
@xiaolongchengithub: There is a more complete implementation over at:
https://github.com/ukBaz/python-bluezero/blob/master/examples/microbit_uart.py
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This example requires BlueZ 5.43 or later
The micro:bit code in PXT