from machine import Pin, PWM, I2C
import utime
from dht import DHT22
from i2c_lcd import I2cLcd
# ---------------------------------------------------------------
# KONFIGURASI PIN
# ---------------------------------------------------------------
sensor = DHT22(Pin(27)) # DHT22 di GPIO27
servo = PWM(Pin(26), freq=50) # Servo di GPIO26
LED_BIRU = Pin(14, Pin.OUT) # DINGIN
LED_HIJAU = Pin(12, Pin.OUT) # NORMAL
LED_KUNING = Pin(13, Pin.OUT) # HANGAT
LED_MERAH = Pin(25, Pin.OUT) # PANAS
# Matikan semua LED di awal
for led in [LED_BIRU, LED_HIJAU, LED_KUNING, LED_MERAH]:
led.value(0)
# ---------------------------------------------------------------
# LCD I2C 20x4
# ---------------------------------------------------------------
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
addr = i2c.scan()
lcd = I2cLcd(i2c, addr[0], 4, 20)
lcd.putstr("Inisialisasi...")
utime.sleep(2)
lcd.clear()
# ---------------------------------------------------------------
# DATA TRAIN
# ---------------------------------------------------------------
data_train = [15, 16, 17, 18, 19, 23, 24, 26, 27, 28,
30, 31, 33, 34, 35, 38, 39, 40, 42, 44]
K = 4 # jumlah cluster
# ---------------------------------------------------------------
# ALGORITMA K-MEANS
# ---------------------------------------------------------------
def kmeans(data, k, iterasi=10):
# inisialisasi centroid awal (ambil data awal dengan jarak terpisah)
centroid = [min(data), 24, 32, max(data)]
for _ in range(iterasi):
cluster = [[] for _ in range(k)]
for d in data:
jarak = [abs(d - c) for c in centroid]
idx = jarak.index(min(jarak))
cluster[idx].append(d)
for i in range(k):
if len(cluster[i]) > 0:
centroid[i] = sum(cluster[i]) / len(cluster[i])
return centroid
# Latih K-Means untuk mencari centroid
centroid = kmeans(data_train, K)
centroid.sort() # urutkan dari kecil ke besar agar sesuai Dingin→Panas
print("Centroid hasil training:", centroid)
# ---------------------------------------------------------------
# FUNGSI KLASIFIKASI & KONTROL
# ---------------------------------------------------------------
def klasifikasi_kmeans(x):
jarak = [abs(x - c) for c in centroid]
cluster = jarak.index(min(jarak))
if cluster == 0:
return "dingin", 0, 0
elif cluster == 1:
return "normal", 45, 100
elif cluster == 2:
return "hangat", 90, 300
else:
return "panas", 135, 600
def set_led(d=0, n=0, h=0, p=0):
LED_BIRU.value(d)
LED_HIJAU.value(n)
LED_KUNING.value(h)
LED_MERAH.value(p)
def set_servo_angle(angle):
duty = int(((angle / 180) * 2 + 0.5) / 20 * 1023)
servo.duty(duty)
def tampil_lcd(suhu, status, rpm):
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("Suhu: {:.1f} C".format(suhu))
lcd.move_to(0, 1)
lcd.putstr("Status: {}".format(status.upper()))
lcd.move_to(0, 2)
lcd.putstr("Kipas: {} RPM".format(rpm))
# ---------------------------------------------------------------
# LOOP UTAMA
# ---------------------------------------------------------------
print("=== SISTEM KLASIFIKASI SUHU (K-Means) ===")
while True:
try:
sensor.measure()
suhu = sensor.temperature()
status, angle, rpm = klasifikasi_kmeans(suhu)
# Reset LED
set_led(0, 0, 0, 0)
# Aktifkan LED sesuai status
if status == "dingin":
set_led(d=1)
elif status == "normal":
set_led(n=1)
elif status == "hangat":
set_led(h=1)
elif status == "panas":
set_led(p=1)
# Kontrol servo & tampilkan LCD
set_servo_angle(angle)
tampil_lcd(suhu, status, rpm)
print("🌡️ Suhu {:.1f}°C → {} (Servo {}°, {} RPM)".format(suhu, status.upper(), angle, rpm))
utime.sleep(3)
except Exception as e:
print("Error:", e)
lcd.clear()
lcd.putstr("Error Sensor!")
utime.sleep(2)
D4_KELAS 4C_TEKNIK ELEKTRONIKA POLINEMA
Syifa Nabila H, Prima Dionanda M, Yusuf Bryan
DATA TEST:
Suhu: 32.4 C
Status: HANGAT (LED KUNING ON)
Kipas: 300 RPM