#include <Wire.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
// Capteurs
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define DHTPIN 25
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int mq2Pin = 34;
const int ldrPin = 35;
// Actionneurs
const int relayPins[] = {19, 18, 5, 17};
const int buttonPins[] = {33, 32, 26, 27};
const int buzzerPin = 14;
bool relayState[4] = {false,false,false,false};
// Seuils
float tempThreshold = 30.0;
float humThreshold = 70.0;
int mq2Threshold = 2500;
int ldrThreshold = 500;
// EEPROM addresses
#define EEPROM_SIZE 64
#define ADDR_TEMP 0
#define ADDR_HUM 4
#define ADDR_MQ2 8
#define ADDR_LDR 12
// MENU
void printMenu() {
Serial.println("\n===== S.I.M.S. MENU =====");
Serial.println("1 - Voir seuils");
Serial.println("2 - Modifier seuils (T=xx H=xx M=xx L=xx)");
Serial.println("3 - Reset seuils par défaut");
Serial.println("4 - Voir état relais");
Serial.println("5 - Basculer relais (ex: 5 1 pour relais 1)");
Serial.println("==========================");
}
// EEPROM
void loadThresholds() {
EEPROM.get(ADDR_TEMP, tempThreshold);
EEPROM.get(ADDR_HUM, humThreshold);
EEPROM.get(ADDR_MQ2, mq2Threshold);
EEPROM.get(ADDR_LDR, ldrThreshold);
if(isnan(tempThreshold)) tempThreshold = 30.0;
if(isnan(humThreshold)) humThreshold = 70.0;
if(mq2Threshold <= 0) mq2Threshold = 2500;
if(ldrThreshold <= 0) ldrThreshold = 500;
}
void saveThresholds() {
EEPROM.put(ADDR_TEMP, tempThreshold);
EEPROM.put(ADDR_HUM, humThreshold);
EEPROM.put(ADDR_MQ2, mq2Threshold);
EEPROM.put(ADDR_LDR, ldrThreshold);
EEPROM.commit();
}
// SETUP
void setup() {
Serial.begin(115200);
EEPROM.begin(EEPROM_SIZE);
loadThresholds();
lcd.init();
lcd.backlight();
dht.begin();
for(int i=0;i<4;i++){
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], LOW);
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode(buzzerPin, OUTPUT);
Serial.println("=== S.I.M.S. Ready ===");
Serial.println("Press any key to show menu");
}
// LOOP
unsigned long lastPlot = 0;
const unsigned long plotInterval = 500;
void loop() {
// BOUTONS PHYSIQUES
for(int i=0;i<4;i++){
int reading = digitalRead(buttonPins[i]);
if(reading == LOW){
relayState[i] = !relayState[i];
digitalWrite(relayPins[i], relayState[i] ? HIGH : LOW);
Serial.printf("Relay%d=%d (bouton)\n", i+1, relayState[i] ? 1 : 0);
delay(100);
}
}
// PROCESS SERIAL MENU
if(Serial.available()) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
if(cmd.length() > 0){
printMenu();
}
if(cmd == "1") {
Serial.printf("Temp Threshold=%.1f C\n", tempThreshold);
Serial.printf("Hum Threshold=%.1f %%\n", humThreshold);
Serial.printf("MQ2 Threshold=%d\n", mq2Threshold);
Serial.printf("LDR Threshold=%d\n", ldrThreshold);
}
else if(cmd.startsWith("T=")) { tempThreshold = cmd.substring(2).toFloat(); saveThresholds(); Serial.println("Temp threshold updated"); }
else if(cmd.startsWith("H=")) { humThreshold = cmd.substring(2).toFloat(); saveThresholds(); Serial.println("Hum threshold updated"); }
else if(cmd.startsWith("M=")) { mq2Threshold = cmd.substring(2).toInt(); saveThresholds(); Serial.println("MQ2 threshold updated"); }
else if(cmd.startsWith("L=")) { ldrThreshold = cmd.substring(2).toInt(); saveThresholds(); Serial.println("LDR threshold updated"); }
else if(cmd == "3") { tempThreshold = 30; humThreshold = 70; mq2Threshold = 2500; ldrThreshold = 500; saveThresholds(); Serial.println("Thresholds reset to default"); }
else if(cmd == "4") { for(int i=0;i<4;i++) Serial.printf("Relay %d = %s\n", i+1, relayState[i]?"ON":"OFF"); }
else if(cmd.startsWith("5")) {
int idx = cmd.substring(2).toInt() - 1;
if(idx>=0 && idx<4){
relayState[idx] = !relayState[idx];
digitalWrite(relayPins[idx], relayState[idx] ? HIGH : LOW);
Serial.printf("Relay%d toggled %s\n", idx+1, relayState[idx]?"ON":"OFF");
}
}
}
// SERIAL PLOTTER & LCD
if(millis() - lastPlot >= plotInterval){
lastPlot = millis();
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
int mq2Value = analogRead(mq2Pin);
int ldrValue = analogRead(ldrPin);
bool alarm = (!isnan(temperature)&&!isnan(humidity)) &&
(temperature > tempThreshold || humidity > humThreshold ||
mq2Value > mq2Threshold || ldrValue < ldrThreshold);
alarm ? tone(buzzerPin, 2000) : noTone(buzzerPin);
// LCD
lcd.setCursor(0,0);
lcd.printf("T:%0.1f H:%0.0f%%", temperature, humidity);
lcd.setCursor(0,1);
lcd.printf("G:%d L:%d ", mq2Value, ldrValue);
}
}