#include #include #include #include #include // UUID pour le service et la caractéristique BLE #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" // Configuration des GPIO à surveiller // Note: GPIO 16 et 17 peuvent poser problème (UART2/PSRAM) // Utilisation de GPIO plus fiables: 15, 4, 5, 18 const int GPIO_PINS[] = {15, 4, 5, 18}; // GPIOs à surveiller (A, B, C, D) const int NUM_PINS = sizeof(GPIO_PINS) / sizeof(GPIO_PINS[0]); // Variables globales BLEServer* pServer = NULL; BLECharacteristic* pCharacteristic = NULL; bool deviceConnected = false; bool oldDeviceConnected = false; uint8_t gpioStates = 0; // Stocke l'état des GPIOs (bit à bit) // Nom du module (peut être modifié pour chaque ESP32) String moduleName = "ESP32-Module-2"; class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; Serial.println("Client connecté"); }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; Serial.println("Client déconnecté"); } }; void setup() { Serial.begin(115200); Serial.println("Démarrage du module ESP32 Bluetooth..."); // Configuration des GPIO en entrée avec pull-up for (int i = 0; i < NUM_PINS; i++) { pinMode(GPIO_PINS[i], INPUT_PULLUP); } // Initialisation BLE BLEDevice::init(moduleName.c_str()); // Créer le serveur BLE pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); // Créer le service BLE BLEService *pService = pServer->createService(SERVICE_UUID); // Créer la caractéristique BLE pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_INDICATE ); // Créer un descripteur BLE2902 pour les notifications pCharacteristic->addDescriptor(new BLE2902()); // Démarrer le service pService->start(); // Démarrer l'advertising BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); pAdvertising->setScanResponse(false); pAdvertising->setMinPreferred(0x0); BLEDevice::startAdvertising(); // Initialiser l'état des GPIO for (int i = 0; i < NUM_PINS; i++) { int pinState = digitalRead(GPIO_PINS[i]); if (pinState == LOW) { gpioStates |= (1 << i); } } Serial.println("En attente de connexion..."); Serial.print("Nom du module: "); Serial.println(moduleName); } void loop() { // Lire l'état de toutes les GPIO uint8_t currentStates = 0; for (int i = 0; i < NUM_PINS; i++) { int pinState = digitalRead(GPIO_PINS[i]); if (pinState == LOW) { // GPIO à l'état bas currentStates |= (1 << i); } } // Créer un message JSON avec l'état des GPIO String message = "{\"module\":\"" + moduleName + "\",\"gpios\":["; for (int i = 0; i < NUM_PINS; i++) { message += "{\"pin\":" + String(GPIO_PINS[i]) + ",\"state\":"; message += ((currentStates & (1 << i)) ? "1" : "0"); message += "}"; if (i < NUM_PINS - 1) message += ","; } message += "]}"; // Mettre à jour la valeur de la caractéristique pCharacteristic->setValue(message.c_str()); // Si l'état a changé et qu'un client est connecté, envoyer notification if (currentStates != gpioStates && deviceConnected) { gpioStates = currentStates; pCharacteristic->notify(); Serial.println("État changé: " + message); } // Gestion de la reconnexion if (!deviceConnected && oldDeviceConnected) { delay(500); pServer->startAdvertising(); Serial.println("Redémarrage de l'advertising"); oldDeviceConnected = deviceConnected; } if (deviceConnected && !oldDeviceConnected) { oldDeviceConnected = deviceConnected; } delay(100); // Délai pour éviter une lecture trop fréquente }