#MUHAMMAD IKMAL AFIFI BIN ISMAIL CB230183
import machine
import uasyncio as asyncio
from machine import Pin, ADC, I2C
from lcd1602 import LCD
from hcsr04 import HCSR04

# Initialize components
i2c = I2C(1, scl=Pin(7), sda=Pin(6))
lcd = LCD(i2c)
pot = ADC(28)
ledR = Pin(12, Pin.OUT)
ledG = Pin(13, Pin.OUT)
PB = Pin(16, Pin.IN, Pin.PULL_UP)
sensor = HCSR04(trigger_pin=2, echo_pin=3)

stop_blink = asyncio.Event()

# Blink red LED at 2Hz indicating startup
async def led_blink_startup():
    while not stop_blink.is_set():
        ledR.value(1)
        await asyncio.sleep(0.5)
        ledR.value(0)
        await asyncio.sleep(0.5)
    ledR.value(0)  # Ensure LED is off when stopping

# Display startup message
async def display_startup():
    lcd.clear()
    lcd.write(0, 0, "Pengesan Jarak")
    await asyncio.sleep(2)
    lcd.clear()
    lcd.write(0, 0, "Tekan PB")
    lcd.write(0, 1, "untuk MULA")
    while PB.value() == 1:
        await asyncio.sleep(0.1)
    stop_blink.set()  # Stop blinking when button is pressed

# Read potentiometer value and scale to 10-100 cm
async def select_distance(prompt):
    last_pot_value = None
    while True:
        anVal = pot.read_u16() / 65535.0
        pot_value = int(10 + anVal * 90)
        if pot_value != last_pot_value:
            lcd.clear()
            lcd.write(0, 0, prompt)
            lcd.write(0, 1, "Dist: {} cm".format(pot_value))
            last_pot_value = pot_value
        await asyncio.sleep(0.5)
        if PB.value() == 0:  # Button pressed
            await asyncio.sleep(0.2)  # Debounce delay
            while PB.value() == 0:
                await asyncio.sleep(0.1)  # Wait for button release
            return pot_value

# Scan mode: check distance and display object status
async def scan_mode(min_threshold, max_threshold):
    last_distance = None
    while True:
        distance = sensor.distance_cm()
        if distance != last_distance:
            if min_threshold <= distance <= max_threshold:
                ledG.off()
                lcd.clear()
                lcd.write(0, 0, "Distance: {} cm".format(distance))
                lcd.write(0, 1, "Status: OK")
            else:
                ledG.on()
                lcd.clear()
                lcd.write(0, 0, "Distance: {} cm".format(distance))
                lcd.write(0, 1, "OUT OF RANGE")
            last_distance = distance
        await asyncio.sleep(0.1)
        if PB.value() == 0:  # Button pressed
            await asyncio.sleep(0.2)  # Debounce delay
            while PB.value() == 0:
                await asyncio.sleep(0.1)  # Wait for button release
            ledG.off()
            return

# Main program
async def main():
    asyncio.create_task(led_blink_startup())
    await display_startup()
    while True:
        min_threshold = await select_distance("Select Min Dist")
        max_threshold = await select_distance("Select Max Dist")
        await scan_mode(min_threshold, max_threshold)

# Create event loop and tasks
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()

BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT