-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
59e7080
commit ab1446a
Showing
31 changed files
with
357 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import time | ||
import terminalio | ||
from State import State | ||
from adafruit_display_text import label | ||
from setup import ( | ||
display, | ||
keys, | ||
neopixels, | ||
) | ||
|
||
|
||
class StartupState(State): | ||
color = (0, 0, 0) | ||
timer = 0 | ||
stage = 0 | ||
|
||
@property | ||
def name(self): | ||
return "startup" | ||
|
||
def enter(self, machine): | ||
neopixels.fill((0, 0, 0)) | ||
State.enter(self, machine) | ||
|
||
def exit(self, machine): | ||
neopixels.fill((255, 0, 0)) | ||
self.color = (0, 0, 0) | ||
self.timer = 0 | ||
self.stage = 0 | ||
State.exit(self, machine) | ||
|
||
def update(self, machine): | ||
self.timer = self.timer + 1 | ||
if self.stage == 0: | ||
text = " DCZia\n Electric Sampler" | ||
if len(text) > self.timer: | ||
text = text[0 : self.timer] | ||
text_area = label.Label(terminalio.FONT, text=text, x=2, y=5) | ||
display.show(text_area) | ||
self.color = (self.timer, self.timer, 0) | ||
if self.timer > (len(text) * 1.5): | ||
self.timer = 0 | ||
self.stage = 1 | ||
elif self.stage == 1: | ||
text = "Fueled by Green Chile\n and Solder" | ||
if len(text) > self.timer: | ||
text = text[0 : self.timer] | ||
text_area = label.Label(terminalio.FONT, text=text, x=2, y=10) | ||
display.show(text_area) | ||
if self.timer > (len(text) * 1.5): | ||
self.timer = 0 | ||
self.stage = 2 | ||
else: | ||
if self.timer < (255 * 8): | ||
color = (0, self.timer % 255, 0) | ||
neopixels[self.timer // 255] = color | ||
neopixels.show() | ||
self.timer = self.timer + 1 # make it faster | ||
else: | ||
time.sleep(0.1) | ||
machine.go_to_state("startup") # TODO: Should go to menu when that is in | ||
# Skip to menu if encoder is pressed | ||
key_event = keys.events.get() | ||
if key_event and key_event.pressed: | ||
machine.go_to_state("startup") # TODO: Should go to menu when that is in |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
class State(object): | ||
def __init__(self): | ||
pass | ||
|
||
@property | ||
def name(self): | ||
return "" | ||
|
||
def enter(self, machine): | ||
pass | ||
|
||
def exit(self, machine): | ||
pass | ||
|
||
def update(self, machine): | ||
return True |
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries | ||
# | ||
# SPDX-License-Identifier: MIT | ||
|
||
""" | ||
`adafruit_displayio_ssd1306` | ||
================================================================================ | ||
DisplayIO driver for SSD1306 monochrome displays | ||
* Author(s): Scott Shawcroft | ||
Implementation Notes | ||
-------------------- | ||
**Hardware:** | ||
* `Monochrome 1.3" 128x64 OLED graphic display <https://www.adafruit.com/product/938>`_ | ||
* `Monochrome 128x32 I2C OLED graphic display <https://www.adafruit.com/product/931>`_ | ||
* `Monochrome 0.96" 128x64 OLED graphic display <https://www.adafruit.com/product/326>`_ | ||
* `Monochrome 128x32 SPI OLED graphic display <https://www.adafruit.com/product/661>`_ | ||
* `Adafruit FeatherWing OLED - 128x32 OLED <https://www.adafruit.com/product/2900>`_ | ||
* Monochrome 0.49" 64x32 I2C OLED graphic display | ||
* Might work on other sub-128 width display: Dots 72x40, 64x48, 96x16 | ||
**Software and Dependencies:** | ||
* Adafruit CircuitPython (version 5+) firmware for the supported boards: | ||
https://github.com/adafruit/circuitpython/releases | ||
""" | ||
|
||
import displayio | ||
|
||
try: | ||
from typing import Union | ||
except ImportError: | ||
pass | ||
|
||
__version__ = "0.0.0+auto.0" | ||
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_SSD1306.git" | ||
|
||
# Sequence from page 19 here: https://cdn-shop.adafruit.com/datasheets/UG-2864HSWEG01+user+guide.pdf | ||
_INIT_SEQUENCE = ( | ||
b"\xAE\x00" # DISPLAY_OFF | ||
b"\x20\x01\x00" # Set memory addressing to horizontal mode. | ||
b"\x81\x01\xcf" # set contrast control | ||
b"\xA1\x00" # Column 127 is segment 0 | ||
b"\xA6\x00" # Normal display | ||
b"\xc8\x00" # Normal display | ||
b"\xA8\x01\x3f" # Mux ratio is 1/64 | ||
b"\xd5\x01\x80" # Set divide ratio | ||
b"\xd9\x01\xf1" # Set pre-charge period | ||
b"\xda\x01\x12" # Set com configuration | ||
b"\xdb\x01\x40" # Set vcom configuration | ||
b"\x8d\x01\x14" # Enable charge pump | ||
b"\xAF\x00" # DISPLAY_ON | ||
) | ||
|
||
|
||
class SSD1306(displayio.Display): | ||
""" | ||
SSD1306 driver | ||
:param int width: The width of the display | ||
:param int height: The height of the display | ||
:param int rotation: The rotation of the display in degrees. Default is 0. Must be one of | ||
(0, 90, 180, 270) | ||
""" | ||
|
||
def __init__( | ||
self, bus: Union[displayio.FourWire, displayio.I2CDisplay], **kwargs | ||
) -> None: | ||
# Patch the init sequence for 32 pixel high displays. | ||
init_sequence = bytearray(_INIT_SEQUENCE) | ||
height = kwargs["height"] | ||
width = kwargs["width"] | ||
if "rotation" in kwargs and kwargs["rotation"] % 180 != 0: | ||
height = kwargs["width"] | ||
width = kwargs["height"] | ||
init_sequence[16] = height - 1 # patch mux ratio | ||
if height == 32 and width == 64: # Make sure this only apply to that resolution | ||
init_sequence[16] = 64 - 1 # FORCED for 64x32 because it fail with formula | ||
if height in (32, 16) and width != 64: | ||
init_sequence[25] = 0x02 # patch com configuration | ||
col_offset = ( | ||
0 if width == 128 else (128 - width) // 2 | ||
) # https://github.com/micropython/micropython/pull/7411 | ||
super().__init__( | ||
bus, | ||
init_sequence, | ||
**kwargs, | ||
colstart=col_offset, | ||
rowstart=col_offset, | ||
color_depth=1, | ||
grayscale=True, | ||
pixels_in_byte_share_row=False, | ||
set_column_command=0x21, | ||
set_row_command=0x22, | ||
data_as_commands=True, | ||
brightness_command=0x81, | ||
single_byte_bounds=True, | ||
) | ||
self._is_awake = True # Display starts in active state (_INIT_SEQUENCE) | ||
|
||
@property | ||
def is_awake(self) -> bool: | ||
""" | ||
The power state of the display. (read-only) | ||
`True` if the display is active, `False` if in sleep mode. | ||
:type: bool | ||
""" | ||
return self._is_awake | ||
|
||
def sleep(self) -> None: | ||
""" | ||
Put display into sleep mode. | ||
Display uses < 10uA in sleep mode. Display remembers display data and operation mode | ||
active prior to sleeping. MP can access (update) the built-in display RAM. | ||
""" | ||
if self._is_awake: | ||
self.bus.send(0xAE, b"") # 0xAE = display off, sleep mode | ||
self._is_awake = False | ||
|
||
def wake(self) -> None: | ||
""" | ||
Wake display from sleep mode | ||
""" | ||
if not self._is_awake: | ||
self.bus.send(0xAF, b"") # 0xAF = display on | ||
self._is_awake = True |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import time | ||
|
||
from setup import ( | ||
select_enc, | ||
volume_enc, | ||
) | ||
|
||
from StartupState import StartupState | ||
|
||
|
||
class StateMachine(object): | ||
def __init__(self): | ||
self.state = None | ||
self.states = {} | ||
self.last_select_pos = select_enc.position | ||
self.last_volume_pos = volume_enc.position | ||
self.paused_state = None | ||
self.ticks_ms = 0 | ||
self.animation = None | ||
|
||
def add_state(self, state): | ||
self.states[state.name] = state | ||
|
||
def go_to_state(self, state_name): | ||
if self.state: | ||
self.state.exit(self) | ||
self.state = self.states[state_name] | ||
self.state.enter(self) | ||
|
||
def update(self): | ||
if self.state: | ||
self.state.update(self) | ||
if self.ticks_ms > 0: | ||
time.sleep(self.ticks_ms / 1000) | ||
|
||
# When pausing, don't exit the state | ||
def pause(self): | ||
self.state = self.states["paused"] | ||
self.state.enter(self) | ||
|
||
# When resuming, don't re-enter the state | ||
def resume_state(self, state_name): | ||
if self.state: | ||
self.state.exit(self) | ||
self.state = self.states[state_name] | ||
|
||
|
||
machine = StateMachine() | ||
machine.add_state(StartupState()) | ||
machine.go_to_state("startup") | ||
|
||
while True: | ||
machine.update() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import adafruit_displayio_ssd1306 | ||
import adafruit_midi | ||
import adafruit_sdcard | ||
import board | ||
import busio | ||
import digitalio | ||
import displayio | ||
import keypad | ||
import neopixel | ||
import rotaryio | ||
import storage | ||
import terminalio | ||
import time | ||
import usb_midi | ||
|
||
from adafruit_display_text import label | ||
|
||
# OLED Screen ( display ) | ||
displayio.release_displays() | ||
i2c = busio.I2C(board.GP15, board.GP14) | ||
display_bus = displayio.I2CDisplay(i2c, device_address=0x3C) | ||
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=32) | ||
|
||
# Neopixels | ||
neopixels = neopixel.NeoPixel(board.GP3, 10, brightness=0.1, auto_write=True) | ||
|
||
# Board LED | ||
led = digitalio.DigitalInOut(board.LED) | ||
led.direction = digitalio.Direction.OUTPUT | ||
|
||
# Sync Out | ||
sync_out = digitalio.DigitalInOut(board.GP7) | ||
sync_out.direction = digitalio.Direction.OUTPUT | ||
|
||
# Sync In | ||
sync_in = digitalio.DigitalInOut(board.GP6) | ||
sync_in.direction = digitalio.Direction.INPUT | ||
|
||
# Buttons | ||
# 0-7 Buttons | ||
# 8 Play | ||
# 9 Function | ||
# 10 Select | ||
# 11 Volume | ||
keys = keypad.KeyMatrix( | ||
row_pins=(board.GP27, board.GP26, board.GP18), | ||
column_pins=(board.GP20, board.GP21, board.GP22, board.GP28), | ||
columns_to_anodes=False, | ||
) | ||
|
||
# Setup rotary encoders | ||
select_enc = rotaryio.IncrementalEncoder(board.GP16, board.GP17) | ||
volume_enc = rotaryio.IncrementalEncoder(board.GP4, board.GP5) | ||
|
||
# MIDI setup | ||
midi_uart = busio.UART(tx=board.GP8, baudrate=31250) | ||
midi_serial_channel = 2 | ||
midi_serial = adafruit_midi.MIDI( | ||
midi_out=midi_uart, out_channel=midi_serial_channel - 1 | ||
) | ||
|
||
midi_usb = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0) | ||
|
||
# Setup the SD card and mount it as /sd | ||
try: | ||
# busio.SPI(clock:, MOSI: , MISO:) | ||
spi = busio.SPI(board.GP10, board.GP11, board.GP12) | ||
cs = digitalio.DigitalInOut(board.GP13) | ||
sdcard = adafruit_sdcard.SDCard(spi, cs) | ||
vfs = storage.VfsFat(sdcard) | ||
storage.mount(vfs, "/sd") | ||
except: | ||
text = "No SD Card Found!" | ||
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFF00, x=2, y=15) | ||
display.show(text_area) | ||
time.sleep(5) |