from machine import Pin
import utime
# Define button pins
button_pins = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
# Create Pin objects for buttons
buttons = [Pin(pin, Pin.IN, Pin.PULL_UP) for pin in button_pins]
# Define individual functions for each button press on each layer and button
def on_button_0_layer_1():
print("Layer 1: Function for Button 0")
def on_button_1_layer_1():
print("Layer 1: Function for Button 1")
def on_button_2_layer_1():
print("Layer 1: Function for Button 2")
def on_button_3_layer_1():
print("Layer 1: Function for Button 3")
def on_button_4_layer_1():
print("Layer 1: Function for Button 4")
def on_button_5_layer_1():
print("Layer 1: Function for Button 5")
def on_button_6_layer_1():
print("Layer 1: Function for Button 6")
def on_button_7_layer_1():
print("Layer 1: Function for Button 7")
def on_button_8_layer_1():
print("Layer 1: Function for Button 8")
def on_button_9_layer_1():
print("Layer 1: Function for Button 9")
def on_button_0_layer_2():
print("Layer 2: Function for Button 0")
def on_button_1_layer_2():
print("Layer 2: Function for Button 1")
def on_button_2_layer_2():
print("Layer 2: Function for Button 2")
def on_button_3_layer_2():
print("Layer 2: Function for Button 3")
def on_button_4_layer_2():
print("Layer 2: Function for Button 4")
def on_button_5_layer_2():
print("Layer 2: Function for Button 5")
def on_button_6_layer_2():
print("Layer 2: Function for Button 6")
def on_button_7_layer_2():
print("Layer 2: Function for Button 7")
def on_button_8_layer_2():
print("Layer 2: Function for Button 8")
def on_button_9_layer_2():
print("Layer 2: Function for Button 9")
def on_button_0_layer_3():
print("Layer 3: Function for Button 0")
def on_button_1_layer_3():
print("Layer 3: Function for Button 1")
def on_button_2_layer_3():
print("Layer 3: Function for Button 2")
def on_button_3_layer_3():
print("Layer 3: Function for Button 3")
def on_button_4_layer_3():
print("Layer 3: Function for Button 4")
def on_button_5_layer_3():
print("Layer 3: Function for Button 5")
def on_button_6_layer_3():
print("Layer 3: Function for Button 6")
def on_button_7_layer_3():
print("Layer 3: Function for Button 7")
def on_button_8_layer_3():
print("Layer 3: Function for Button 8")
def on_button_9_layer_3():
print("Layer 3: Function for Button 9")
# Create a dictionary to map pin objects to functions for each layer
button_mapping_layer_1 = {
buttons[0]: on_button_0_layer_1,
buttons[1]: on_button_1_layer_1,
buttons[2]: on_button_2_layer_1,
buttons[3]: on_button_3_layer_1,
buttons[4]: on_button_4_layer_1,
buttons[5]: on_button_5_layer_1,
buttons[6]: on_button_6_layer_1,
buttons[7]: on_button_7_layer_1,
buttons[8]: on_button_8_layer_1,
buttons[9]: on_button_9_layer_1,
}
button_mapping_layer_2 = {
buttons[0]: on_button_0_layer_2,
buttons[1]: on_button_1_layer_2,
buttons[2]: on_button_2_layer_2,
buttons[3]: on_button_3_layer_2,
buttons[4]: on_button_4_layer_2,
buttons[5]: on_button_5_layer_2,
buttons[6]: on_button_6_layer_2,
buttons[7]: on_button_7_layer_2,
buttons[8]: on_button_8_layer_2,
buttons[9]: on_button_9_layer_2,
}
button_mapping_layer_3 = {
buttons[0]: on_button_0_layer_3,
buttons[1]: on_button_1_layer_3,
buttons[2]: on_button_2_layer_3,
buttons[3]: on_button_3_layer_3,
buttons[4]: on_button_4_layer_3,
buttons[5]: on_button_5_layer_3,
buttons[6]: on_button_6_layer_3,
buttons[7]: on_button_7_layer_3,
buttons[8]: on_button_8_layer_3,
buttons[9]: on_button_9_layer_3,
}
# Dictionary to track the last known state and last press time of each button
last_button_state = {button: 1 for button in buttons} # Assuming pull-up, so the initial state is 1
last_button_press_time = {button: 0 for button in buttons}
# Debounce time in milliseconds for buttons
debounce_time = 50
# Rotary Encoder pins
encoder_dt_pin = 26
encoder_clk_pin = 22
encoder_sw_pin = 27
encoder_dt = Pin(encoder_dt_pin, Pin.IN, Pin.PULL_UP)
encoder_clk = Pin(encoder_clk_pin, Pin.IN, Pin.PULL_UP)
encoder_sw = Pin(encoder_sw_pin, Pin.IN, Pin.PULL_UP)
# Variables for rotary encoder
total_rotation = 1 # Start at level 1
last_dt_state = encoder_dt.value()
last_clk_state = encoder_clk.value()
encoder_sw_last_state = encoder_sw.value() # Initialize the variable
encoder_sw_press_time = 0 # Initialize the variable
# Function to handle button presses and call the corresponding function
def handle_button(pin):
global last_button_state, last_button_press_time
# Check for both rising and falling edges
pin_state = pin.value()
current_time = utime.ticks_ms()
if pin_state != last_button_state[pin]:
if pin_state == 0: # Falling edge (button press)
# Debounce the button press
if (current_time - last_button_press_time[pin]) > debounce_time:
# Call the corresponding function based on the current rotation level
if total_rotation == 1:
button_mapping_layer_1[pin]()
elif total_rotation == 2:
button_mapping_layer_2[pin]()
elif total_rotation == 3:
button_mapping_layer_3[pin]()
# Update the last press time
last_button_press_time[pin] = current_time
# Update the last known state
last_button_state[pin] = pin_state
# Function to handle rotary encoder rotation
def handle_rotary_encoder_rotation(pin):
global total_rotation, last_dt_state, last_clk_state
dt_state = encoder_dt.value()
clk_state = encoder_clk.value()
# Handle rotary encoder rotation
if pin == encoder_dt:
if dt_state != last_dt_state:
if dt_state == 0:
if clk_state == 0:
total_rotation = (total_rotation % 3) + 1 # Clockwise rotation
print(f"Rotated clockwise. Current level: {total_rotation}")
elif pin == encoder_clk:
if clk_state != last_clk_state:
if clk_state == 0:
if dt_state == 0:
total_rotation = (total_rotation - 2) % 3 + 1 # Counterclockwise rotation
print(f"Rotated counterclockwise. Current level: {total_rotation}")
last_dt_state = dt_state
last_clk_state = clk_state
# Function to handle rotary encoder switch press (using interrupt)
def handle_rotary_encoder_switch(pin):
global encoder_sw_last_state, encoder_sw_press_time
# Check for both rising and falling edges
pin_state = pin.value()
current_time = utime.ticks_ms()
if pin_state != encoder_sw_last_state:
if pin_state == 0: # Falling edge (switch press)
# Debounce the switch press
if (current_time - encoder_sw_press_time) > debounce_time:
# Call the corresponding function
print("Switch pressed")
# Update the last press time
encoder_sw_press_time = current_time
# Update the last known state
encoder_sw_last_state = pin_state
# Attach interrupt handlers to the buttons
for button in buttons:
button.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=lambda p, button=button: handle_button(button))
# Attach interrupt handlers to the rotary encoder signals
encoder_dt.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=lambda p, pin=encoder_dt: handle_rotary_encoder_rotation(pin))
encoder_clk.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=lambda p, pin=encoder_clk: handle_rotary_encoder_rotation(pin))
# Attach interrupt handler to the rotary encoder switch
encoder_sw.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=lambda p, pin=encoder_sw: handle_rotary_encoder_switch(pin))
# Main loop
while True:
utime.sleep_ms(10) # Adjust sleep time based on your needs