import machine
import time
from machine import Pin, I2C
from onewire import OneWire
from ds18x20 import DS18X20
from dht import DHT22
# Configuration
DEBUG = True
TARGET_TEMP = 37.5
HYSTERESIS = 0.2
TURN_INTERVAL = 7200000 # 2h en ms
def log(msg):
if DEBUG:
print("[DEBUG]", msg)
class SafeLCD:
def __init__(self):
self._working = False
try:
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
self.i2c = I2C(0, sda=Pin(21), scl=Pin(22), freq=100000)
self.lcd = I2cLcd(self.i2c, 0x27, 4, 20)
self._working = True
log("LCD initialisé avec succès")
except Exception as e:
log(f"Erreur LCD: {e}")
def display(self, line1, line2=""):
if self._working:
self.lcd.clear()
self.lcd.putstr(line1[:20])
if line2:
self.lcd.move_to(0, 1)
self.lcd.putstr(line2[:20])
else:
print(f"[LCD] {line1}\n{line2}")
class TemperatureSystem:
def __init__(self):
self.simulated_temp = 37.2
self.simulated_hum = 40.0
self.use_simulation = False
self.ds_sensor = None
self.dht_sensor = None
# Initialisation DS18B20
try:
self.ow = OneWire(Pin(13))
self.ds_sensor = DS18X20(self.ow)
self.roms = self.ds_sensor.scan()
if self.roms:
log(f"DS18B20 trouvé: {self.roms}")
else:
self.use_simulation = True
except Exception as e:
log(f"Erreur DS18B20: {e}")
self.use_simulation = True
# Initialisation DHT22
try:
self.dht_sensor = DHT22(Pin(16))
log("DHT22 initialisé")
except Exception as e:
log(f"Erreur DHT22: {e}")
def read_sensors(self):
temp, hum = self.simulated_temp, self.simulated_hum
# Lecture DS18B20
if self.ds_sensor and self.roms:
try:
self.ds_sensor.convert_temp()
time.sleep_ms(750)
temp = self.ds_sensor.read_temp(self.roms[0])
except Exception as e:
log(f"Erreur lecture DS18B20: {e}")
# Lecture DHT22
if self.dht_sensor:
try:
self.dht_sensor.measure()
hum = self.dht_sensor.humidity()
temp = self.dht_sensor.temperature() if self.use_simulation else temp
except Exception as e:
log(f"Erreur lecture DHT22: {e}")
return temp, hum
class StepperController:
def __init__(self, pins):
self.pins = [Pin(p, Pin.OUT) for p in pins]
self.sequence = [
[1,0,0,1],
[1,0,0,0],
[1,1,0,0],
[0,1,0,0],
[0,1,1,0],
[0,0,1,0],
[0,0,1,1],
[0,0,0,1]
]
self.step_index = 0
def rotate(self, steps=50, delay=3):
for _ in range(steps):
for pin, val in zip(self.pins, self.sequence[self.step_index]):
pin.value(val)
time.sleep_ms(delay)
self.step_index = (self.step_index + 1) % len(self.sequence)
def main():
# Initialisation
lcd = SafeLCD()
temp_system = TemperatureSystem()
heater = Pin(5, Pin.OUT, value=0)
status_led = Pin(23, Pin.OUT, value=1)
stepper = StepperController([12, 14, 27, 26])
last_turn = time.ticks_ms()
heater_status = False
try:
while True:
# Lecture capteurs
temp, hum = temp_system.read_sensors()
# Contrôle température
if temp < TARGET_TEMP - HYSTERESIS and not heater_status:
heater.on()
heater_status = True
elif temp > TARGET_TEMP + HYSTERESIS and heater_status:
heater.off()
heater_status = False
# Rotation automatique
if time.ticks_diff(time.ticks_ms(), last_turn) >= TURN_INTERVAL:
log("Rotation des œufs")
stepper.rotate(steps=512, delay=5) # 1 tour complet
last_turn = time.ticks_ms()
# Affichage
lcd.display(
f"Temp: {temp:.1f}C Hum: {hum:.1f}%",
f"Chauffage: {'ON ' if heater_status else 'OFF'} Proch. rot: {((TURN_INTERVAL - time.ticks_diff(time.ticks_ms(), last_turn)) // 60000):02d}min"
)
time.sleep(1)
except KeyboardInterrupt:
log("Arrêt propre du système")
heater.off()
status_led.off()
lcd.display("Systeme arrete", "Merci!")
if __name__ == "__main__":
log("Démarrage du système...")
main()