Add class for HUSB238 board control and LED matrix control
This commit is contained in:
@@ -1,5 +0,0 @@
|
|||||||
Adafruit CircuitPython 9.0.4 on 2024-04-16; Adafruit ItsyBitsy M4 Express with samd51g19
|
|
||||||
Board ID:itsybitsy_m4_express
|
|
||||||
UID:A9C26FCF53324853202020472A3908FF
|
|
||||||
[2K[0Gboot.py output:
|
|
||||||
Booting normal mode
|
|
||||||
BIN
ControlMixerPython/lib/neopixel.mpy
Normal file
BIN
ControlMixerPython/lib/neopixel.mpy
Normal file
Binary file not shown.
109
ControlMixerPython/mixer_leds.py
Normal file
109
ControlMixerPython/mixer_leds.py
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
from power import HUSB238
|
||||||
|
import board
|
||||||
|
import neopixel
|
||||||
|
|
||||||
|
VM_GREEN = (32,255,32)
|
||||||
|
VM_RED = (255,16,16)
|
||||||
|
|
||||||
|
LED1 = 1 << 0 # 1
|
||||||
|
LED2 = 1 << 1 # 2
|
||||||
|
LED3 = 1 << 2 # 4
|
||||||
|
LED4 = 1 << 3 # 8
|
||||||
|
LED5 = 1 << 4 # 16
|
||||||
|
LED6 = 1 << 5 # 32
|
||||||
|
LED7 = 1 << 6 # 64
|
||||||
|
LED8 = 1 << 7 # 128
|
||||||
|
LED9 = 1 << 8 # 256
|
||||||
|
LED10 = 1 << 9 # 512
|
||||||
|
LED11 = 1 << 10 # 1024
|
||||||
|
LED12 = 1 << 11 # 2048
|
||||||
|
LED13 = 1 << 12 # 4096
|
||||||
|
LED14 = 1 << 13 # 8192
|
||||||
|
LED15 = 1 << 14 # 16384
|
||||||
|
LED16 = 1 << 15 # 32768
|
||||||
|
LED17 = 1 << 16 # 65536
|
||||||
|
LED18 = 1 << 17 # 131072
|
||||||
|
LED19 = 1 << 18 # 262144
|
||||||
|
LED20 = 1 << 19 # 524288
|
||||||
|
LED21 = 1 << 20 # 1048576
|
||||||
|
LED22 = 1 << 21 # 2097152
|
||||||
|
LED23 = 1 << 22 # 4194304
|
||||||
|
LED24 = 1 << 23 # 8388608
|
||||||
|
LED25 = 1 << 24 # 16777216
|
||||||
|
LED26 = 1 << 25 # 33554432
|
||||||
|
LED27 = 1 << 26 # 67108864
|
||||||
|
LED28 = 1 << 27 # 134217728
|
||||||
|
LED29 = 1 << 28 # 268435456
|
||||||
|
LED30 = 1 << 29 # 536870912
|
||||||
|
LED31 = 1 << 30 # 1073741824
|
||||||
|
LED32 = 1 << 31 # 2147483648
|
||||||
|
LED33 = 1 << 32 # 4294967296
|
||||||
|
LED34 = 1 << 33 # 8589934592
|
||||||
|
LED35 = 1 << 34 # 17179869184
|
||||||
|
LED36 = 1 << 35 # 34359738368
|
||||||
|
LED37 = 1 << 36 # 68719476736
|
||||||
|
LED38 = 1 << 37 # 137438953472
|
||||||
|
LED39 = 1 << 38 # 274877906944
|
||||||
|
LED40 = 1 << 39 # 549755813888
|
||||||
|
LED41 = 1 << 40 # 1099511627776
|
||||||
|
LED42 = 1 << 41 # 2199023255552
|
||||||
|
LED43 = 1 << 42 # 4398046511104
|
||||||
|
LED44 = 1 << 43 # 8796093022208
|
||||||
|
LED45 = 1 << 44 # 17592186044416
|
||||||
|
|
||||||
|
leds = [
|
||||||
|
LED1, LED2, LED3, LED4, LED5,
|
||||||
|
LED6, LED7, LED8, LED9, LED10,
|
||||||
|
LED11, LED12, LED13, LED14, LED15,
|
||||||
|
LED16, LED17, LED18, LED19, LED20,
|
||||||
|
LED21, LED22, LED23, LED24, LED25,
|
||||||
|
LED26, LED27, LED28, LED29, LED30,
|
||||||
|
LED31, LED32, LED33, LED34, LED35,
|
||||||
|
LED36, LED37, LED38, LED39, LED40,
|
||||||
|
LED41, LED42, LED43, LED44, LED45
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_led_states(value):
|
||||||
|
return [(value & led) != 0 for led in leds]
|
||||||
|
|
||||||
|
|
||||||
|
_COLORS = [
|
||||||
|
VM_RED, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN,
|
||||||
|
VM_RED, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN,
|
||||||
|
VM_RED, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN,
|
||||||
|
VM_RED, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN,
|
||||||
|
VM_RED, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN, VM_GREEN
|
||||||
|
]
|
||||||
|
|
||||||
|
class MixerLeds:
|
||||||
|
def __init__(self, i2c):
|
||||||
|
self._i2c = i2c
|
||||||
|
self._pd = HUSB238(i2c)
|
||||||
|
self._pixels = neopixel.NeoPixel(board.D5, 45, auto_write=False)
|
||||||
|
self._known_wattage = 0
|
||||||
|
|
||||||
|
def _init_pd(self):
|
||||||
|
if not self._pd.connect():
|
||||||
|
print('Init PD failed to start connection')
|
||||||
|
return False
|
||||||
|
if self._known_wattage == self._pd.wattage:
|
||||||
|
return
|
||||||
|
available_wattage = self._pd.attempt_wattage(30)
|
||||||
|
self._known_wattage = available_wattage[1]
|
||||||
|
if not available_wattage[0]:
|
||||||
|
self._pixels.deinit()
|
||||||
|
available_brightness = available_wattage[1]/30.0
|
||||||
|
self._pixels = neopixel.NeoPixel(board.D5, 45, brightness=available_brightness, auto_write=False)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def set_state(self, state):
|
||||||
|
if not self._init_pd():
|
||||||
|
return
|
||||||
|
|
||||||
|
for idx, led_state in enumerate(get_led_states(state)):
|
||||||
|
if (led_state):
|
||||||
|
self._pixels[idx] = _COLORS[idx]
|
||||||
|
else:
|
||||||
|
self._pixels[idx] = (0,0,0)
|
||||||
|
self._pixels.show()
|
||||||
88
ControlMixerPython/power.py
Normal file
88
ControlMixerPython/power.py
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import adafruit_husb238
|
||||||
|
import time
|
||||||
|
|
||||||
|
class HUSB238:
|
||||||
|
_pd = None
|
||||||
|
|
||||||
|
def __init__(self, i2c):
|
||||||
|
self._i2c = i2c
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
if (self.is_connected()):
|
||||||
|
try:
|
||||||
|
return self._pd.attached
|
||||||
|
except Exception as e:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
self._pd = adafruit_husb238.Adafruit_HUSB238(self._i2c)
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
self._pd = None
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_connected(self):
|
||||||
|
if self._pd is not None:
|
||||||
|
try:
|
||||||
|
return self._pd.attached
|
||||||
|
except Exception as e:
|
||||||
|
self._pd = None
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def attempt_wattage(self, watts):
|
||||||
|
if not self.is_connected():
|
||||||
|
return False, 0
|
||||||
|
if self.wattage >= watts:
|
||||||
|
return True, self.wattage
|
||||||
|
voltages = self.available_voltages
|
||||||
|
next_voltage_index = voltages.index(self.voltage) + 1
|
||||||
|
while self.wattage < watts and next_voltage_index < len(voltages):
|
||||||
|
if not self.is_connected():
|
||||||
|
print('Connection lost')
|
||||||
|
return False, 0
|
||||||
|
target = voltages[next_voltage_index]
|
||||||
|
self.voltage = target
|
||||||
|
time.sleep(1)
|
||||||
|
if (self._pd.voltage != target):
|
||||||
|
print(f'Voltage did not switch to {target}v')
|
||||||
|
return False, self.wattage
|
||||||
|
next_voltage_index += 1
|
||||||
|
resulting_wattage = self.wattage
|
||||||
|
return resulting_wattage >= watts, resulting_wattage
|
||||||
|
|
||||||
|
@property
|
||||||
|
def wattage(self):
|
||||||
|
return self.voltage * self.current
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available_voltages(self):
|
||||||
|
return self._safe_pd_call(lambda: self._pd.available_voltages, [])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def voltage(self):
|
||||||
|
return self._safe_pd_call(lambda: self._pd.voltage, 0);
|
||||||
|
|
||||||
|
@voltage.setter
|
||||||
|
def voltage(self, value):
|
||||||
|
self._pd.voltage = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current(self):
|
||||||
|
return self._safe_pd_call(lambda: self._pd.current, 0)
|
||||||
|
|
||||||
|
def _unsafe_pd_call(self, func, default_val, attempts=20):
|
||||||
|
attempt_count = 0
|
||||||
|
while attempt_count < attempts:
|
||||||
|
try:
|
||||||
|
return func()
|
||||||
|
except Exception as e:
|
||||||
|
print('unsafe waiting')
|
||||||
|
time.sleep(0.5)
|
||||||
|
return default_val
|
||||||
|
|
||||||
|
def _safe_pd_call(self, func, default_val):
|
||||||
|
if self.is_connected():
|
||||||
|
return func()
|
||||||
|
else:
|
||||||
|
return default_val
|
||||||
Reference in New Issue
Block a user