You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.1 KiB
136 lines
4.1 KiB
#include <Arduino.h> |
|
#include <BLEDevice.h> |
|
#include <BLEServer.h> |
|
#include <BLEUtils.h> |
|
#include <BLE2902.h> |
|
|
|
// 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 |
|
}
|
|
|