Skip to content

Commit dd075a7

Browse files
committed
Works. Needs testing and docs.
1 parent 4d42ee5 commit dd075a7

File tree

5 files changed

+294
-15
lines changed

5 files changed

+294
-15
lines changed

README.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ This is easily achieved by downloading
3636
or individual libraries can be installed using
3737
`circup <https://github.com/adafruit/circup>`_.
3838

39-
.. todo:: Describe the Adafruit product this library works with. For PCBs, you can also add the
40-
image from the assets folder in the PCB's GitHub repo.
39+
This library is designed to work withe the Adafruit MacroPad RP2040.
4140

4241
`Purchase one from the Adafruit shop <http://www.adafruit.com/products/5100>`_
4342

@@ -69,7 +68,6 @@ Usage Example
6968
=============
7069

7170
.. todo:: Add a quick, simple example. It and other examples should live in the
72-
examples folder and be included in docs/examples.rst.
7371

7472
Contributing
7573
============

adafruit_macropad.py

Lines changed: 285 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
21
# SPDX-FileCopyrightText: Copyright (c) 2021 Kattni Rembor for Adafruit Industries
32
#
43
# SPDX-License-Identifier: MIT
@@ -16,22 +15,299 @@
1615
1716
**Hardware:**
1817
19-
.. todo:: Add links to any specific hardware product page(s), or category page(s).
20-
Use unordered list & hyperlink rST inline format: "* `Link Text <url>`_"
18+
* `Adafruit MacroPad RP2040 Bare Bones <https://www.adafruit.com/product/5100>`_
19+
* `Adafruit MacroPad RP2040 Starter Kit <https://www.adafruit.com/product/5128>`_
2120
2221
**Software and Dependencies:**
2322
2423
* Adafruit CircuitPython firmware for the supported boards:
25-
https://github.com/adafruit/circuitpython/releases
24+
https://circuitpython.org/downloads
2625
27-
.. todo:: Uncomment or remove the Bus Device and/or the Register library dependencies
28-
based on the library's use of either.
26+
* Adafruit's CircuitPython NeoPixel library:
27+
https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel
2928
30-
# * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
31-
# * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
3229
"""
3330

34-
# imports
31+
import board
32+
import digitalio
33+
import rotaryio
34+
import keypad
35+
import neopixel
36+
import usb_hid
37+
from adafruit_hid.keyboard import Keyboard
38+
from adafruit_hid.keycode import Keycode
39+
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
40+
from adafruit_hid.consumer_control import ConsumerControl
41+
from adafruit_hid.consumer_control_code import ConsumerControlCode
42+
from adafruit_hid.mouse import Mouse
43+
import usb_midi
44+
import adafruit_midi
45+
from adafruit_midi.note_on import NoteOn
46+
from adafruit_midi.note_off import NoteOff
47+
from adafruit_midi.pitch_bend import PitchBend
48+
from adafruit_midi.control_change import ControlChange
49+
from adafruit_simple_text_display import SimpleTextDisplay
50+
3551

3652
__version__ = "0.0.0-auto.0"
3753
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_MacroPad.git"
54+
55+
56+
class MacroPad:
57+
"""
58+
Class representing a single MacroPad.
59+
60+
:param int rotation: The rotational position of the MacroPad. Allows for rotating the MacroPad
61+
in 90 degree increments to four different positions and rotates the keypad
62+
layout and display orientation to match. Keypad layout is always left to
63+
right, top to bottom, beginning with key number 0 in the top left, and
64+
ending with key number 11 in the bottom right. Supports ``0``, ``90``,
65+
``180``, and ``270`` degree rotations. ``0`` is when the USB port is at
66+
the top, ``90`` is when the USB port is to the left, ``180`` is when the
67+
USB port is at the bottom, and ``270`` is when the USB port is to the
68+
right. Defaults to ``0``.
69+
:param int or tuple midi_in_channel: The MIDI input channel. This can either be an integer for
70+
one channel, or a tuple of integers to listen on multiple
71+
channels. Defaults to 0.
72+
:param int midi_out_channel: The MIDI output channel. Defaults to 0.
73+
74+
"""
75+
76+
# pylint: disable=invalid-name, too-many-instance-attributes
77+
def __init__(self, rotation=0, midi_in_channel=0, midi_out_channel=0):
78+
if rotation not in (0, 90, 180, 270):
79+
raise ValueError("Only 90 degree rotations are supported.")
80+
81+
# Define keys:
82+
if rotation == 0:
83+
self._key_pins = (
84+
board.KEY1,
85+
board.KEY2,
86+
board.KEY3,
87+
board.KEY4,
88+
board.KEY5,
89+
board.KEY6,
90+
board.KEY7,
91+
board.KEY8,
92+
board.KEY9,
93+
board.KEY10,
94+
board.KEY11,
95+
board.KEY12,
96+
)
97+
98+
if rotation == 90:
99+
self._key_pins = (
100+
board.KEY3,
101+
board.KEY6,
102+
board.KEY9,
103+
board.KEY12,
104+
board.KEY2,
105+
board.KEY5,
106+
board.KEY8,
107+
board.KEY11,
108+
board.KEY1,
109+
board.KEY4,
110+
board.KEY7,
111+
board.KEY10,
112+
)
113+
114+
if rotation == 180:
115+
self._key_pins = (
116+
board.KEY12,
117+
board.KEY11,
118+
board.KEY10,
119+
board.KEY9,
120+
board.KEY8,
121+
board.KEY7,
122+
board.KEY6,
123+
board.KEY5,
124+
board.KEY4,
125+
board.KEY3,
126+
board.KEY2,
127+
board.KEY1,
128+
)
129+
130+
if rotation == 270:
131+
self._key_pins = (
132+
board.KEY10,
133+
board.KEY7,
134+
board.KEY4,
135+
board.KEY1,
136+
board.KEY11,
137+
board.KEY8,
138+
board.KEY5,
139+
board.KEY2,
140+
board.KEY12,
141+
board.KEY9,
142+
board.KEY6,
143+
board.KEY3,
144+
)
145+
146+
self._keys = keypad.Keys(self._key_pins, value_when_pressed=False, pull=True)
147+
148+
# Define rotary encoder:
149+
self._encoder = rotaryio.IncrementalEncoder(board.ROTA, board.ROTB)
150+
self._encoder_switch = digitalio.DigitalInOut(board.BUTTON)
151+
self._encoder_switch.switch_to_input(pull=digitalio.Pull.UP)
152+
153+
# Define display:
154+
self._display = board.DISPLAY
155+
self._display.rotation = rotation
156+
157+
# Define audio:
158+
# Audio functionality will be added soon.
159+
160+
# Define LEDs:
161+
self._pixels = neopixel.NeoPixel(board.NEOPIXEL, 12, brightness=0.5)
162+
self._led = digitalio.DigitalInOut(board.LED)
163+
self._led.switch_to_output()
164+
165+
# Define HID:
166+
self._keyboard = Keyboard(usb_hid.devices)
167+
# This will need to be updated if we add more keyboard layouts. Currently there is only US.
168+
self._keyboard_layout = KeyboardLayoutUS(self._keyboard)
169+
self._consumer_control = ConsumerControl(usb_hid.devices)
170+
self._mouse = Mouse(usb_hid.devices)
171+
172+
# Define MIDI:
173+
self._midi = adafruit_midi.MIDI(
174+
midi_in=usb_midi.ports[0],
175+
# MIDI uses channels 1-16. CircuitPython uses 0-15. Ergo +1.
176+
in_channel=midi_in_channel + 1,
177+
midi_out=usb_midi.ports[1],
178+
out_channel=midi_out_channel + 1,
179+
)
180+
181+
@property
182+
def pixels(self):
183+
"""Sequence-like object representing the twelve NeoPixel LEDs in a 3 x 4 grid on the
184+
MacroPad. Each pixel is at a certain index in the sequence, numbered 0-11. Colors can be an
185+
RGB tuple like (255, 0, 0) where (R, G, B), or an RGB hex value like 0xFF0000 for red where
186+
each two digits are a color (0xRRGGBB). Set the global brightness using any number from 0
187+
to 1 to represent a percentage, i.e. 0.3 sets global brightness to 30%. Brightness defaults
188+
to 1.
189+
190+
See `neopixel.NeoPixel` for more info.
191+
192+
The following example turns all the pixels green at 50% brightness.
193+
194+
.. code-block:: python
195+
196+
from adafruit_macropad import MacroPad
197+
198+
macropad = MacroPad()
199+
200+
macropad.pixels.brightness = 0.5
201+
202+
while True:
203+
macropad.pixels.fill((0, 255, 0))
204+
205+
The following example sets the first pixel red and the twelfth pixel blue.
206+
207+
.. code-block:: python
208+
209+
from adafruit_macropad import MacroPad
210+
211+
macropad = MacroPad()
212+
213+
while True:
214+
macropad.pixels[0] = (255, 0, 0)
215+
macropad.pixels[11] = (0, 0, 255)
216+
"""
217+
return self._pixels
218+
219+
@property
220+
def red_led(self):
221+
"""The red led next to the USB port.
222+
223+
The following example blinks the red LED every 0.5 seconds.
224+
225+
.. code-block:: python
226+
227+
import time
228+
from adafruit_macropad import MacroPad
229+
230+
macropad = MacroPad()
231+
232+
while True:
233+
macropad.red_led = True
234+
time.sleep(0.5)
235+
macropad.red_led = False
236+
time.sleep(0.5)
237+
"""
238+
return self._led.value
239+
240+
@red_led.setter
241+
def red_led(self, value):
242+
self._led.value = value
243+
244+
@property
245+
def keys(self):
246+
return self._keys
247+
248+
@property
249+
def encoder(self):
250+
return self._encoder.position * -1
251+
252+
@property
253+
def encoder_switch(self):
254+
return not self._encoder_switch.value
255+
256+
@property
257+
def keyboard(self):
258+
return self._keyboard
259+
260+
@staticmethod
261+
def Keycode():
262+
return Keycode
263+
264+
@property
265+
def keyboard_layout(self):
266+
return self._keyboard_layout
267+
268+
@property
269+
def consumer_control(self):
270+
return self._consumer_control
271+
272+
@staticmethod
273+
def ConsumerControlCode():
274+
return ConsumerControlCode
275+
276+
@property
277+
def mouse(self):
278+
return self._mouse
279+
280+
@property
281+
def midi(self):
282+
return self._midi
283+
284+
@staticmethod
285+
def NoteOn():
286+
return NoteOn
287+
288+
@staticmethod
289+
def NoteOff():
290+
return NoteOff
291+
292+
@staticmethod
293+
def PitchBend():
294+
return PitchBend
295+
296+
@staticmethod
297+
def ControlChange():
298+
return ControlChange
299+
300+
@staticmethod
301+
def text_display(
302+
title=None, title_scale=1, title_length=80, text_scale=1, font=None
303+
):
304+
return SimpleTextDisplay(
305+
title=title,
306+
title_color=SimpleTextDisplay.WHITE,
307+
title_scale=title_scale,
308+
title_length=title_length,
309+
text_scale=text_scale,
310+
font=font,
311+
colors=(SimpleTextDisplay.WHITE,),
312+
display=board.DISPLAY,
313+
)

docs/conf.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
# Uncomment the below if you use native CircuitPython modules such as
2626
# digitalio, micropython and busio. List the modules you use. Without it, the
2727
# autodoc module docs will fail to generate with a warning.
28-
# autodoc_mock_imports = ["digitalio", "busio"]
28+
autodoc_mock_imports = ["board", "digitalio", "rotaryio", "keypad", "neopixel", "usb_hid",
29+
"usb_midi", "adafruit_hid", "adafruit_midi", "adafruit_simple_text_display"
30+
]
2931

3032

3133
intersphinx_mapping = {

examples/macropad_simpletest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
21
# SPDX-FileCopyrightText: Copyright (c) 2021 Kattni Rembor for Adafruit Industries
32
#
43
# SPDX-License-Identifier: Unlicense
4+
from adafruit_macropad import MacroPad
5+
6+
macropad = MacroPad()

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
# SPDX-License-Identifier: MIT
55

66
Adafruit-Blinka
7-
adafruit-circuitpython-displayio-sh1106
87
adafruit-circuitpython-hid
98
adafruit-circuitpython-midi
109
adafruit-circuitpython-neopixel
10+
adafruit-circuitpython-display-text
11+
adafruit-circuitpython-simple-display-text

0 commit comments

Comments
 (0)