# ==========================================================
# Reading Rotary Encoder Values - ESP32
# MicroPython - Wokwi Simulation
# ==========================================================
from machine import Pin
import time
# ---------------- Pin Configuration ----------------
clk = Pin(12, Pin.IN, Pin.PULL_UP)
dt = Pin(13, Pin.IN, Pin.PULL_UP)
sw = Pin(14, Pin.IN, Pin.PULL_UP)
# ---------------- Global Variables ----------------
counter = 0 # Encoder position counter
last_clk_state = clk.value() # Last known state of CLK pin
position_changed = False # Flag to indicate a new value should be printed
reset_flag = False # Flag to indicate button was pressed
# ==========================================================
# Interrupt Handler: Encoder Rotation (CLK pin)
# ==========================================================
def encoder_callback(pin):
global counter, last_clk_state, position_changed
clk_state = clk.value()
# Detect valid transition (falling edge on CLK)
if clk_state != last_clk_state and clk_state == 0:
dt_state = dt.value()
if dt_state != clk_state:
# Clockwise rotation
counter += 1
else:
# Counter-clockwise rotation
counter -= 1
position_changed = True
last_clk_state = clk_state
# ==========================================================
# Interrupt Handler: Push Button (SW pin) - Reset Counter
# ==========================================================
def button_callback(pin):
global counter, reset_flag
time.sleep_ms(50) # Simple debounce
if sw.value() == 0:
counter = 0
reset_flag = True
# ---------------- Attach Interrupts ----------------
clk.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=encoder_callback)
sw.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)
# ---------------- Startup Message ----------------
print("Rotary Encoder Reading Started...")
print("Current Position:", counter)
# ---------------- Main Loop ----------------
while True:
if position_changed:
print("Encoder Position:", counter)
position_changed = False
if reset_flag:
print("Button Pressed! Encoder Reset to:", counter)
reset_flag = False
time.sleep(0.05) # Small delay to reduce CPU load