from machine import Pin, I2C, PWM
import time
import dht
# Library untuk I2C LCD
class I2cLcd:
# Constants
LCD_CLR = 0x01
LCD_HOME = 0x02
LCD_ENTRY_MODE = 0x04
LCD_ENTRY_INC = 0x02
LCD_ENTRY_SHIFT = 0x01
LCD_ON_CTRL = 0x08
LCD_ON_DISPLAY = 0x04
LCD_ON_CURSOR = 0x02
LCD_ON_BLINK = 0x01
LCD_MOVE = 0x10
LCD_MOVE_DISP = 0x08
LCD_MOVE_RIGHT = 0x04
LCD_FUNCTION = 0x20
LCD_FUNCTION_8BIT = 0x10
LCD_FUNCTION_2LINES = 0x08
LCD_FUNCTION_10DOTS = 0x04
LCD_CGRAM = 0x40
LCD_DDRAM = 0x80
LCD_RS = 0x01
LCD_RW = 0x02
LCD_EN = 0x04
def __init__(self, i2c, addr, rows, cols):
self.i2c = i2c
self.addr = addr
self.rows = rows
self.cols = cols
self.backlight = True
self.i2c.writeto(self.addr, bytearray([0x33])) # Initialize
self.i2c.writeto(self.addr, bytearray([0x32])) # Set to 4-bit mode
self.i2c.writeto(self.addr, bytearray([0x28])) # 2 line display
self.i2c.writeto(self.addr, bytearray([0x0C])) # Display on, cursor off
self.clear()
def clear(self):
self.command(self.LCD_CLR)
time.sleep_ms(2)
def command(self, cmd):
self.i2c.writeto(self.addr, bytearray([cmd & 0xF0 | 0x04]))
self.i2c.writeto(self.addr, bytearray([cmd & 0xF0]))
self.i2c.writeto(self.addr, bytearray([(cmd << 4) & 0xF0 | 0x04]))
self.i2c.writeto(self.addr, bytearray([(cmd << 4) & 0xF0]))
def putstr(self, string):
for char in string:
self.i2c.writeto(self.addr, bytearray([ord(char) & 0xF0 | 0x05]))
self.i2c.writeto(self.addr, bytearray([ord(char) & 0xF0 | 0x01]))
self.i2c.writeto(self.addr, bytearray([(ord(char) << 4) & 0xF0 | 0x05]))
self.i2c.writeto(self.addr, bytearray([(ord(char) << 4) & 0xF0 | 0x01]))
# Konfigurasi DHT22
dht_sensor = dht.DHT22(Pin(4))
# Konfigurasi I2C untuk LCD1602
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
# Konfigurasi Servo pada pin GPIO18
servo = PWM(Pin(18), freq=50)
# Fungsi untuk menggerakkan servo (0 derajat - 180 derajat)
def set_servo_angle(angle):
# Hitung duty cycle berdasarkan sudut (0-180 derajat)
minDuty = 40 # Duty cycle untuk 0 derajat
maxDuty = 115 # Duty cycle untuk 180 derajat
duty = int(minDuty + (angle / 180.0) * (maxDuty - minDuty))
servo.duty(duty)
# Fungsi untuk menampilkan data pada LCD
def update_lcd(text1, text2):
lcd.clear()
lcd.putstr(text1)
lcd.putstr(text2)
while True:
try:
# Membaca data dari sensor DHT22
dht_sensor.measure()
suhu = dht_sensor.temperature()
kelembaban = dht_sensor.humidity()
print(f"Suhu: {suhu}°C, Kelembaban: {kelembaban}%")
# Tampilkan data suhu dan kelembaban pada LCD
update_lcd(f"Suhu: {suhu}C", f"Kelembaban: {kelembaban}%")
# Cek apakah kelembaban rendah (misal < 40%)
if kelembaban < 40:
# Tampilkan penyiraman pada LCD
update_lcd("Penyiraman", "Aktif")
print("Penyiraman Aktif!")
# Menggerakkan servo ke sudut 90 derajat (aktif)
set_servo_angle(90)
else:
# Servo dalam keadaan mati (sudut 0 derajat)
set_servo_angle(0)
update_lcd(f"Suhu: {suhu}C", f"Kelembaban: {kelembaban}%")
time.sleep(2)
except OSError as e:
print("Gagal membaca sensor!")