print("Hello, ESP32!")
import utime
from machine import Pin, ADC, PWM
from tfli import TFLite
# This is a new TFLite model trained to classify a single
# input value (from 0.0 to 1.0) into one of three categories.
knob_model_data = bytearray(b'\x1c\x00\x00\x00TFL3\x14\x00\x18\x00\x04\x00\x08\x00\x0c\x00\x10\x00\x14\x00\x00\x00\x18\x00\x03\x00\x00\x00\x14\x00\x00\x00\xb4\x01\x00\x00\xa4\x01\x00\x00L\x00\x00\x00\x0c\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x18\x00\x00\x00\xd0\x01\x00\x00\xfc\xff\xff\xff\x14\x00\x00\x00\x01\x00\x00\x00\x0c\x00\x00\x00\x08\x00\x0c\x00\x04\x00\x08\x00\x08\x00\x00\x00\x08\x00\x00\x00\x0f\x00\x00\x00H\x01\x00\x00@\x01\x00\x004\x01\x00\x00(\x01\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x18\x00\x00\x00\x04\x00\x00\x00\x1c\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x1c\x00\x00\x00\x04\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00\x0c\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\xfc\xff\xff\xff\x04\x00\x00\x00\x10\x00\x00\x00serving_default_x:0\x00\x01\x00\x00\x00\x0c\x00\x00\x00\x08\x00\x0c\x00\x04\x00\x08\x00\x04\x00\x00\x00\x01\x00\x00\x00\x0c\x00\x00\x00\x0c\x00\x10\x00\x0c\x00\x0c\x00\x08\x00\x04\x00\x0c\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x18\x00\x00\x00StatefulPartitionedCall:0\x00\xfc\xff\xff\xff\x04\x00\x00\x00\x07\x00\x00\x00dense\x00\x00\xfc\xff\xff\xff\x0c\x00\x00\x00\x04\x00\x00\x00\x0f\x00\x00\x00\xfc\xff\xff\xff\xfc\xff\xff\xff\x00\x00\x00\x00\xea\x9e\x19\xbf\x9a\x99\x19\xbf\xcd\xccL\xbe\xf3G\xb8\xbd\xf3G\xb8\xbd\x9a\x99\x19\xbf\xfc\xff\xff\xff\xcd\xcc\xcc\xbd\xcd\xcc\xcc\xbd\x00\x00\x80?')
TENSOR_ARENA_SIZE = 4 * 1024
LABELS = ["Low", "Medium", "High"]
## --- Peripheral Setup ---
# Input: Potentiometer on ADC capable pin 34
pot = ADC(Pin(34))
pot.atten(ADC.ATTN_11DB) # Configure for full 0-3.3V range
# Output: RGB LED (Common Anode)
# We use PWM to control brightness. 0=On, 1023=Off for common anode.
FREQ = 1000
red_pin = PWM(Pin(25), FREQ)
green_pin = PWM(Pin(26), FREQ)
blue_pin = PWM(Pin(27), FREQ)
def set_led_color(r, g, b):
# Invert duty cycle for common anode LED
red_pin.duty(1023 - r)
green_pin.duty(1023 - g)
blue_pin.duty(1023 - b)
## --- ML Model Setup ---
print("--- Smart Knob Classifier ---")
try:
knob_model = TFLite(knob_model_data, TENSOR_ARENA_SIZE)
print("Model initialized successfully.")
except Exception as e:
print(f"Failed to initialize model: {e}")
raise SystemExit
## --- Main Loop ---
while True:
# 1. Read sensor value (0-4095)
raw_value = pot.read()
# 2. Pre-process the data: Normalize to a 0.0-1.0 float
normalized_value = raw_value / 4095.0
# 3. Feed the value into the model
knob_model.input(normalized_value, "f")
# 4. Run inference
knob_model.invoke()
# 5. Get the output probabilities
output_data = knob_model.output("b")
# 6. Post-process: Find the highest probability to get the prediction
# The output is 3 bytes, each representing the probability of a class.
# We find the index of the largest byte.
predicted_index = output_data.index(max(output_data))
predicted_label = LABELS[predicted_index]
# 7. Take action based on the prediction
if predicted_label == "Low":
set_led_color(0, 0, 1023) # Blue
elif predicted_label == "Medium":
set_led_color(0, 1023, 0) # Green
else: # High
set_led_color(1023, 0, 0) # Red
print("Raw: {:4d}, Normalized: {:.2f} -> Prediction: {}".format(raw_value, normalized_value, predicted_label))
utime.sleep_ms(200)