Skip to content

Instantly share code, notes, and snippets.

@CubeLegend
Created June 2, 2022 13:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CubeLegend/f77c6f0d8b2aaee78a30d2c6508cdaf2 to your computer and use it in GitHub Desktop.
Save CubeLegend/f77c6f0d8b2aaee78a30d2c6508cdaf2 to your computer and use it in GitHub Desktop.
Connecting to an Xbox one controller
import binascii
import ubluetooth
from micropython import const
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_IRQ_GATTS_READ_REQUEST = const(4)
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_PERIPHERAL_CONNECT = const(7)
_IRQ_PERIPHERAL_DISCONNECT = const(8)
_IRQ_GATTC_SERVICE_RESULT = const(9)
_IRQ_GATTC_SERVICE_DONE = const(10)
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11)
_IRQ_GATTC_CHARACTERISTIC_DONE = const(12)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
_IRQ_GATTC_READ_RESULT = const(15)
_IRQ_GATTC_READ_DONE = const(16)
_IRQ_GATTC_WRITE_DONE = const(17)
_IRQ_GATTC_NOTIFY = const(18)
_IRQ_GATTC_INDICATE = const(19)
_IRQ_GATTS_INDICATE_DONE = const(20)
_IRQ_MTU_EXCHANGED = const(21)
_IRQ_L2CAP_ACCEPT = const(22)
_IRQ_L2CAP_CONNECT = const(23)
_IRQ_L2CAP_DISCONNECT = const(24)
_IRQ_L2CAP_RECV = const(25)
_IRQ_L2CAP_SEND_READY = const(26)
_IRQ_CONNECTION_UPDATE = const(27)
_IRQ_ENCRYPTION_UPDATE = const(28)
_IRQ_GET_SECRET = const(29)
_IRQ_SET_SECRET = const(30)
_ADV_IND = const(0x00)
_ADV_DIRECT_IND = const(0x01)
_ADV_SCAN_IND = const(0x02)
_ADV_NONCONN_IND = const(0x03)
_UART_SERVICE_UUID = ubluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
_UART_RX_CHAR_UUID = ubluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E")
_UART_TX_CHAR_UUID = ubluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")
class BLESimpleCentral:
def __init__(self, ble):
self.gamepad_name = None
self.gamepad_addr_type = None
self.gamepad_addr = None
self._ble = ble
self._ble.active(True)
self._ble.irq(self.bt_irq)
def bt_irq(self, event, data):
if event == _IRQ_SCAN_RESULT:
# A single scan result.
addr_type, addr, adv_type, rssi, adv_data = data
if find_adv_name(adv_data) is None:
return
print('Address-Type: ', addr_type)
print('Address: ', [hex(n) for n in addr])
print('ADV-Type: ', adv_type)
print('RSSI in dBm: ', rssi)
print('ADV-Data: ', [hex(n) for n in adv_data])
print('ADV-Data (Name): ', find_adv_name(adv_data)) # Xbox Wireless Controller
print()
if find_adv_name(adv_data) == "Xbox Wireless Controller":
self.gamepad_name = find_adv_name(adv_data)
self.gamepad_addr_type = addr_type
self.gamepad_addr = addr
self._ble.gap_scan(None)
self.connect()
elif event == _IRQ_SCAN_DONE:
# Scan duration finished or manually stopped.
pass
elif event == _IRQ_PERIPHERAL_CONNECT:
# A successful gap_connect().
conn_handle, addr_type, addr = data
print("connect")
print(data)
print('Address-Type: ', addr_type)
print('Address: ', [hex(n) for n in addr])
print()
elif event == _IRQ_PERIPHERAL_DISCONNECT:
# Connected peripheral has disconnected.
conn_handle, addr_type, addr = data
print("disconnect")
print(data)
print('Address-Type: ', addr_type)
print('Address: ', [hex(n) for n in addr])
print()
# Find a device advertising the environmental sensor service.
def scan(self):
self._ble.gap_scan(5000, 100000, 25000, True)
def connect(self):
print(self.gamepad_addr)
self._ble.gap_connect(self.gamepad_addr_type, self.gamepad_addr)
def find_adv(adv_type, data):
i = 0
while i + 1 < len(data):
ad_structure_len = data[i]
ad_structure_type = data[i + 1]
ad_structure_payload = data[i + 2: i + ad_structure_len + 1]
if ad_structure_type == adv_type:
return ad_structure_payload
i += ad_structure_len + 1
return None
def find_adv_name(data):
n = find_adv(9, data)
if n:
return str(n, 'UTF-8') # Text
return None
def demo():
ble = ubluetooth.BLE()
central = BLESimpleCentral(ble)
central.scan()
def demo_connect():
ble = ubluetooth.BLE()
central = BLESimpleCentral(ble)
central.connect()
if __name__ == "__main__":
demo()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment