Files

copied
Last update 2 years 2 months by DasK
Filespico_firmware
..
lib
README.md
code.py
code.py
from time import sleep import board import busio import neopixel from keypad import KeyMatrix from digitalio import DigitalInOut, Direction, Pull import rotaryio from analogio import AnalogIn import random # import storage import displayio import terminalio from adafruit_display_text import label import adafruit_displayio_ssd1306 class CustomDisplay: def __init__(self): displayio.release_displays() i2c = busio.I2C(board.GP5, board.GP4) display_bus = displayio.I2CDisplay(i2c, device_address=0x3c) self._display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=32) self._splash = displayio.Group() self._text = "" self._text_changed = True # Make the display context self._display.show(self._splash) color_bitmap = displayio.Bitmap(128, 32, 1) color_palette = displayio.Palette(1) color_palette[0] = 0xFFFFFF # White bg_sprite = displayio.TileGrid(color_bitmap, pixel_shader=color_palette, x=0, y=0) self._splash.append(bg_sprite) # Draw a smaller inner rectangle as text background inner_bitmap = displayio.Bitmap(118, 24, 1) inner_palette = displayio.Palette(1) inner_palette[0] = 0x000000 # Black inner_sprite = displayio.TileGrid(inner_bitmap, pixel_shader=inner_palette, x=5, y=4) self._splash.append(inner_sprite) # Draw a label self._text_area = label.Label(terminalio.FONT, text=self._text, color=0xFFFFFF, x=28, y=15) self._splash.append(self._text_area) def text(self, text): self._text = text self._text_changed = True def update(self): if not self._text_changed: return self._text_changed = False self._text_area.text = self._text self._display.show(self._splash) def close(self): displayio.release_displays() display = CustomDisplay() pixels = neopixel.NeoPixel(board.GP0, 13, brightness=0.3, auto_write=True) # does not need pixels.show() each time l2b = (0, 1, 2, 3, 4, 8, 7, 6, 5, 9, 10, 11, 12) # led index map with button index # CUSTOM FUNCTIONS FOR POTENTIOMETERS =============================== def change_brightness(val): # val 0.0 to 1.0 pixels.brightness = round(val, 3) print(f"brightness {pixels.brightness}") last_volume = 0 def change_volume(val): # val 0.0 to 1.0 global last_volume volume = round(val*10) if volume == last_volume: return last_volume = volume m = f"vol {volume}" print(m) display.text(m) last_example = 0 def change_example(val): # val 0.0 to 1.0 global last_example disc_value = round(val*50) if disc_value == last_example: return last_example = disc_value m = f"exam {disc_value}" print(m) display.text(m) pots = [] pots.append({ "id": 1, 'apin': AnalogIn(board.GP27_A1), 'min': 3872, # TODO get from configuration file 'max': 62272, 'threshold': 1200, 'divisions': 10, 'inverted': True, 'trigger_at_start': False, 'callback': change_volume, }) pots.append({ "id": 2, 'apin': AnalogIn(board.GP28_A2), 'min': 4256 + 450, # measured 4256 'max': 62704 - 600, # measured 62704 'threshold': 1200, 'divisions': 20, 'inverted': True, 'trigger_at_start': True, 'callback': change_brightness, }) pots.append({ "id": 3, 'apin': AnalogIn(board.GP26_A0), 'min': 144 + 450, # measured 144 'max': 65520 - 450, # measured 65520 'threshold': 900, 'divisions': 10, 'inverted': True, 'trigger_at_start': False, 'callback': change_example, }) # configure pots for pot in pots: sleep(0.01) if pot['trigger_at_start']: pot['last_value'] = 99999 else: pot['last_value'] = pot['apin'].value encoders = [] encoders.append({ "id": 1, 'obj': rotaryio.IncrementalEncoder(board.GP12, board.GP11), 'last_position': 0 }) # configure and fill last_position for encoder in encoders: encoder['obj'].divisor = 2 encoder['last_position'] = encoder['obj'].position km = KeyMatrix( row_pins=(board.GP20, board.GP19, board.GP18), column_pins=(board.GP16, board.GP17, board.GP21, board.GP22), # interval=0.050, # debounce ) def check_pots(): for pot in pots: value = pot['apin'].value if abs(value - pot['last_value']) > pot['threshold']: # v = value * 3.3 / 65536 pot['last_value'] = value d = (value - pot['min'])/(pot['max'] - pot['min']) if d<0: d=0.0 elif d>1: d=1.0 if pot['inverted']: d=1.0-d print(f"pot id {pot['id']}: raw {value} norm {d:.3f}") # display.text(f"p{pot['id']}: {d:.2f}") pot['callback'](d) def check_encoders(): for encoder in encoders: position = encoder['obj'].position if position != encoder['last_position']: encoder['last_position'] = position print(f"encoder id{encoder['id']}: {position}") display.text(f"e{encoder['id']}: {position}") def check_keyboard(): while 1: event = km.events.get() if not event: break # print(event) print(f"{event.key_number} {event.pressed} {event.released} {event.timestamp} ") display.text(f"key {event.key_number+1} {event.pressed}") if event.pressed: r = random.randrange(0,256) g = random.randrange(0,256) b = random.randrange(0,256) i = l2b[event.key_number+1] pixels[i] = (r,g,b) def calibrate_pots_limits(): for pot in pots: pot['min'] = 65536 pot['max'] = 0 print_resoult = True while True: for pot in pots: sleep(0.05) value = pot['apin'].value if value < pot['min']: pot['min'] = value print_resoult=True elif value > pot['max']: pot['max'] = value print_resoult=True if print_resoult: s = "" for pot in pots: s+=f"id{pot['id']} min {pot['min']} max {pot['max']}, " print(s) print_resoult=False def calibrate_pots_threshold(): for pot in pots: pot['m'] = 0 while True: s = "" for pot in pots: r = pot['apin'].value for i in range(50): sleep(0.005) v = pot['apin'].value if abs(v-r) > pot['m']: pot['m']=abs(v-r) s+=f"{pot['id']}: {pot['m']}, " print(s) sleep(5) pixels[0] = (0, 128, 0) # status LED # calibrate_pots_limits() # calibrate_pots_threshold() counter = 0 # try: while True: check_pots() check_encoders() check_keyboard() if counter%5 == 0: display.update() counter+=1 sleep(0.01) # except MemoryError: # because of the display # except: # pixels[0] = (128, 0, 0) # pixels.brightness = 0.25 # displayio.release_displays()
Report a bug