diff --git a/README.md b/README.md index a8678e2..471c3eb 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,22 @@ -# ESP32 Bluetooth HTML Monitor +# BleQuiz -Système de surveillance Bluetooth permettant de connecter plusieurs modules ESP32 et d'afficher l'état de leurs GPIOs en temps réel sur une page web. +Application HTML5 de quiz temps réel pour plusieurs modules ESP32 via Bluetooth Low Energy (BLE) -## 📋 Fonctionnalités +## 📋 Description -- ✅ Connexion de plusieurs modules ESP32 via Bluetooth (Web Bluetooth API) -- ✅ Affichage en temps réel de l'état des GPIOs -- ✅ Interface web moderne et responsive -- ✅ Notifications visuelles lors des changements d'état -- ✅ Gestion automatique de la reconnexion +BleQuiz permet de créer un système de quiz interactif en temps réel où plusieurs ESP32 peuvent être connectés simultanément via Bluetooth. Chaque module ESP32 surveille des GPIOs (boutons) et envoie instantanément les événements à une interface web HTML5. + +**Cas d'usage** : Quiz en classe, jeux de rapidité, systèmes de vote, buzzers interactifs. ## 🔧 Configuration ### ESP32 (src/main.cpp) -Par défaut, le code surveille 4 GPIOs : **15, 16, 17, 18** +Par défaut, le code surveille 4 GPIOs : **2, 4, 5, 6** (compatibles ESP32 Wrover et ESP32-C3) Pour modifier les GPIOs surveillés, éditez cette ligne : ```cpp -const int GPIO_PINS[] = {15, 16, 17, 18}; // Modifier selon vos besoins +const int GPIO_PINS[] = {2, 4, 5, 6}; // GPIOs à surveiller (A, B, C, D) ``` Pour changer le nom du module (important pour différencier plusieurs ESP32) : @@ -35,39 +33,69 @@ Le système envoie une notification à la page HTML **quand un GPIO passe à l' ## 🚀 Installation et utilisation -### 1. Compiler et téléverser sur ESP32 +### 1. Prérequis + +- **PlatformIO** installé (via VS Code ou CLI) +- **Python 3** (pour le serveur HTTPS) +- **Navigateur compatible** : Chrome, Edge ou Opera (Firefox et Safari ne supportent pas Web Bluetooth) + +### 2. Configuration des ESP32 +Le projet supporte deux environnements (voir `platformio.ini`) : +- **esp32dev** : ESP32 Wrover standard +- **esp32-c3-supermini** : Seeed XIAO ESP32-C3 (ou module générique ESP32-C3) + +**Compiler et téléverser pour ESP32 Wrover** : ```bash -# Compiler le projet -pio run +pio run -e esp32dev +pio run -e esp32dev --target upload +``` -# Téléverser sur l'ESP32 -pio run --target upload +**Compiler et téléverser pour ESP32-C3** : +```bash +pio run -e esp32-c3-supermini +pio run -e esp32-c3-supermini --target upload +``` -# Monitorer le port série (optionnel) +**Monitorer le port série** (optionnel) : +```bash pio device monitor ``` -### 2. Démarrer le serveur HTTPS +⚠️ **Important** : Si vous utilisez plusieurs modules, modifiez le nom de chaque module dans `src/main.cpp` : +```cpp +String moduleName = "ESP32-Module-1"; // Changer pour Module-2, Module-3, etc. +``` + +### 3. Démarrer le serveur HTTPS ⚠️ **Important** : Web Bluetooth nécessite HTTPS (ou localhost en HTTP) -**Option A - Serveur Python (recommandé)** : +**Option A - Script automatique (Linux)** : +```bash +./start.sh +``` +Ce script : +- Démarre automatiquement le serveur Python HTTPS +- Lance Chrome avec les flags Web Bluetooth appropriés +- Ouvre directement l'application à `https://localhost:8443` + +**Option B - Serveur Python manuel** : ```bash python3 server.py ``` -**Option B - Serveur Node.js** : +**Option C - Serveur Node.js** : ```bash node server.js ``` -Les deux serveurs : +Les serveurs Python et Node.js : - Génèrent automatiquement un certificat SSL auto-signé - Démarrent sur `https://localhost:8443` - Servent la page HTML avec support Bluetooth -### 3. Ouvrir dans le navigateur +### 4. Ouvrir dans le navigateur Ouvrez **Chrome**, **Edge** ou **Opera** et accédez à : ``` @@ -77,13 +105,14 @@ https://localhost:8443 **Note** : - Vous verrez un avertissement de sécurité (certificat auto-signé) → Cliquez sur "Avancé" puis "Continuer vers localhost" - Firefox et Safari ne supportent pas encore Web Bluetooth +- Sur Linux, utilisez le script `start.sh` pour lancer Chrome avec les bons paramètres -### 3. Connecter les modules +### 5. Utiliser l'application -1. Cliquez sur **"Connecter un module"** -2. Sélectionnez votre ESP32 dans la liste -3. Les GPIOs s'affichent en temps réel -4. Répétez pour connecter plusieurs modules +1. **Charger un fichier de questions** : Cliquez sur "Choisir un fichier" et sélectionnez votre fichier de quiz (voir `quiz_exemple.txt`) +2. **Connecter les modules** : Cliquez sur "Connecter un module" et sélectionnez votre ESP32 +3. **Lancer le quiz** : Naviguez entre les questions, les modules répondent en appuyant sur leurs boutons +4. **Répétez** pour connecter plusieurs modules simultanément ## 🌐 Pourquoi HTTPS est nécessaire ? @@ -96,47 +125,88 @@ Les serveurs fournis (`server.py` et `server.js`) génèrent automatiquement un ## 🔌 Branchement des GPIOs -Pour tester, connectez vos GPIOs à la masse (GND) : +Pour tester, connectez vos boutons/switches entre les GPIOs et la masse (GND) : ``` -ESP32 Bouton/Capteur -GPIO 15 ---- [Switch] ---- GND -GPIO 16 ---- [Switch] ---- GND -GPIO 17 ---- [Switch] ---- GND -GPIO 18 ---- [Switch] ---- GND +ESP32 Bouton/Switch +GPIO 2 ---- [Bouton A] ---- GND +GPIO 4 ---- [Bouton B] ---- GND +GPIO 5 ---- [Bouton C] ---- GND +GPIO 6 ---- [Bouton D] ---- GND ``` -## 📊 Format des données +**Configuration** : Les GPIOs utilisent des résistances de pull-up internes, donc : +- État normal (bouton non pressé) : HIGH (3.3V) +- État actif (bouton pressé) : LOW (0V / GND) + +## 📁 Structure du projet + +``` +BleQuiz/ +├── index.html # Interface web du quiz +├── platformio.ini # Configuration PlatformIO (esp32dev, esp32-c3) +├── server.py # Serveur HTTPS Python +├── server.js # Serveur HTTPS Node.js +├── start.sh # Script de lancement automatique (Linux) +├── quiz_exemple.txt # Exemple de fichier de questions +├── src/ +│ └── main.cpp # Code ESP32 (BLE + GPIO) +└── include/ + └── README +``` -Les données sont envoyées en JSON : +## 📊 Format des données BLE + +Les données sont envoyées en JSON via Bluetooth Low Energy : ```json { "module": "ESP32-Module-1", "gpios": [ - {"pin": 15, "state": "0"}, - {"pin": 16, "state": "1"}, - {"pin": 17, "state": "0"}, - {"pin": 18, "state": "0"} + {"pin": 2, "state": "0"}, + {"pin": 4, "state": "1"}, + {"pin": 5, "state": "0"}, + {"pin": 6, "state": "0"} ] } ``` -- `state: "0"` = GPIO HIGH (état normal) -- `state: "1"` = GPIO LOW (état actif) +- `state: "0"` = GPIO HIGH (bouton non pressé) +- `state: "1"` = GPIO LOW (bouton pressé) -## 🎨 Interface +## 🎨 Fonctionnalités de l'interface -L'interface affiche : -- Le nom de chaque module connecté -- L'état de chaque GPIO (HAUT/BAS) avec code couleur -- L'horodatage de la dernière mise à jour -- Des animations visuelles lors des changements d'état +L'application web offre : +- **Chargement de quiz** : Support de fichiers texte avec questions et réponses +- **Connexion multi-modules** : Connectez jusqu'à 10 ESP32 simultanément +- **Affichage en temps réel** : État des boutons de chaque module avec code couleur +- **Système de scoring** : Points automatiques pour les bonnes réponses +- **Mode de jeu** : Détection du premier à répondre avec verrouillage +- **Animations visuelles** : Feedback instantané lors des appuis +- **Historique** : Suivi des réponses et du temps de réaction ## ⚙️ Personnalisation +### Changer le nom du module ESP32 + +Dans `src/main.cpp`, modifiez : +```cpp +String moduleName = "ESP32-Module-1"; // Changer pour chaque ESP32 (Module-2, Module-3, etc.) +``` + +### Modifier les GPIOs surveillés + +Dans `src/main.cpp`, adaptez selon votre matériel : +```cpp +const int GPIO_PINS[] = {2, 4, 5, 6}; // GPIOs à surveiller +``` + +**GPIOs recommandés** : +- **ESP32 Wrover** : 2, 4, 5, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23 +- **ESP32-C3** : 2, 3, 4, 5, 6, 7, 8, 9, 10 + ### Changer les UUID Bluetooth -Dans `main.cpp` et `index.html`, modifiez : +Dans `src/main.cpp` et `index.html`, modifiez (doit être identique des deux côtés) : ```cpp #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" @@ -144,37 +214,134 @@ Dans `main.cpp` et `index.html`, modifiez : ### Modifier le délai de lecture -Dans `main.cpp`, ligne finale : +Dans `src/main.cpp`, dernière ligne de `loop()` : ```cpp delay(100); // Modifier selon vos besoins (en millisecondes) ``` -## 🐛 Dépannage +### Format du fichier de quiz -**L'ESP32 n'apparaît pas dans la liste Bluetooth** -- Vérifiez que le module est alimenté -- Consultez le moniteur série pour voir les messages de démarrage -- Assurez-vous que le Bluetooth est activé sur votre PC +Créez un fichier texte avec ce format (voir `quiz_exemple.txt`) : +``` +* Quelle est la formule de l'ion fer(III) ? +- Fe^(2+) ++ Fe^(3+) +- Fe_(2)^(3-) +- Fe_(3)^(2+) + +* Question suivante ? +- Mauvaise réponse +- Autre mauvaise réponse ++ Bonne réponse +- Encore une mauvaise réponse +``` + +**Format** : +- `*` = Question +- `-` = Mauvaise réponse +- `+` = Bonne réponse -**Pas de données reçues** -- Vérifiez les UUID dans le code ESP32 et HTML -- Consultez la console JavaScript (F12) pour les erreurs -- Testez en connectant un GPIO à GND +**Syntaxe pour indices et exposants** : +- `^(texte)` = exposant → `Fe^(3+)` s'affiche comme Fe³⁺ +- `_(texte)` = indice → `H_(2)O` s'affiche comme H₂O +- Combinaison possible : `Fe_(2)O_(3)` → Fe₂O₃ -**Déconnexions fréquentes** -- Vérifiez la distance entre l'ESP32 et le PC -- Assurez-vous que l'alimentation de l'ESP32 est stable +## 🐛 Dépannage + +### L'ESP32 n'apparaît pas dans la liste Bluetooth +- Vérifiez que le module est alimenté correctement (USB ou externe 5V) +- Consultez le moniteur série : `pio device monitor` pour voir les messages de démarrage +- Assurez-vous que le Bluetooth est activé sur votre ordinateur +- Sur Linux, vérifiez que BlueZ est à jour : `bluetoothctl --version` +- Redémarrez l'ESP32 (bouton RESET ou débrancher/rebrancher) + +### Pas de données reçues dans l'interface web +- Vérifiez que les UUID correspondent dans `src/main.cpp` et `index.html` +- Consultez la console JavaScript (F12) pour voir les erreurs +- Testez en connectant un GPIO à GND avec un simple fil +- Vérifiez que le module est bien connecté (voyant dans l'interface) + +### Déconnexions fréquentes +- Réduisez la distance entre l'ESP32 et l'ordinateur (< 5 mètres) +- Assurez-vous que l'alimentation de l'ESP32 est stable (câble USB de qualité) +- Évitez les interférences (WiFi 2.4GHz, micro-ondes) +- Augmentez le délai dans la boucle principale si trop de données sont envoyées + +### Erreur "HTTPS required" ou "Bluetooth API not available" +- Vérifiez que vous accédez bien à `https://localhost:8443` (pas `http://`) +- Utilisez Chrome, Edge ou Opera (pas Firefox ni Safari) +- Sur Linux, utilisez le script `./start.sh` pour les bons paramètres Chrome + +### Erreur de compilation PlatformIO +- Vérifiez votre environnement dans `platformio.ini` +- Mettez à jour PlatformIO : `pio upgrade` +- Nettoyez le projet : `pio run --target clean` +- Réinstallez les dépendances : `pio pkg update` + +## 📝 Caractéristiques techniques + +- **Protocole** : Bluetooth Low Energy (BLE 4.0+) +- **Compatibilité ESP32** : ESP32 Wrover, ESP32-C3 (Seeed XIAO) +- **GPIOs configurables** : 4 par défaut (extensible) +- **Connexions simultanées** : Jusqu'à 10 modules ESP32 +- **Fréquence de mise à jour** : 100ms par défaut +- **Portée Bluetooth** : ~10 mètres en intérieur +- **Navigateurs supportés** : Chrome 56+, Edge 79+, Opera 43+ +- **Serveurs fournis** : Python 3 (SSL auto-signé) et Node.js + +## 🎯 Notes d'utilisation + +- **Modules multiples** : Chaque module doit avoir un nom unique configuré dans `src/main.cpp` +- **Sécurité BLE** : Le code utilise un mode sans bonding (pas de mémorisation d'appairage) +- **Web Bluetooth** : La page HTML doit obligatoirement être servie en HTTPS ou via localhost +- **Détection de changement** : Les événements GPIO sont envoyés instantanément lors des transitions HIGH→LOW +- **Mode Pull-up** : Les boutons doivent connecter le GPIO à GND (pas à VCC) + +## 🚀 Démarrage rapide (Linux) -## 📝 Notes +```bash +# 1. Compiler et téléverser le code ESP32 +pio run -e esp32dev --target upload -- Plusieurs modules peuvent être connectés simultanément -- Chaque module doit avoir un nom unique -- La page HTML doit être servie en HTTPS ou localhost pour Web Bluetooth -- Les changements d'état sont détectés et envoyés automatiquement +# 2. Lancer l'application (serveur + navigateur) +./start.sh + +# 3. Dans l'interface web : +# - Charger un fichier de quiz +# - Connecter les modules ESP32 +# - Commencer le quiz ! +``` ## 🔐 Sécurité -Pour un usage en production, considérez : -- Ajouter une authentification Bluetooth -- Chiffrer les données transmises -- Implémenter une validation côté serveur +Le projet est conçu pour un usage éducatif et de démonstration. Pour un usage en production : + +- **Authentification BLE** : Implémenter un système de pairing sécurisé +- **Chiffrement des données** : Activer le chiffrement des caractéristiques BLE +- **Certificat SSL valide** : Remplacer le certificat auto-signé par un certificat CA +- **Validation côté serveur** : Ajouter une validation des réponses côté serveur +- **Limitation de connexions** : Implémenter une limite et un contrôle d'accès +- **Logs d'audit** : Enregistrer les actions pour le suivi et la sécurité + +## 📚 Ressources + +- [Web Bluetooth API Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API) +- [ESP32 BLE Arduino Documentation](https://github.com/espressif/arduino-esp32/tree/master/libraries/BLE) +- [PlatformIO Documentation](https://docs.platformio.org/) +- [ESP32 GPIO Reference](https://randomnerdtutorials.com/esp32-pinout-reference-gpios/) + +## 📄 Licence + +Ce projet est open source. Libre d'utilisation, modification et distribution. + +## 👥 Contribution + +Les contributions sont les bienvenues ! N'hésitez pas à : +- Signaler des bugs +- Proposer de nouvelles fonctionnalités +- Améliorer la documentation +- Soumettre des pull requests + +--- + +**Créé avec ❤️ pour l'éducation et l'apprentissage interactif** diff --git a/index.html b/index.html index 476d75d..d6f594a 100644 --- a/index.html +++ b/index.html @@ -461,6 +461,17 @@ .notification.hiding { animation: slideOut 0.3s ease-in forwards; } + + /* Styles pour indices et exposants */ + sub { + font-size: 0.75em; + vertical-align: sub; + } + + sup { + font-size: 0.75em; + vertical-align: super; + }
@@ -540,6 +551,15 @@ const correctScoreInput = document.getElementById('correctScore'); const incorrectScoreInput = document.getElementById('incorrectScore'); + // Fonction pour convertir les indices et exposants + function formatText(text) { + // Remplacer _(contenu) par contenu + text = text.replace(/_\(([^)]+)\)/g, '$1'); + // Remplacer ^(contenu) par contenu + text = text.replace(/\^\(([^)]+)\)/g, '$1'); + return text; + } + // Fonction pour afficher une notification function showNotification(message, type = 'info', duration = 5000) { const notification = document.createElement('div'); @@ -698,16 +718,16 @@ console.log('📊 GPIOs pour', moduleName, ':', data.gpios); - // Détecter la réponse (A=GPIO15, B=GPIO4, C=GPIO5, D=GPIO18) + // Détecter la réponse (A=GPIO2, B=GPIO4, C=GPIO5, D=GPIO6) // Réponse détectée si GPIO est à l'état BAS (1) let answer = null; data.gpios.forEach(gpio => { console.log(` GPIO ${gpio.pin} = ${gpio.state} (type: ${typeof gpio.state})`); if (String(gpio.state) === '1') { - if (gpio.pin === 15) answer = 'A'; + if (gpio.pin === 2) answer = 'A'; else if (gpio.pin === 4) answer = 'B'; else if (gpio.pin === 5) answer = 'C'; - else if (gpio.pin === 18) answer = 'D'; + else if (gpio.pin === 6) answer = 'D'; } }); @@ -946,7 +966,7 @@ // Afficher la question document.querySelector('.question-number').textContent = `Question ${currentQuestionIndex + 1}/${questions.length}`; - document.querySelector('.question-text').textContent = question.question; + document.querySelector('.question-text').innerHTML = formatText(question.question); // Afficher les réponses const answersContainer = document.getElementById('answersContainer'); @@ -960,7 +980,7 @@ answerDiv.innerHTML = `