forked from kevinmcaleer/pico_ble_remote
/
robot.py
125 lines (109 loc) · 4.04 KB
/
robot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# June 2023
# Bluetooth cores specification versio 5.4 (0x0D)
# Bluetooth Remote Control
# Kevin McAleer
# KevsRobot.com
import aioble
import bluetooth
import machine
import uasyncio as asyncio
# Bluetooth UUIDS can be found online at https://www.bluetooth.com/specifications/gatt/services/
_REMOTE_UUID = bluetooth.UUID(0x1848)
_ENV_SENSE_UUID = bluetooth.UUID(0x1800)
_REMOTE_CHARACTERISTICS_UUID = bluetooth.UUID(0x2A6E)
led = machine.Pin("LED", machine.Pin.OUT)
connected = False
alive = False
async def find_remote():
# Scan for 5 seconds, in active mode, with very low interval/window (to
# maximise detection rate).
async with aioble.scan(5000, interval_us=30000, window_us=30000, active=True) as scanner:
async for result in scanner:
# See if it matches our name
if result.name() == "KevsRobots":
print("Found KevsRobots")
for item in result.services():
print (item)
if _ENV_SENSE_UUID in result.services():
print("Found Robot Remote Service")
return result.device
return None
async def blink_task():
""" Blink the LED on and off every second """
toggle = True
while True and alive:
led.value(toggle)
toggle = not toggle
# print(f'blink {toggle}, connected: {connected}')
if connected:
blink = 1000
else:
blink = 250
await asyncio.sleep_ms(blink)
async def peripheral_task():
print('starting peripheral task')
global connected
connected = False
device = await find_remote()
if not device:
print("Robot Remote not found")
return
try:
print("Connecting to", device)
connection = await device.connect()
except asyncio.TimeoutError:
print("Timeout during connection")
return
async with connection:
print("Connected")
connected = True
alive = True
while True and alive:
try:
robot_service = await connection.service(_REMOTE_UUID)
print(robot_service)
control_characteristic = await robot_service.characteristic(_REMOTE_CHARACTERISTICS_UUID)
print(control_characteristic)
except asyncio.TimeoutError:
print("Timeout discovering services/characteristics")
return
while True:
if control_characteristic != None:
try:
command = await control_characteristic.read()
# print(f"Command: {temp_deg_c}")
if command == b'a':
print("a button pressed")
if command == b'b':
print("b button pressed")
if command == b'x':
print("x button pressed")
if command == b'y':
print("y button pressed")
except TypeError:
print(f'something went wrong; remote disconnected?')
connected = False
alive = False
return
except asyncio.TimeoutError:
print(f'something went wrong; timeout error?')
connected = False
alive = False
return
except asyncio.GattError:
print(f'something went wrong; Gatt error - did the remote die?')
connected = False
alive = False
return
else:
print('no characteristic')
await asyncio.sleep_ms(10)
async def main():
tasks = []
tasks = [
asyncio.create_task(blink_task()),
asyncio.create_task(peripheral_task()),
]
await asyncio.gather(*tasks)
while True:
asyncio.run(main())