from machine import Pin, SPI, I2C
import os
import sdcard
from time import ticks_ms, sleep_ms
import ssd1306
# SPI configuration for SD card
spi = SPI(2, baudrate=2000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
cs = Pin(5, Pin.OUT)
# Initialize SD card
sd = sdcard.SDCard(spi, cs)
os.mount(sd, "/sd")
# I2C configuration for OLED
i2c = I2C(0, scl=Pin(22), sda=Pin(21)) # GPIO 22 = SCL, GPIO 21 = SDA
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
# Function to display messages on OLED
def display_message(line1="", line2="", line3=""):
oled.fill(0) # Clear screen
oled.text(line1, 0, 0)
oled.text(line2, 0, 20)
oled.text(line3, 0, 40)
oled.show()
# Pin assignments
cap = Pin(21, Pin.IN) # Soil moisture sensor
button_1 = Pin(26, Pin.IN, Pin.PULL_DOWN)
button_2 = Pin(25, Pin.IN, Pin.PULL_DOWN)
blue = Pin(2, Pin.OUT)
# Variables
toggle_1 = False
toggle_2 = False
last_press_1 = 0
last_press_2 = 0
button_1_last = 0
button_2_last = 0
recording = False
start_time = 0
calibration = {"air": 0, "water": 100}
# Calibration function
def calibrate_sensor():
global calibration
display_message("Calibration:", "Hold in Air", "Press Both Buttons")
blue.value(1) # Turn on blue LED
stable = False
while not stable:
if button_1.value() and button_2.value():
air_value = cap.value()
display_message("Air Value:", str(air_value), "Release Buttons")
while button_1.value() or button_2.value():
pass
stable = True
calibration["air"] = air_value
display_message("Calibration:", "Hold in Water", "Press Both Buttons")
stable = False
while not stable:
if button_1.value() and button_2.value():
water_value = cap.value()
display_message("Water Value:", str(water_value), "Release Buttons")
while button_1.value() or button_2.value():
pass
stable = True
calibration["water"] = water_value
blue.value(0) # Turn off blue LED
display_message("Calibration Done!", "", "")
sleep_ms(2000)
# Function to map sensor value to percentage
def map_moisture(value, air, water):
return int((value - air) / (water - air) * 100)
# Check buttons
def check_buttons():
global toggle_1, toggle_2, last_press_1, last_press_2, button_1_last, button_2_last, recording, start_time
time_now = ticks_ms()
# Button 1 logic
button_1_now = button_1.value()
if button_1_now != button_1_last:
button_1_last = button_1_now
if button_1_now == 1: # Button press
toggle_1 = not toggle_1
last_press_1 = time_now
recording = toggle_1
if recording:
start_time = ticks_ms()
display_message("Recording:", "Started", "")
else:
display_message("Recording:", "Stopped", "")
sleep_ms(5)
# Button 2 logic
button_2_now = button_2.value()
if button_2_now != button_2_last:
button_2_last = button_2_now
if button_2_now == 1: # Button press
toggle_2 = not toggle_2
last_press_2 = time_now
if not recording:
save_to_sd()
display_message("Saving Data...", "", "")
sleep_ms(5)
# Save data to SD card
def save_to_sd():
try:
filename = "/sd/moisture_data.csv"
with open(filename, "w") as file:
file.write("Time (minutes),Moisture (%)\n")
for entry in data_log:
file.write(f"{entry[0]},{entry[1]}\n")
display_message("Data Saved!", filename, "")
except Exception as e:
display_message("Error:", str(e), "")
# Main loop
data_log = []
calibrate_sensor()
while True:
check_buttons()
if recording:
elapsed_time = (ticks_ms() - start_time) // 60000 # Convert ms to minutes
moisture = cap.value()
moisture_percent = map_moisture(moisture, calibration["air"], calibration["water"])
data_log.append((elapsed_time, moisture_percent))
display_message(f"Time: {elapsed_time} min", f"Moisture: {moisture_percent}%", "")
sleep_ms(1000)