92 lines
2.1 KiB
Python
92 lines
2.1 KiB
Python
import machine
|
|
from machine import Pin, ADC
|
|
from neopixel import NeoPixel
|
|
from time import sleep
|
|
|
|
machine.freq(240000000) # set the CPU frequency to 240 MHz
|
|
|
|
PIXELPIN = Pin(20, Pin.OUT)
|
|
NUM_PIXELS = 40
|
|
|
|
ADC0 = ADC(Pin(26))
|
|
ADC1 = ADC(Pin(27))
|
|
ADC2 = ADC(Pin(28))
|
|
|
|
|
|
def read_adc_float(adc: ADC) -> float:
|
|
value = adc.read_u16()
|
|
return value / 2**16
|
|
|
|
|
|
def read_adc(adc: ADC) -> int:
|
|
lower_limit = 1024
|
|
upper_limit = 1024
|
|
|
|
adc_range = 2**16
|
|
|
|
value = adc.read_u16()
|
|
|
|
if value < lower_limit:
|
|
return 0
|
|
if value > adc_range - upper_limit:
|
|
return 255
|
|
|
|
value -= lower_limit
|
|
|
|
value = min(value, adc_range - lower_limit - upper_limit)
|
|
|
|
return min(int(value / (adc_range - lower_limit - upper_limit) * 256), 255)
|
|
|
|
|
|
def float_to_u8(value: float) -> int:
|
|
return min(255, int(256 * value))
|
|
|
|
|
|
def denoise(value: float, factor: float = 0.05) -> float:
|
|
"""
|
|
Rescales the range of the float from 0.0 to 1.0 to factor to 1-factor.
|
|
Values below factor and above 1-factor are set to 0.0 and 1.0 respecitvely.
|
|
"""
|
|
|
|
if value < factor:
|
|
return 0.0
|
|
if value > 1 - factor:
|
|
return 1.0
|
|
|
|
return max(0.0, min(1.0, (value - factor) / (1 - 2 * factor)))
|
|
|
|
def gate(initial: float, new: float, gate: float) -> float:
|
|
"""
|
|
needs a minimum amount of change (given as gate) between the initial and the new value for the output to change.
|
|
"""
|
|
|
|
if abs(initial - new) > gate:
|
|
return new
|
|
|
|
return initial
|
|
|
|
|
|
np = NeoPixel(PIXELPIN, NUM_PIXELS, bpp=4)
|
|
|
|
r = 0.0
|
|
g = 0.0
|
|
b = 0.0
|
|
|
|
dampening_factor = 0.25
|
|
while True:
|
|
r = dampening_factor * gate(r, denoise(1-read_adc_float(ADC0)), 4.0/512) + (1-dampening_factor) * r
|
|
g = dampening_factor * gate(g, denoise(1-read_adc_float(ADC1)), 4.0/512) + (1-dampening_factor) * g
|
|
b = dampening_factor * gate(b, denoise(1-read_adc_float(ADC2)), 4.0/512) + (1-dampening_factor) * b
|
|
|
|
for i in range(0, NUM_PIXELS):
|
|
np[i] = (
|
|
float_to_u8(r),
|
|
float_to_u8(g),
|
|
float_to_u8(b),
|
|
float_to_u8(0.0),
|
|
)
|
|
|
|
np.write()
|
|
|
|
print(float_to_u8(r), float_to_u8(g), float_to_u8(b))
|
|
sleep(0.01)
|