Skip to content

Commit 94fd493

Browse files
UI and Button Handling (#18)
* basic window * run loop with asyncio & command queue * button handling and command queue * update test script, remove print statements * red, green, blue parameters * working textualize ui * readme
1 parent 8192b77 commit 94fd493

File tree

10 files changed

+526
-137
lines changed

10 files changed

+526
-137
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ robot.move(0, 0) # Stop the robot
3636

3737
robot.led(0, 0, 0) # Turn off the LED
3838

39-
robot.run() # Execute the commands
39+
a = robot.set_key_binding('a').led(0, 0, 255, 1) # set LED color one button A
40+
w = robot.set_key_binding('w').move(100, 100) # bind move forward to key W
4041
```
4142

4243
## API

demo/test.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
from weallcode_robot import Robot
22

33
# Create a robot
4-
name = "beep"
4+
name = "WAC-C9B9"
55
robot = Robot(name)
66

7+
# assign button A to set LED to blue for 1 second
8+
robot.button_a.led(0, 0, 255, 1)
9+
10+
# assign button B to set LED to red & buzz at 440Hz for 0.5 seconds
11+
robot.button_b.led(255, 0, 0)
12+
13+
a = robot.set_key_binding('a').led(0, 0, 255, 1)
14+
715
# Display the robot's name (uppercased) on the robot's display for 2.5 seconds
816
robot.displayText(name.upper(), 2.5)
917

@@ -49,13 +57,11 @@
4957
robot.led(0, 0, 255, 0.25)
5058

5159
# Play a tone (Hz) for .5 seconds
52-
robot.buzz(440, 0.25)
60+
# robot.buzz(440, 0.25)
5361

5462
# Move 30, 40, 60, 80, 100, -30, -40, -60, -80, -100 percentages for 0.5 seconds
5563
for x in [-100, -80, -60, 60, 80, 100]:
5664
# Move forward at x% speed for 0.5 seconds
5765
robot.move(x, -x, 0.25)
5866
robot.stop()
5967
robot.wait(0.25)
60-
61-
robot.run()

demo/test_keybindings.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from weallcode_robot import Robot
2+
3+
# Create a robot
4+
name = "WAC-2463"
5+
robot = Robot(name)
6+
7+
robot.led(0,0,255,1)
8+
9+
a = robot.set_key_binding('a').led(0, 0, 255, 1)
10+
b = robot.set_key_binding('b').led(255, 0, 0, 1)
11+
c = robot.set_key_binding('c').led(0, 255, 0, 1)
12+
13+
w = robot.set_key_binding('w').move(100, 100).displayDots(
14+
# fmt: off
15+
[
16+
0, 0, 1, 0, 0,
17+
0, 0, 1, 0, 0,
18+
0, 0, 1, 0, 0,
19+
0, 1, 1, 1, 0,
20+
0, 0, 1, 0, 0,
21+
]
22+
)
23+
a = robot.set_key_binding('a').move(100, 0).displayDots(
24+
# fmt: off
25+
[
26+
0, 0, 0, 0, 0,
27+
0, 0, 0, 1, 0,
28+
1, 1, 1, 1, 1,
29+
0, 0, 0, 1, 0,
30+
0, 0, 0, 0, 0,
31+
]
32+
)
33+
s = robot.set_key_binding('d').move(0, 100).displayDots(
34+
# fmt: off
35+
[
36+
0, 0, 0, 0, 0,
37+
0, 1, 0, 0, 0,
38+
1, 1, 1, 1, 1,
39+
0, 1, 0, 0, 0,
40+
0, 0, 0, 0, 0,
41+
]
42+
)
43+
d = robot.set_key_binding('s').move(-100, -100).displayDots(
44+
# fmt: off
45+
[
46+
0, 0, 1, 0, 0,
47+
0, 1, 1, 1, 0,
48+
0, 0, 1, 0, 0,
49+
0, 0, 1, 0, 0,
50+
0, 0, 1, 0, 0,
51+
]
52+
)

demo/tk_play.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import tkinter as tk
2+
3+
window = tk.Tk()
4+
window.title('')
5+
6+
7+
window.mainloop()

pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
66
name = "weallcode_robot"
7-
version = "3.0.2"
7+
version = "3.0.3"
88
description = "Micro:bit TinyBit BLE Python Library"
99
license = "MIT"
1010
authors = [
@@ -45,3 +45,4 @@ black = "^23.3.0"
4545
pre-commit = "^3.2.1"
4646
isort = "^5.12.0"
4747
ruff = "^0.0.260"
48+
textual = "^0.52.1"

weallcode_robot/commands.py

+85
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,93 @@
11
import asyncio
22
import logging
3+
from queue import Queue
34

45
from bleak import BleakClient
56

7+
from .utils import copy_asyncio_queue, empty_asyncio_queue
8+
9+
10+
class CommandQueue():
11+
def __init__(self, name: str):
12+
self.name = name
13+
14+
self.queue = asyncio.Queue(maxsize=100)
15+
self._queue = None
16+
17+
def put(self, command):
18+
if not self.queue.full():
19+
self.queue.put_nowait(command)
20+
21+
async def get(self):
22+
return await self.queue.get()
23+
24+
def empty(self):
25+
return self.queue.empty()
26+
27+
def led(self, red, green, blue, duration: float = 0):
28+
self.put(LEDCommand(red, green, blue))
29+
self.wait(duration)
30+
return self
31+
32+
def move(self, right, left, duration: float = 0):
33+
self.put(MoveCommand(left, right))
34+
self.wait(duration)
35+
return self
36+
37+
def stop(self, duration: float = 0):
38+
self.put(MoveCommand(0, 0))
39+
self.wait(duration)
40+
return self
41+
42+
def wait(self, duration: float):
43+
if duration > 0:
44+
self.put(WaitCommand(duration))
45+
return self
46+
47+
def displayText(self, text: str, duration: float = 0):
48+
self.put(DisplayTextCommand(text))
49+
self.wait(duration)
50+
return self
51+
52+
def displayDots(self, matrix: list[int], duration: float = 0):
53+
self.put(DisplayDotMatrixCommand(matrix))
54+
self.wait(duration)
55+
return self
56+
57+
def clearDisplay(self):
58+
self.put(DisplayDotMatrixCommand())
59+
return self
60+
61+
def buzz(self, frequency: int, duration: float = 0.25):
62+
self.put(BuzzerCommand(frequency))
63+
self.wait(duration)
64+
return self
65+
66+
async def clear_immediate(self):
67+
await empty_asyncio_queue(self.queue)
68+
self.clear()
69+
return self
70+
71+
def clear(self):
72+
self.put(DisplayDotMatrixCommand())
73+
self.put(MoveCommand(0, 0))
74+
self.put(LEDCommand(0, 0, 0))
75+
self.put(BuzzerCommand(0))
76+
return self
77+
78+
async def save(self):
79+
self._queue = await copy_asyncio_queue(self.queue)
80+
81+
def save_sync(self):
82+
self._queue = self.queue
83+
84+
async def restore(self):
85+
if self._queue:
86+
self.queue = await copy_asyncio_queue(self._queue)
87+
88+
def restore_sync(self):
89+
if self._queue:
90+
self.queue = self._queue
691

792
class RobotCommand:
893
def __init__(self):

0 commit comments

Comments
 (0)