"""
FILE: GallonCounter_Interrupt_ESP32
AUTHOR: rfgnerd & ChatGPT
DESCRIPTION: Demonstrates using an interrupt to respond to a switch
             within the water meter that trips when a gallon is
             measured
            Furthermore, a debounce timer is employed
HARDWARE: ESP32, TM1637 4-7seg over I2c
"""
import tm1637
from machine import Pin, Timer
import time
global gallons
gallons = 0
tm = tm1637.TM1637(clk=Pin(4), dio=Pin(5))
tm.number(round(gallons))
# Define pin numbers
button_pin = 27
led_pin = 2
# Initialize LED
led = Pin(led_pin, Pin.OUT)
led.value(0)
# Initialize button
button = Pin(button_pin, Pin.IN, Pin.PULL_UP)
# Debounce timer
debounce_time_ms = 200  # 200ms debounce
debounce_timer = Timer(-1)  # Virtual timer (ID -1 means software timer)
# Interrupt handler with debounce logic
def handle_interrupt(pin):
    global gallons
    # Disable further interrupts
    button.irq(handler=None)
    # Confirm it was a genuine press (not bouncing)
    if pin.value() == 0:
        print("Debounced interrupt triggered!")
        gallons = gallons + 1
        print("GALLONS ", gallons)
        tm.number(round(gallons))
        led.value(1)
        time.sleep(1)
        led.value(0)
    # Re-enable interrupt after debounce period
    debounce_timer.init(
        mode=Timer.ONE_SHOT,
        period=debounce_time_ms,
        callback=lambda t: button.irq(trigger=Pin.IRQ_FALLING, handler=handle_interrupt)
    )
# Attach initial interrupt
button.irq(trigger=Pin.IRQ_FALLING, handler=handle_interrupt)
# Main loop
while True:
    time.sleep(0.1)