#Smartegg incubator using PID controller
#esp32 and dht22
# setpoints for humidity and temperature
#Author Basheer N. J 23-12-2012
import machine
import utime
import dht
import math
from PID import PID
import tm1637
# Pin assignments
RELAY_PIN = 27
FAN_PIN = 26 # Replace with the actual GPIO pin for the fan
DHT_PIN = 4
BUTTON_DECREASE_PIN = 13
BUTTON_INCREASE_PIN = 12
BUTTON_TOGGLE_PIN = 14
# PID parameters
PID_PARAMS = {
'Kp': 1,
'Ki': 0.1,
'Kd': 0.05,
}
SETPOINTS = {
'temp': 37.5,
'humidity': 60,
}
# Initialize PID controllers
pid_temp = PID(PID_PARAMS['Kp'], PID_PARAMS['Ki'], PID_PARAMS['Kd'])
pid_temp.setpoint = SETPOINTS['temp']
pid_humidity = PID(PID_PARAMS['Kp'], PID_PARAMS['Ki'], PID_PARAMS['Kd'])
pid_humidity.setpoint = SETPOINTS['humidity']
# Setup DHT sensor
dht_sensor = dht.DHT22(machine.Pin(DHT_PIN))
# Setup relay and fan
relay = machine.Pin(RELAY_PIN, machine.Pin.OUT)
fan = machine.Pin(FAN_PIN, machine.Pin.OUT)
# Setup buttons
button_decrease = machine.Pin(BUTTON_DECREASE_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
button_increase = machine.Pin(BUTTON_INCREASE_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
button_toggle = machine.Pin(BUTTON_TOGGLE_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
# Setup TM1637 display
tm = tm1637.TM1637(clk=machine.Pin(18), dio=machine.Pin(19))
# Variable to track the current setpoint mode
current_setpoint = 'temp'
# Enum to represent different states
class State:
MEASURE = 1
TOGGLE_SETPOINT = 2
SET_SETPOINT = 3
# Initial state
current_state = State.MEASURE
def read_sensor_data():
"""Read temperature and humidity from the DHT sensor."""
dht_sensor.measure()
humidity = dht_sensor.humidity()
temperature = dht_sensor.temperature()
if math.isnan(humidity) or math.isnan(temperature):
raise ValueError("Failed to read from DHT sensor!")
return temperature, humidity
def update_pid_output(pid_controller, value):
"""Update PID controller output based on current value."""
pid_controller.update(value)
return max(0, min(100, pid_controller.output))
def control_devices(temp, humidity, temp_pid_output, humidity_pid_output):
"""Control relay and fan based on PID controller outputs."""
relay.value(int(temp < pid_temp.setpoint and temp_pid_output > 0))
fan.value(int(humidity > pid_humidity.setpoint and humidity_pid_output > 0))
def display_sensor_data(temp, humidity):
"""Display the current temperature and humidity on the TM1637 display."""
tm.show(f"T:{temp:.1f}C H:{int(humidity):02d}")
def display_setpoint():
"""Display the current setpoint value on the TM1637 display."""
if current_setpoint == 'temp':
value = pid_temp.setpoint
else:
value = pid_humidity.setpoint
tm.show(f"{current_setpoint.upper()}:{value:.1f}")
def adjust_setpoint(increment):
"""Adjust the current setpoint value (either temperature or humidity)."""
global current_setpoint
adjustment = 0.5 if current_setpoint == 'temp' else 2
if increment:
adjustment *= 1 # Increase
else:
adjustment *= -1 # Decrease
if current_setpoint == 'temp':
pid_temp.setpoint += adjustment
else:
pid_humidity.setpoint += adjustment
def toggle_setpoint():
"""Toggle between temperature and humidity setpoints."""
global current_setpoint
current_setpoint = 'humidity' if current_setpoint == 'temp' else 'temp'
def handle_button_inputs():
"""Handle button inputs for adjusting settings."""
utime.sleep_ms(50) # Debounce
if not button_decrease.value():
adjust_setpoint(increment=False)
elif not button_increase.value():
adjust_setpoint(increment=True)
elif not button_toggle.value():
toggle_setpoint()
utime.sleep_ms(200) # Debounce adjustment
def main():
"""Main loop for reading sensor data and managing the incubator."""
while True:
try:
temp, humidity =