from machine import Pin, ADC, I2C, PWM
import time
from lcd_i2c import I2cLcd # Pastikan library sudah diinstal
# Inisialisasi pin AOUT sensor gas (misalnya GPIO34)
gas_sensor_aout = ADC(Pin(34))
gas_sensor_aout.atten(ADC.ATTN_11DB) # Rentang ADC 0-3.3V
# Inisialisasi pin DOUT sensor gas (misalnya GPIO14)
gas_sensor_dout = Pin(14, Pin.IN)
# Inisialisasi pin buzzer (misalnya GPIO25) dengan PWM
buzzer_pwm = PWM(Pin(25), freq=1000, duty=0) # Frekuensi awal 1000 Hz, duty cycle 0 (mati)
# Inisialisasi pin sensor jarak ultrasonic (HC-SR04)
trigger_pin = Pin(12, Pin.OUT) # GPIO12 untuk trigger
echo_pin = Pin(13, Pin.IN) # GPIO13 untuk echo
# Inisialisasi pin servo (misalnya GPIO26) dengan PWM
servo_pwm = PWM(Pin(26), freq=50) # Frekuensi 50 Hz untuk servo
servo_pwm.duty(0) # Duty cycle awal 0 (posisi netral)
# Inisialisasi I2C untuk LCD
i2c = I2C(scl=Pin(22), sda=Pin(21), freq=400000) # GPIO22 (SCL), GPIO21 (SDA)
lcd = I2cLcd(i2c, 0x27, 2, 16) # Alamat I2C LCD 0x27, 2 baris, 16 kolom
# Frekuensi nada (dalam Hz)
NOTES = {
"NOTE_E5": 659,
"NOTE_D5": 587,
"NOTE_C5": 523,
"NOTE_B4": 494,
"NOTE_A4": 440,
"NOTE_G4": 392,
"NOTE_F5": 698,
"NOTE_G5": 784,
"REST": 0
}
# Melodi dan durasi
melody = [
NOTES["REST"], NOTES["NOTE_E5"], NOTES["NOTE_D5"], NOTES["NOTE_C5"], NOTES["NOTE_B4"], NOTES["NOTE_A4"], NOTES["NOTE_G4"], NOTES["NOTE_A4"], NOTES["NOTE_B4"],
NOTES["NOTE_G5"], NOTES["NOTE_E5"], NOTES["NOTE_F5"], NOTES["NOTE_G5"], NOTES["NOTE_E5"], NOTES["NOTE_F5"], NOTES["NOTE_G5"], NOTES["REST"],
NOTES["NOTE_E5"], NOTES["NOTE_C5"], NOTES["NOTE_D5"], NOTES["NOTE_E5"], NOTES["NOTE_C5"], NOTES["NOTE_D5"], NOTES["NOTE_E5"], NOTES["NOTE_C5"], NOTES["NOTE_D5"], NOTES["NOTE_E5"], NOTES["NOTE_D5"], NOTES["NOTE_C5"],
NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["REST"], NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["NOTE_G4"], NOTES["NOTE_A4"], NOTES["NOTE_G4"], NOTES["NOTE_G4"], NOTES["REST"], NOTES["NOTE_G4"],
NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["NOTE_C5"], NOTES["NOTE_B4"],
NOTES["NOTE_G5"], NOTES["NOTE_E5"], NOTES["NOTE_F5"], NOTES["NOTE_G5"], NOTES["NOTE_E5"], NOTES["NOTE_F5"], NOTES["NOTE_G5"],
NOTES["NOTE_E5"], NOTES["NOTE_C5"], NOTES["NOTE_D5"], NOTES["NOTE_E5"], NOTES["NOTE_C5"], NOTES["NOTE_D5"], NOTES["NOTE_E5"], NOTES["NOTE_C5"], NOTES["NOTE_D5"], NOTES["NOTE_E5"], NOTES["NOTE_D5"], NOTES["NOTE_C5"],
NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["REST"], NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["NOTE_G4"], NOTES["NOTE_A4"], NOTES["NOTE_G4"], NOTES["NOTE_G4"], NOTES["REST"], NOTES["NOTE_G4"], NOTES["NOTE_G4"],
NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["NOTE_A4"], NOTES["REST"], NOTES["NOTE_A4"], NOTES["NOTE_C5"], NOTES["NOTE_B4"], NOTES["NOTE_B4"], NOTES["NOTE_B4"], NOTES["NOTE_B4"], NOTES["NOTE_C5"], NOTES["REST"],
NOTES["REST"]
]
durations = [
4, 2, 2, 2, 2, 2, 2, 2, 4,
4, 8, 8, 4, 8, 8, 2, 2,
4, 8, 8, 4, 8, 8, 4, 8, 8, 4, 8, 8,
4, 8, 8, 4, 8, 8, 8, 8, 2, 8, 8,
8, 8, 4, 4, 4, 1,
4, 8, 8, 4, 8, 8, 1,
4, 8, 8, 4, 8, 8, 4, 8, 8, 4, 8, 8,
4, 8, 8, 4, 8, 8, 8, 8, 4, 4, 8, 8,
8, 8, 8, 8, 4, 4, 8, 8, 4, 4, 8, 8,
1
]
# Fungsi untuk membaca jarak dari sensor ultrasonic
def read_distance():
# Kirim pulsa trigger
trigger_pin.off()
time.sleep_us(2)
trigger_pin.on()
time.sleep_us(10)
trigger_pin.off()
# Baca waktu echo
while echo_pin.value() == 0:
pulse_start = time.ticks_us()
while echo_pin.value() == 1:
pulse_end = time.ticks_us()
# Hitung jarak (dalam cm)
pulse_duration = time.ticks_diff(pulse_end, pulse_start)
distance = (pulse_duration * 0.0343) / 2
return distance
# Fungsi untuk menggerakkan servo berdasarkan jarak
def move_servo(distance):
if distance < 10: # Jika jarak < 10 cm
servo_pwm.duty(40) # Posisi 0 derajat
elif distance < 20: # Jika jarak < 20 cm
servo_pwm.duty(77) # Posisi 90 derajat
else: # Jika jarak >= 20 cm
servo_pwm.duty(115) # Posisi 180 derajat
# Fungsi untuk memainkan melodi
def play_melody():
size = len(durations)
for note in range(size):
duration = 1000 // durations[note] # Durasi nada dalam ms
if melody[note] == NOTES["REST"]:
buzzer_pwm.duty(0) # Matikan buzzer untuk REST
else:
buzzer_pwm.freq(melody[note]) # Set frekuensi nada
buzzer_pwm.duty(512) # Duty cycle 50% untuk menghasilkan suara
time.sleep_ms(duration) # Jeda sesuai durasi nada
buzzer_pwm.duty(0) # Matikan buzzer setelah nada selesai
time.sleep_ms(int(duration * 0.3)) # Jeda antar nada
# Fungsi untuk membaca nilai analog sensor gas
def read_gas_sensor_analog():
return gas_sensor_aout.read()
# Loop utama
while True:
# Baca nilai analog sensor gas
gas_value_analog = read_gas_sensor_analog()
# Baca nilai digital sensor gas
gas_detected_digital = gas_sensor_dout.value()
# Baca jarak dari sensor ultrasonic
distance = read_distance()
# Gerakkan servo berdasarkan jarak
move_servo(distance)
# Tampilkan nilai ke LCD
lcd.clear()
lcd.putstr("Gas: " + str(gas_value_analog))
lcd.move_to(0, 1) # Pindah ke baris kedua
lcd.putstr("Dist: " + str(int(distance)) + " cm")
# Jika nilai analog > 1000 atau DOUT HIGH, mainkan melodi
if gas_value_analog > 1000 or gas_detected_digital == 1:
print("Gas terdeteksi! Memainkan melodi...")
play_melody()
else:
buzzer_pwm.duty(0) # Matikan buzzer jika tidak ada gas terdeteksi
time.sleep(1) # Jeda 1 detik sebelum membaca lagi