#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// ----------------- Définir les pins -----------------
#define DHTPIN 4 // DHT22 connecté à GPIO4
#define DHTTYPE DHT22
#define LEDPIN 5 // LED alerte luminosité
#define RELAYPIN 16 // Relais pour pompe
#define SOILPIN 33 // Potentiomètre simulant humidité du sol
#define LDRPIN 34 // LDR pour luminosité
// Initialiser capteurs
DHT dht(DHTPIN, DHTTYPE);
// OLED 128x64
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ----------------- WiFi & MQTT -----------------
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
bool manualPumpControl = false; // Flag to indicate if pump was turned on via MQTT
bool manualPumpState = false;
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
Serial.println(message);
if (String(topic) == "agrismart/user/control/pump") {
if (message == "ON") {
manualPumpControl = true;
manualPumpState = true;
digitalWrite(RELAYPIN, HIGH);
} else if (message == "OFF") {
manualPumpControl = true;
manualPumpState = false;
digitalWrite(RELAYPIN, LOW);
} else if (message == "AUTO") {
manualPumpControl = false;
}
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("connected");
client.subscribe("agrismart/user/control/pump");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(LEDPIN, OUTPUT);
pinMode(RELAYPIN, OUTPUT);
// Initialiser OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("Erreur OLED");
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Connecting WiFi...");
display.display();
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > 3000) {
lastMsg = now;
// Lire capteurs
float temp = dht.readTemperature();
float hum = dht.readHumidity();
int soilRaw = analogRead(SOILPIN);
int soilPercent = map(soilRaw, 0, 4095, 0, 100);
int lightRaw = analogRead(LDRPIN);
int lightPercent = map(lightRaw, 0, 4095, 0, 100);
// MQTT Publish payload
StaticJsonDocument<200> doc;
doc["temp"] = temp;
doc["hum"] = hum;
doc["soil"] = soilPercent;
doc["light"] = lightRaw; // interface uses raw values (0-4095) for visualization
char jsonString[200];
serializeJson(doc, jsonString);
client.publish("agrismart/user/sensors", jsonString);
// Afficher dans le moniteur série
Serial.print("Payload sent: ");
Serial.println(jsonString);
// Afficher sur OLED
display.clearDisplay();
display.setCursor(0,0);
display.println("Smart Agriculture");
display.print("Temp: "); display.print(temp); display.println(" C");
display.print("Hum: "); display.print(hum); display.println(" %");
display.print("Soil: "); display.print(soilPercent); display.println(" %");
display.print("Light: "); display.print(lightPercent); display.println(" %");
display.println("MQTT: Connected");
display.display();
// 1. Contrôle relais pour pompe (Automatique)
if (!manualPumpControl) {
if(soilPercent < 30){
digitalWrite(RELAYPIN, HIGH);
} else {
digitalWrite(RELAYPIN, LOW);
}
}
// 2. Contrôle LED alerte luminosité (Automatique)
if(lightPercent < 30){
digitalWrite(LEDPIN, HIGH);
} else {
digitalWrite(LEDPIN, LOW);
}
}
}