from machine import Pin, ADC, PWM
import time
import dht
# ======= Inisialisasi =======
# Potensiometer (ADC) di GP26
pot = ADC(Pin(26))
# Servo di GP15, PWM 50Hz
servo = PWM(Pin(15))
servo.freq(50)
# Sensor DHT di GP20
d = dht.DHT22(Pin(20))
# Buzzer di GP0, PWM
buzzer = PWM(Pin(0))
buzzer.freq(1000) # default freq, nanti diubah untuk nada
# Fungsi map nilai ADC ke derajat servo (0–180°)
def map_range(x, in_min, in_max, out_min, out_max):
return int((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)
# Fungsi set sudut servo (derajat)
def set_servo_angle(angle):
# Duty uPulse: 0° ≈ 0.5 ms, 180° ≈ 2.5 ms
# Pada 50 Hz, period = 20 ms, duty_u16 max = 65535
min_d = 1638 # 0.5 ms → 1638/65535
max_d = 8192 # 2.5 ms → 8192/65535
duty = int(min_d + (max_d - min_d) * angle / 180)
servo.duty_u16(duty)
# Nada untuk buzzer (frekuensi dalam Hz)
notes = {
'C4': 262,
'D4': 294,
'E4': 330,
'G4': 392,
'A4': 440,
}
def play_tone(freq, duration_ms):
buzzer.freq(freq)
buzzer.duty_u16(32768) # set 50% duty
time.sleep_ms(duration_ms)
buzzer.duty_u16(0)
time.sleep_ms(50)
# ======= Loop Utama =======
last_pot = pot.read_u16()
while True:
# 1. Baca potensiometer
pot_val = pot.read_u16()
angle = map_range(pot_val, 0, 65535, 0, 180)
set_servo_angle(angle)
# Jika diputar CW (pot meningkat), servo bergerak CW (sudah di-handle oleh sudut)
# Jika CCW, sudut menurun otomatis
# 2. Baca sensor DHT
try:
d.measure()
temp = d.temperature()
hum = d.humidity()
except OSError:
# Gagal baca sensor, skip
temp = None
hum = None
# 3. Logika buzzer
if temp is not None and temp < 35:
# Satu nada (misal C4 selama 300 ms)
play_tone(notes['C4'], 300)
if hum is not None and hum > 50:
# Tiga nada berurutan: C4, E4, G4
play_tone(notes['C4'], 200)
play_tone(notes['E4'], 200)
play_tone(notes['G4'], 200)
time.sleep(2)