# interface incremental encoder with interrupts
# raspberry pi pico and micropython
# https://diyprojectslab.com/rotary-encoder-with-raspberry-pi-pico/

# import libraries
from machine import Pin
import utime


# define encoder pins
switch = Pin(2, mode=Pin.IN, pull = Pin.PULL_UP) # inbuilt switch on the rotary encoder, ACTIVE LOW
outA = Pin(4, mode=Pin.IN) # Pin CLK of encoder
outB = Pin(3, mode=Pin.IN) # Pin DT of encoder

ledPin = Pin(25, mode = Pin.OUT, value = 0) # Onboard led on GPIO 25
# led.off()
#ledPin.on()

# define global variables
counter = 0   # counter updates when encoder rotates
direction = "" # empty string for registering direction change
outA_last = 0 # registers the last state of outA pin / CLK pin
outA_current = 0 # registers the current state of outA pin / CLK pin

button_last_state = False # initial state of encoder's button 
button_current_state = "" # empty string ---> current state of button

# Read the last state of CLK pin in the initialisaton phase of the program 
outA_last = outA.value() # lastStateCLK




# interrupt handler function (IRQ) for CLK and DT pins
def encoder(pin):
    # get global variables
    global counter
    global direction
    global outA_last
    global outA_current
    
    # read the value of current state of outA pin / CLK pin
    outA_current = outA.value()
    
    # if current state is not same as the last stare , encoder has rotated
    if outA_current != outA_last:
        # read outB pin/ DT pin
        # if DT value is not equal to CLK value
        # rotation is clockwise [or Counterclockwise ---> sensor dependent]
        if outB.value() != outA_current:
            counter += 1
            direction = "Clockwise"
        else:
            counter -= 1
            direction = "Counter Clockwise"
        
        # print the data on screen
        print("Counter : ", counter, "     |   Direction : ",direction)
        print("\n")

    outA_last = outA_current
    utime.sleep_ms(1) 
                      
    
def button(pin):
    # get global variable
    global button_last_state
    global button_current_state
    
    button_current_state = True
    
    if button_current_state != button_last_state:
       
       # write some code here for button press
    
        print("Button is Pressed ","\n")
                    
        utime.sleep_ms(10) # 10 millisecond sleep for button debounce ,
                       
        button_last_state = button_current_state
        
    
    

outA.irq(trigger = Pin.IRQ_RISING | Pin.IRQ_FALLING,
              handler = encoder)

# attach interrupt to the outB pin ( DT pin of encoder module )
outB.irq(trigger = Pin.IRQ_RISING | Pin.IRQ_FALLING ,
              handler = encoder)

# attach interrupt to the switch pin ( SW pin of encoder module )
switch.irq(trigger = Pin.IRQ_FALLING,
           handler = button)


while True:
   # ledPin.value(1)
   # utime.sleep(2)
       
    ledPin.toggle()
    utime.sleep(1)
    
    button_last_state = False # reset button last state to false again ,
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT