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
|
import struct
import time
import board
import digitalio
import analogio
from adafruit_hid import find_device
class Gamepad:
def __init__(self, devices):
self._gamepad_device = find_device(devices, usage_page=0x1, usage=0x05)
self._buttons = {
1: digitalio.DigitalInOut(board.GP0),
2: digitalio.DigitalInOut(board.GP1),
3: digitalio.DigitalInOut(board.GP2),
4: digitalio.DigitalInOut(board.GP3),
5: digitalio.DigitalInOut(board.GP4),
6: digitalio.DigitalInOut(board.GP5),
7: digitalio.DigitalInOut(board.GP6),
}
for button in self._buttons.values():
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP
self._joy_x_axis = analogio.AnalogIn(board.GP26)
self._joy_y_axis = analogio.AnalogIn(board.GP27)
self._report = bytearray(6)
self._last_report = bytearray(6)
self._buttons_state = 0
self._joy_x = 0
self._joy_y = 0
self._joy_z = 0
self._joy_r_z = 0
try:
self.reset_all()
except OSError:
time.sleep(1)
self.reset_all()
def read_buttons(self):
self._buttons_state = 0
for button_num, button in self._buttons.items():
if not button.value:
self._buttons_state |= 1 << (button_num - 1)
def read_joysticks(self):
self._joy_x = self._scale_joystick_value(self._joy_x_axis.value)
self._joy_y = self._scale_joystick_value(self._joy_y_axis.value)
def _scale_joystick_value(self, value):
return (value - 32768) // 258
def update(self):
self.read_buttons()
self.read_joysticks()
self._send()
def _send(self, always=False):
struct.pack_into(
"<Hbbbb",
self._report,
0,
self._buttons_state,
self._joy_x,
self._joy_y,
self._joy_z,
self._joy_r_z,
)
if always or self._last_report != self._report:
self._gamepad_device.send_report(self._report)
self._last_report[:] = self._report
def reset_all(self):
self._buttons_state = 0
self._joy_x = 0
self._joy_y = 0
self._joy_z = 0
self._joy_r_z = 0
self._send(always=True)
@staticmethod
def _validate_button_number(button):
if not 1 <= button <= 16:
raise ValueError("Button number must in range 1 to 16")
return button
@staticmethod
def _validate_joystick_value(value):
if not -127 <= value <= 127:
raise ValueError("Joystick value must be in range -127 to 127")
return value
|