from micropython import const
from machine import Pin, PWM, ADC
import time
print("---- Program start ----")
try:
# RGB PWMs - Pins 25, 27, 26
# Frequency 1000Hz is good for LEDs to avoid flickering
r_pwm = PWM(Pin(25), freq=1000)
g_pwm = PWM(Pin(27), freq=1000)
b_pwm = PWM(Pin(26), freq=1000)
# ADC Pin - Potentiometer on Pin 34
pot = ADC(Pin(34))
pot.atten(ADC.ATTN_11DB) # Allows reading up to ~3.3V
except Exception as e:
print("Hardware error: ", e)
def voltage_to_rgb_duty_values(val, adc_r=65535):
"""
Map ADC value (0-65535) to RGB transitions.
"""
# Define the max duty cycle for u16
MAX_DUTY = 65535
r_duty = 0
g_duty = 0
b_duty = 0
# Sector 1: Red to Green
if val < (adc_r // 3):
# Scale val to the 0 - MAX_DUTY range within this third
relative_val = val * 3
r_duty = MAX_DUTY - relative_val
g_duty = relative_val
b_duty = 0
# Sector 2: Green to Blue
elif val < (2 * adc_r // 3):
relative_val = (val - (adc_r // 3)) * 3
r_duty = 0
g_duty = MAX_DUTY - relative_val
b_duty = relative_val
# Sector 3: Blue to Red
else:
relative_val = (val - (2 * adc_r // 3)) * 3
r_duty = relative_val
g_duty = 0
b_duty = MAX_DUTY - relative_val
# Ensure we stay in bounds and return integers
return int(max(0, min(MAX_DUTY, r_duty))), \
int(max(0, min(MAX_DUTY, g_duty))), \
int(max(0, min(MAX_DUTY, b_duty)))
# Main Loop
while True:
try:
# Read the input voltage using 16-bit mapping (0-65535)
raw = pot.read_u16()
# Map input to RGB
rd, gd, bd = voltage_to_rgb_duty_values(raw)
# Apply the duty cycles
r_pwm.duty_u16(rd)
g_pwm.duty_u16(gd)
b_pwm.duty_u16(bd)
# Small delay for stability
time.sleep(0.02)
except KeyboardInterrupt:
print("Program stopped")
# Turn off LEDs on exit
r_pwm.duty_u16(0)
g_pwm.duty_u16(0)
b_pwm.duty_u16(0)
break