Skip to content

Commit 32bfbd5

Browse files
committed
Added examples to use asyncio
Added TinyPICO specific examples Updated readme
1 parent 8c917da commit 32bfbd5

File tree

11 files changed

+1055
-20
lines changed

11 files changed

+1055
-20
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# MicroPython Human Interface Device library
2+
# Copyright (C) 2021 H. Groefsema
3+
#
4+
# This program is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
18+
# Implements a BLE HID joystick
19+
import time
20+
from machine import SoftSPI, Pin
21+
from hid_services import Joystick
22+
23+
class Device:
24+
def __init__(self):
25+
# Define state
26+
self.x = 0
27+
self.y = 0
28+
29+
self.prev_x = 0
30+
self.prev_y = 0
31+
32+
# Define buttons
33+
self.pin_forward = Pin(23, Pin.IN)
34+
self.pin_reverse = Pin(19, Pin.IN)
35+
self.pin_left = Pin(18, Pin.IN)
36+
self.pin_right = Pin(5, Pin.IN)
37+
38+
# Create our device
39+
self.joystick = Joystick("Joystick")
40+
# Set a callback function to catch changes of device state
41+
self.joystick.set_state_change_callback(self.joystick_state_callback)
42+
# Start our device
43+
self.joystick.start()
44+
45+
# Function that catches device status events
46+
def joystick_state_callback(self):
47+
if self.joystick.get_state() is Joystick.DEVICE_IDLE:
48+
return
49+
elif self.joystick.get_state() is Joystick.DEVICE_ADVERTISING:
50+
return
51+
elif self.joystick.get_state() is Joystick.DEVICE_CONNECTED:
52+
return
53+
else:
54+
return
55+
56+
def advertise(self):
57+
self.joystick.start_advertising()
58+
59+
def stop_advertise(self):
60+
self.joystick.stop_advertising()
61+
62+
# Main loop
63+
def start(self):
64+
while True:
65+
# Read pin values and update variables
66+
self.x = self.pin_right.value() * 127 - self.pin_left.value() * 127
67+
self.y = self.pin_reverse.value() * 127 - self.pin_forward.value() * 127
68+
69+
# If the variables changed do something depending on the device state
70+
if (self.x != self.prev_x) or (self.y != self.prev_y):
71+
# Update values
72+
self.prev_x = self.x
73+
self.prev_y = self.y
74+
75+
# If connected set axes and notify
76+
# If idle start advertising for 30s or until connected
77+
if self.joystick.get_state() is Joystick.DEVICE_CONNECTED:
78+
self.joystick.set_axes(self.x, self.y)
79+
self.joystick.notify_hid_report()
80+
elif self.joystick.get_state() is Joystick.DEVICE_IDLE:
81+
self.joystick.start_advertising()
82+
i = 10
83+
while i > 0 and self.joystick.get_state() is Joystick.DEVICE_ADVERTISING:
84+
time.sleep(3)
85+
i -= 1
86+
if self.joystick.get_state() is Joystick.DEVICE_ADVERTISING:
87+
self.joystick.stop_advertising()
88+
89+
if self.joystick.get_state() is Joystick.DEVICE_CONNECTED:
90+
time.sleep_ms(20)
91+
else:
92+
time.sleep(2)
93+
94+
# Only for test
95+
def stop(self):
96+
self.joystick.stop()
97+
98+
# Test routine
99+
def test(self):
100+
self.joystick.set_battery_level(50)
101+
self.joystick.notify_battery_level()
102+
103+
for i in range(30):
104+
self.joystick.set_axes(100,100)
105+
self.joystick.set_buttons(1)
106+
self.joystick.notify_hid_report()
107+
time.sleep_ms(500)
108+
109+
self.joystick.set_axes(100,-100)
110+
self.joystick.set_buttons(b3=1)
111+
self.joystick.notify_hid_report()
112+
time.sleep_ms(500)
113+
114+
self.joystick.set_axes(-100,-100)
115+
self.joystick.set_buttons()
116+
self.joystick.notify_hid_report()
117+
time.sleep_ms(500)
118+
119+
self.joystick.set_axes(-100,100)
120+
self.joystick.set_buttons(b2=1)
121+
self.joystick.notify_hid_report()
122+
time.sleep_ms(500)
123+
124+
self.joystick.set_axes(0,0)
125+
self.joystick.set_buttons()
126+
self.joystick.notify_hid_report()
127+
128+
self.joystick.set_battery_level(100)
129+
self.joystick.notify_battery_level()
130+
131+
if __name__ == "__main__":
132+
d = Device()
133+
d.start()
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# MicroPython Human Interface Device library
2+
# Copyright (C) 2021 H. Groefsema
3+
#
4+
# This program is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
18+
# Implements a BLE HID keyboard
19+
import time
20+
from machine import SoftSPI, Pin
21+
from hid_services import Keyboard
22+
23+
class Device:
24+
def __init__(self):
25+
# Define state
26+
self.key0 = 0x00
27+
self.key1 = 0x00
28+
self.key2 = 0x00
29+
self.key3 = 0x00
30+
31+
# Define buttons
32+
self.pin_forward = Pin(5, Pin.IN)
33+
self.pin_reverse = Pin(23, Pin.IN)
34+
self.pin_right = Pin(19, Pin.IN)
35+
self.pin_left = Pin(18, Pin.IN)
36+
37+
# Create our device
38+
self.keyboard = Keyboard("Keyboard")
39+
# Set a callback function to catch changes of device state
40+
self.keyboard.set_state_change_callback(self.keyboard_state_callback)
41+
# Start our device
42+
self.keyboard.start()
43+
44+
# Function that catches device status events
45+
def keyboard_state_callback(self):
46+
if self.keyboard.get_state() is Keyboard.DEVICE_IDLE:
47+
return
48+
elif self.keyboard.get_state() is Keyboard.DEVICE_ADVERTISING:
49+
return
50+
elif self.keyboard.get_state() is Keyboard.DEVICE_CONNECTED:
51+
return
52+
else:
53+
return
54+
55+
def keyboard_event_callback(self, bytes):
56+
print("Keyboard state callback with bytes: ", bytes)
57+
58+
def advertise(self):
59+
self.keyboard.start_advertising()
60+
61+
def stop_advertise(self):
62+
self.keyboard.stop_advertising()
63+
64+
# Main loop
65+
def start(self):
66+
while True:
67+
# Read pin values and update variables
68+
if self.pin_forward.value():
69+
self.key0 = 0x1A # W
70+
else:
71+
self.key0 = 0x00
72+
73+
if self.pin_left.value():
74+
self.key1 = 0x04 # A
75+
else:
76+
self.key1 = 0x00
77+
78+
if self.pin_reverse.value():
79+
self.key2 = 0x16 # S
80+
else:
81+
self.key2 = 0x00
82+
83+
if self.pin_right.value():
84+
self.key3 = 0x07 # D
85+
else:
86+
self.key3 = 0x00
87+
88+
# If the variables changed do something depending on the device state
89+
if (self.key0 != 0x00) or (self.key1 != 0x00) or (self.key2 != 0x00) or (self.key3 != 0x00):
90+
# If connected set keys and notify
91+
# If idle start advertising for 30s or until connected
92+
if self.keyboard.get_state() is Keyboard.DEVICE_CONNECTED:
93+
self.keyboard.set_keys(self.key0, self.key1, self.key2, self.key3)
94+
self.keyboard.notify_hid_report()
95+
elif self.keyboard.get_state() is Keyboard.DEVICE_IDLE:
96+
self.keyboard.start_advertising()
97+
i = 10
98+
while i > 0 and self.keyboard.get_state() is Keyboard.DEVICE_ADVERTISING:
99+
time.sleep(3)
100+
i -= 1
101+
if self.keyboard.get_state() is Keyboard.DEVICE_ADVERTISING:
102+
self.keyboard.stop_advertising()
103+
104+
if self.keyboard.get_state() is Keyboard.DEVICE_CONNECTED:
105+
time.sleep_ms(20)
106+
else:
107+
time.sleep(2)
108+
109+
def send_char(self, char):
110+
if char == " ":
111+
mod = 0
112+
code = 0x2C
113+
elif ord("a") <= ord(char) <= ord("z"):
114+
mod = 0
115+
code = 0x04 + ord(char) - ord("a")
116+
elif ord("A") <= ord(char) <= ord("Z"):
117+
mod = 1
118+
code = 0x04 + ord(char) - ord("A")
119+
else:
120+
assert 0
121+
122+
self.keyboard.set_keys(code)
123+
self.keyboard.set_modifiers(left_shift=mod)
124+
self.keyboard.notify_hid_report()
125+
time.sleep_ms(2)
126+
127+
self.keyboard.set_keys()
128+
self.keyboard.set_modifiers()
129+
self.keyboard.notify_hid_report()
130+
time.sleep_ms(2)
131+
132+
133+
def send_string(self, st):
134+
for c in st:
135+
self.send_char(c)
136+
137+
# Only for test
138+
def stop(self):
139+
self.keyboard.stop()
140+
141+
# Test routine
142+
def test(self):
143+
time.sleep(5)
144+
self.keyboard.set_battery_level(50)
145+
self.keyboard.notify_battery_level()
146+
time.sleep_ms(2)
147+
148+
# Press Shift+W
149+
self.keyboard.set_keys(0x1A)
150+
self.keyboard.set_modifiers(right_shift=1)
151+
self.keyboard.notify_hid_report()
152+
153+
# release
154+
self.keyboard.set_keys()
155+
self.keyboard.set_modifiers()
156+
self.keyboard.notify_hid_report()
157+
time.sleep_ms(500)
158+
159+
# Press a
160+
self.keyboard.set_keys(0x04)
161+
self.keyboard.notify_hid_report()
162+
163+
# release
164+
self.keyboard.set_keys()
165+
self.keyboard.notify_hid_report()
166+
time.sleep_ms(500)
167+
168+
# Press s
169+
self.keyboard.set_keys(0x16)
170+
self.keyboard.notify_hid_report()
171+
172+
# release
173+
self.keyboard.set_keys()
174+
self.keyboard.notify_hid_report()
175+
time.sleep_ms(500)
176+
177+
# Press d
178+
self.keyboard.set_keys(0x07)
179+
self.keyboard.notify_hid_report()
180+
181+
# release
182+
self.keyboard.set_keys()
183+
self.keyboard.notify_hid_report()
184+
time.sleep_ms(500)
185+
186+
self.send_string(" Hello World")
187+
188+
self.keyboard.set_battery_level(100)
189+
self.keyboard.notify_battery_level()
190+
191+
if __name__ == "__main__":
192+
d = Device()
193+
d.start()

0 commit comments

Comments
 (0)