import time
import board
import analogio
import digitalio
import adafruit_dht
from adafruit_servokit import ServoKit
import adafruit_character_lcd.character_lcd_i2c as character_lcd

# Konfigurasi perangkat
lcd_columns = 20
lcd_rows = 4
i2c = board.I2C()
lcd = character_lcd.Character_LCD_I2C(i2c, lcd_columns, lcd_rows)

servo_kit = ServoKit(channels=16)
servo_motor = servo_kit.servo[0]

dht_device = adafruit_dht.DHT22(board.D38)

led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT

buzzer = digitalio.DigitalInOut(board.D14)
buzzer.direction = digitalio.Direction.OUTPUT

ultrasonic_trigger = digitalio.DigitalInOut(board.D21)
ultrasonic_trigger.direction = digitalio.Direction.OUTPUT

ultrasonic_echo = digitalio.DigitalInOut(board.D20)
ultrasonic_echo.direction = digitalio.Direction.INPUT

potensio_ph = analogio.AnalogIn(board.A0)
potensio_do = analogio.AnalogIn(board.A1)

led_pins = [digitalio.DigitalInOut(pin) for pin in (board.D2, board.D3, board.D4, board.D5,
                                                    board.D6, board.D7, board.D8, board.D9,
                                                    board.D0, board.D1)]

for led_pin in led_pins:
    led_pin.direction = digitalio.Direction.OUTPUT

# Fungsi untuk membaca jarak dengan sensor ultrasonik
def get_distance():
    ultrasonic_trigger.value = False
    time.sleep(0.000002)  # 2 microseconds
    ultrasonic_trigger.value = True
    time.sleep(0.00001)  # 10 microseconds
    ultrasonic_trigger.value = False

    start_time = time.monotonic()
    while not ultrasonic_echo.value:
        start_time = time.monotonic()

    stop_time = time.monotonic()
    while ultrasonic_echo.value:
        stop_time = time.monotonic()

    elapsed_time = stop_time - start_time
    distance = (elapsed_time * 34300) / 2  # Convert to cm
    return distance

# Fungsi untuk membaca nilai potensiometer
def read_potensio(potensio):
    return (potensio.value / 65535) * 1023  # Map ke range 0-1023

# Loop utama
while True:
    # Membaca nilai sensor
    ph_value = read_potensio(potensio_ph)
    do_value = read_potensio(potensio_do)

    ph_display = (ph_value / 1200.0) * 10
    do_display = (do_value / 1200.0) * 10

    # Logika untuk sensor PH dan DO
    if ph_display < 4:
        servo_motor.angle = 180
        buzzer.value = True
        led.value = False
    elif ph_display > 7:
        servo_motor.angle = 0
        buzzer.value = True
        led.value = True
    elif do_display < 3 or do_display > 5:
        servo_motor.angle = 0
        buzzer.value = True
        led.value = False
    else:
        servo_motor.angle = 0
        buzzer.value = False
        led.value = False

    # Membaca suhu dari sensor DHT
    try:
        temperature = dht_device.temperature
    except RuntimeError as error:
        print(f"Error reading temperature: {error}")
        temperature = None

    # Menentukan level LED bar berdasarkan suhu
    if temperature is not None:
        led_level = int((temperature - 20) / (50 - 20) * len(led_pins))
        for i, led_pin in enumerate(led_pins):
            led_pin.value = i < led_level

    # Membaca jarak dengan ultrasonik
    distance = get_distance()
    fertilizer_status = "HABIS" if distance > 10 else "TERSEDIA"

    # Menampilkan data pada LCD
    lcd.clear()
    lcd.message = (
        f"PH Air : {ph_display:.1f}\n"
        f"Oxygen : {do_display:.1f} mg\n"
        f"Suhu   : {temperature:.1f} C\n"
        f"Pupuk  : {fertilizer_status}\n"
    )

    time.sleep(1)
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT