# ADRIANA SARAH BINTI AHMAD FAIZA (52224123439) // PRACTICAL TEST
from machine import Pin, ADC, PWM, SoftI2C
import time
import dht
from i2c_lcd import I2cLcd
# Pin Definitions
DHT_PIN = 4 # DHT22 sensor pin
GAS_PIN = ADC(Pin(34)) # Wokwi Gas Sensor
GAS_PIN.atten(ADC.ATTN_11DB) # Set ADC to 0-3.3V range
TRIG_PIN = Pin(14, Pin.OUT) # Ultrasonic Trigger pin
ECHO_PIN = Pin(27, Pin.IN) # Ultrasonic Echo pin
LED_PIN = 2 # LED pin
SERVO_PIN = PWM(Pin(25), freq=50) # Servo Motor pin
I2C_SCL = Pin(22) # I2C Clock pin
I2C_SDA = Pin(21) # I2C Data pin
# I2C and LCD Initialization
i2c = SoftI2C(scl=I2C_SCL, sda=I2C_SDA)
lcd = I2cLcd(i2c, 0x27, 2, 16) # LCD (2 rows, 16 columns)
# DHT22 Initialization
dht_sensor = dht.DHT22(Pin(DHT_PIN))
# LED Setup
led = Pin(LED_PIN, Pin.OUT)
# Servo Motor Setup
servo = SERVO_PIN
# Blink LED for emergencies
def blink_led():
led.on()
time.sleep(0.5)
led.off()
time.sleep(0.5)
# Scale gas readings from ADC to ppm
def scale_gas_level_to_ppm(adc_value):
"""Scale the raw ADC value to a range of 0.1 ppm to 400 ppm."""
max_adc = 4095 # Max ADC value for 11dB attenuation
gas_ppm = 0.1 + (adc_value / max_adc) * (400 - 0.1)
return gas_ppm
# Measure distance using Ultrasonic Sensor
def get_distance():
TRIG_PIN.value(1)
time.sleep_us(10)
TRIG_PIN.value(0)
while ECHO_PIN.value() == 0:
pass
start = time.ticks_us()
while ECHO_PIN.value() == 1:
pass
end = time.ticks_us()
duration = time.ticks_diff(end, start)
return (duration / 2) / 29.1 # Speed of sound = 343 m/s
# Read sensors
def read_sensors():
try:
# DHT22 sensor
dht_sensor.measure()
temperature = dht_sensor.temperature()
humidity = dht_sensor.humidity()
# Gas sensor
gas_value = GAS_PIN.read()
gas_ppm = scale_gas_level_to_ppm(gas_value) # Scale gas value to ppm
# Ultrasonic sensor
distance = get_distance()
return temperature, humidity, gas_ppm, distance
except Exception as e:
print(f"Error reading sensors: {e}")
return None, None, None, None
# Display data on LCD
def display_on_lcd(temp, humidity, gas, distance):
lcd.clear()
lcd.putstr(f"Temp: {temp:.1f}C\nHum: {humidity:.1f}%")
time.sleep(2)
lcd.clear()
lcd.putstr(f"Gas: {gas:.1f}ppm\nDist: {distance:.1f}cm")
# Emergency Actions
def emergency_actions(temp, distance): # Removed gas sensor influence
if temp > 35 or distance < 20: # Gate logic only depends on temp and distance
print("Emergency condition detected!")
blink_led()
servo.duty(40) # Open vent (e.g., 90 degrees)
else:
print("Conditions normal. Closing gate...")
led.off()
servo.duty(0) # Close vent (e.g., 0 degrees)
# Main Loop
def main():
print("Starting Smart Agriculture System...")
time.sleep(2)
while True:
temp, humidity, gas, distance = read_sensors()
if temp is None or humidity is None or gas is None or distance is None:
print("Skipping cycle due to sensor error.")
continue
# Display data on LCD
display_on_lcd(temp, humidity, gas, distance)
# Check emergency conditions and act (gas sensor excluded)
emergency_actions(temp, distance)
time.sleep(2)
if __name__ == "__main__":
main()