// ═══════════════════════════════════════════════════
// Maintenance Prédictive IoT — Industrie 4.0
// ESP32 + MPU6050 + DS18B20 + INA219 + LCD
// ═══════════════════════════════════════════════════
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Adafruit_MPU6050.h>
#include <DallasTemperature.h>
#include <Adafruit_INA219.h>
#include <LiquidCrystal_I2C.h>
// ── WiFi credentials (simulé sur Wokwi) ──────────
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASS = "";
// ── HiveMQ Cloud MQTT ─────────────────────────────
const char* MQTT_BROKER = "broker.hivemq.com";
const int MQTT_PORT = 1883;
const char* TOPIC_DATA = "usine/machine1/data";
const char* TOPIC_ALERT = "usine/machine1/alert";
// ── Seuils d'alarme ───────────────────────────────
const float TEMP_MAX = 75.0; // °C
const float ACCEL_MAX = 2.5; // m/s² (vibration)
const float CURRENT_MAX= 500.0; // mA (surcharge)
// ── Capteurs ──────────────────────────────────────
Adafruit_MPU6050 mpu;
OneWire oneWire(4);
DallasTemperature ds18(&oneWire);
Adafruit_INA219 ina219;
LiquidCrystal_I2C lcd(0x27, 16, 2);
WiFiClient wifiClient;
PubSubClient mqtt(wifiClient);
void setup() {
Serial.begin(115200);
lcd.begin(); lcd.backlight();
lcd.print("Initialisation...");
mpu.begin();
ds18.begin();
ina219.begin();
// Connexion WiFi
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print(".");
}
lcd.setCursor(0,1); lcd.print("WiFi OK");
mqtt.setServer(MQTT_BROKER, MQTT_PORT);
reconnectMQTT();
}
void loop() {
if (!mqtt.connected()) reconnectMQTT();
mqtt.loop();
// ── Lecture capteurs ─────────────────────────
sensors_event_t a, g, temp_ev;
mpu.getEvent(&a, &g, &temp_ev);
float accel = sqrt(
a.acceleration.x * a.acceleration.x +
a.acceleration.y * a.acceleration.y +
a.acceleration.z * a.acceleration.z
);
ds18.requestTemperatures();
float temp = ds18.getTempCByIndex(0);
float current = ina219.getCurrent_mA();
float power = ina219.getPower_mW();
// ── Détection anomalies ──────────────────────
bool alert = (temp > TEMP_MAX) ||
(accel > ACCEL_MAX) ||
(current > CURRENT_MAX);
// ── Payload JSON ─────────────────────────────
StaticJsonDocument<256> doc;
doc["machine"] = "machine1";
doc["temperature"] = round(temp * 10) / 10.0;
doc["vibration"] = round(accel * 100) / 100.0;
doc["current_mA"] = round(current);
doc["power_mW"] = round(power);
doc["alert"] = alert;
doc["status"] = alert ? "ANOMALIE" : "OK";
char buf[256];
serializeJson(doc, buf);
mqtt.publish(TOPIC_DATA, buf);
if (alert) {
char alertMsg[128];
snprintf(alertMsg, sizeof(alertMsg),
"{\"type\":\"ANOMALIE\",\"temp\":%.1f,\"vib\":%.2f}",
temp, accel);
mqtt.publish(TOPIC_ALERT, alertMsg);
}
// ── Affichage LCD ────────────────────────────
lcd.clear();
lcd.setCursor(0, 0);
lcd.printf("T:%.1fC V:%.2f", temp, accel);
lcd.setCursor(0, 1);
lcd.print(alert ? "[!] ALERTE " : "Statut: OK ");
Serial.println(buf);
delay(2000);
}
void reconnectMQTT() {
while (!mqtt.connected()) {
if (mqtt.connect("ESP32_Industrie40")) {
lcd.setCursor(0,1); lcd.print("MQTT OK! ");
} else delay(3000);
}
}