#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <MPU6050.h>
/* Configuration réseau */
const char* ssid = "Wokwi-GUEST";
const char* password = "";
/* Configuration MQTT sécurisée */
const char* mqtt_server = "57789a6c640d4535a96ce70f90c9d5f4.s1.eu.hivemq.cloud";
const int mqtt_port = 8883;
const char* mqtt_user = "ESP32_Medical";
const char* mqtt_password = "ESP32_Medical";
const char* topic = "medical/sensors";
WiFiClientSecure espClient;
PubSubClient client(espClient);
/* Configuration hardware */
#define BTN_RFID_PIN 4 // Bouton vert sur GPIO4
#define LED_INT_PIN 2 // LED intégrée de l'ESP32
#define LED_ALERTE_PIN 23 // LED d'alerte externe sur GPIO23
#define NTC_PIN 34 // Capteur de température sur GPIO34
#define LED_ON LOW // Niveau logique pour allumer les LED
#define LED_OFF HIGH
MPU6050 mpu;
void initHardware() {
pinMode(LED_INT_PIN, OUTPUT);
pinMode(LED_ALERTE_PIN, OUTPUT);
pinMode(BTN_RFID_PIN, INPUT_PULLUP);
digitalWrite(LED_INT_PIN, LED_OFF);
digitalWrite(LED_ALERTE_PIN, LED_OFF);
Serial.begin(115200);
Wire.begin(21, 22); // I2C pins (SDA=21, SCL=22)
// Initialisation du MPU6050
mpu.initialize();
if (!mpu.testConnection()) {
Serial.println("[ERREUR] MPU6050 non détecté");
while (1) {
digitalWrite(LED_ALERTE_PIN, !digitalRead(LED_ALERTE_PIN)); // Clignotement d'erreur
delay(250);
}
}
Serial.println("[INFO] MPU6050 détecté");
}
void setup_wifi() {
Serial.print("\nConnexion au WiFi ");
WiFi.begin(ssid, password);
int tries = 0;
while (WiFi.status() != WL_CONNECTED && tries++ < 20) {
delay(500);
Serial.print(".");
digitalWrite(LED_INT_PIN, !digitalRead(LED_INT_PIN)); // Clignote pendant la connexion
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("\n[ERREUR] Impossible de se connecter au WiFi");
while (1) {
digitalWrite(LED_ALERTE_PIN, !digitalRead(LED_ALERTE_PIN)); // Clignotement d'erreur rapide
delay(100);
}
}
digitalWrite(LED_INT_PIN, LED_ON); // LED intégrée allumée = WiFi OK
Serial.println("\nWiFi connecté | IP: " + WiFi.localIP().toString());
}
void reconnectMQTT() {
while (!client.connected()) {
Serial.print("Tentative de connexion MQTT...");
String clientId = "ESP32Client-" + String(random(0xFFFF), HEX);
if (client.connect(clientId.c_str(), mqtt_user, mqtt_password)) {
Serial.println("OK");
digitalWrite(LED_INT_PIN, LED_OFF); // Éteindre LED WiFi quand MQTT connecté
} else {
Serial.println("ECHEC (rc=" + String(client.state()) + ")");
digitalWrite(LED_ALERTE_PIN, LED_ON); // Allumer LED alerte
delay(5000);
digitalWrite(LED_ALERTE_PIN, LED_OFF);
}
}
}
float readTemperature() {
// Lecture du capteur NTC (simulation dans Wokwi)
int rawValue = analogRead(NTC_PIN);
// Conversion en température (simulation pour Wokwi)
float temp = map(rawValue, 0, 4095, 350, 380) / 10.0; // 35.0°C - 38.0°C
return temp;
}
float readVibration() {
int16_t ax, ay, az;
mpu.getAcceleration(&ax, &ay, &az);
// Conversion en m/s² (1g = 9.81 m/s²)
float vibration = sqrt(ax * ax + ay * ay + az * az) / 16384.0 * 9.81;
return vibration;
}
float calculateError(float temp) {
// Simulation d'erreur de mesure (aléatoire ±0.5°C)
return (random(-50, 50) / 100.0);
}
String generateProductID(bool isRFID) {
return (isRFID ? "RFID-" : "VIRT-") + String(random(1000, 9999));
}
void publishSensorData() {
bool rfidDetected = (digitalRead(BTN_RFID_PIN) == LOW);
float temp = readTemperature();
float error = calculateError(temp);
float vibration = readVibration();
String etape = rfidDetected ? "sterilisation" : "production";
// Détection des alertes
bool tempAlert = temp > 37.5;
bool vibrationAlert = vibration > 10.0;
bool errorAlert = abs(error) > 0.3;
String payload = "{"
"\"id\":\"" + generateProductID(rfidDetected) + "\","
"\"temp\":" + String(temp, 1) + ","
"\"error\":" + String(error, 1) + ","
"\"vibration\":" + String(vibration, 1) + ","
"\"etape\":\"" + etape + "\","
"\"alertes\": {"
"\"temperature\":" + String(tempAlert ? "true" : "false") + ","
"\"vibration\":" + String(vibrationAlert ? "true" : "false") + ","
"\"precision\":" + String(errorAlert ? "true" : "false") +
"}"
"}";
if (client.publish(topic, payload.c_str())) {
Serial.println("[MQTT] Données envoyées ✔️");
} else {
Serial.println("[MQTT] Échec envoi ❌");
}
// Gestion des LED
bool anyAlert = tempAlert || vibrationAlert || errorAlert;
digitalWrite(LED_ALERTE_PIN, anyAlert ? LED_ON : LED_OFF);
Serial.println("[DATA] " + payload);
}
void setup() {
initHardware();
setup_wifi();
espClient.setInsecure(); // À remplacer par des certificats en production
client.setServer(mqtt_server, mqtt_port);
randomSeed(analogRead(0)); // Initialisation du générateur aléatoire
}
void loop() {
if (!client.connected()) {
reconnectMQTT();
}
client.loop();
publishSensorData();
delay(3000); // Envoi toutes les 3 secondes
}