from machine import Pin, ADC, I2C, SPI
from time import sleep, ticks_ms, ticks_diff
import os
import math
import sdcard
from ds1307 import DS1307
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
# === PIN SETUP ===
ntc_adc = ADC(Pin(12))
ntc_adc.atten(ADC.ATTN_11DB)
ntc_adc.width(ADC.WIDTH_12BIT)
ldr_adc = ADC(Pin(13))
ldr_adc.atten(ADC.ATTN_11DB)
ldr_adc.width(ADC.WIDTH_12BIT)
relay = Pin(15, Pin.OUT)
relay.off()
button = Pin(25, Pin.IN, Pin.PULL_UP)
red_led = Pin(26, Pin.OUT)
green_led = Pin(27, Pin.OUT)
blue_led = Pin(14, Pin.OUT)
red_led.on(); green_led.on(); blue_led.on()
white_led = Pin(33, Pin.OUT)
white_led.off()
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
rtc = DS1307(i2c)
lcd = I2cLcd(i2c, 0x27, 2, 16)
# === SD CARD INIT ===
sd_card_ok = False
try:
spi = SPI(1, baudrate=1000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
cs = Pin(5, Pin.OUT)
sd = sdcard.SDCard(spi, cs)
vfs = os.VfsFat(sd)
os.mount(vfs, "/sd")
sd_card_ok = True
lcd.move_to(0, 0)
lcd.putstr("SD Card OK ")
sleep(1)
except Exception as e:
lcd.move_to(0, 0)
lcd.putstr("SD Card Error ")
print("SD Card Error:", e)
sleep(2)
# === VARIABLES ===
is_manual_mode = False
last_button_press_time = 0
# === FUNCTIONS ===
def calculate_temperature(adc_val):
R_FIXED = 10000.0
BETA = 3950.0
T0 = 298.15
R0 = 10000.0
Vref = 3.3
voltage = adc_val / 4095 * Vref
try:
resistance = (voltage * R_FIXED) / (Vref - voltage)
except ZeroDivisionError:
resistance = 1e9
inv_T = 1/T0 + (1/BETA) * math.log(resistance / R0)
temp_K = 1 / inv_T
temp_C = temp_K - 273.15
return temp_C
def read_light_percent():
raw = ldr_adc.read()
light_percent = 100 - int((raw / 4095) * 100)
return light_percent
def update_led_by_temp(temp):
if temp <= 25:
red_led.on(); green_led.on(); blue_led.off() # Blue
elif temp <= 30:
red_led.on(); green_led.off(); blue_led.on() # Green
else:
red_led.off(); green_led.on(); blue_led.on() # Red
def update_white_led(light):
white_led.on() if light < 10 else white_led.off()
def button_handler(pin):
global is_manual_mode, last_button_press_time
now = ticks_ms()
if ticks_diff(now, last_button_press_time) > 500:
is_manual_mode = not is_manual_mode
last_button_press_time = now
button.irq(trigger=Pin.IRQ_FALLING, handler=button_handler)
def display_normal(temp, light):
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("T:{:.1f}C L:{:3d}%".format(temp, light))
lcd.move_to(0, 1)
if temp <= 25:
lcd.putstr("Low Temperature ")
elif temp <= 30:
lcd.putstr("Moderate Temp ")
else:
if light <= 10:
lcd.putstr("Night Mode ")
else:
lcd.putstr("Ready Condition ")
def display_special(message):
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr(message)
lcd.move_to(0, 1)
lcd.putstr(" ")
def log_data(temp, light):
if not sd_card_ok:
return
try:
t = rtc.datetime()
timestamp = "{:02d}/{:02d} {:02d}:{:02d}:{:02d}".format(t[2], t[1], t[4], t[5], t[6])
data = "{}, Temp:{:.1f}C, Light:{}%\n".format(timestamp, temp, light)
with open("/sd/data.txt", "a") as f:
f.write(data)
except Exception as e:
print("Log error:", e)
# === MAIN LOOP ===
last_log_second = -1
while True:
adc_val = ntc_adc.read()
temp_c = calculate_temperature(adc_val)
light_percent = read_light_percent()
update_led_by_temp(temp_c)
update_white_led(light_percent)
watering = False
if is_manual_mode:
watering = True
display_special(" MODE : MANUAL ")
relay.on()
sleep(5)
relay.off()
is_manual_mode = False
elif temp_c > 30 and light_percent > 10:
watering = True
display_special(" HIGH TEMP !!!")
sleep(1)
display_special(" WATERING... ")
relay.on()
sleep(5)
relay.off()
if not watering:
display_normal(temp_c, light_percent)
t = rtc.datetime()
if t[6] % 10 == 0 and t[6] != last_log_second:
log_data(temp_c, light_percent)
last_log_second = t[6]
sleep(0.5)