====== idée cadeau pour jeunes développeurs ====== * Porteur du projet : reso-nance (Laurent) * Date : déc/2019 * Licence : libre ! * Contexte : Noël * Fichiers : {{ :projets:serveurwebsurbatterie:noelquizz.zip | code}} {{tag>noël cadeau esp8266 IoT objet connecté développeur batterie piezo}} ===== Description ===== Cadeau original et intriguant pour développeurs en herbe ou mordus d'objets connectés, ce circuit simple, fun et réutilisable leur permet de s'amuser avant de le transformer en un tout autre projet. Un ESP8266 alimenté sur batterie crée un réseau WIFI et héberge un quizz personnalisable sur un serveur web utilisant bootstrap et jquery. Une fois le quizz complété, une page web affiche le nombre de bonnes réponses. Quand toutes les réponses sont validées, un piezo joue la mélodie de "//we wish you a merry christmas//" et allume la led bleue intégrée. Les questions du quizz peuvent être facilement personnalisées et le destinataire peut réutiliser le circuit en y flashant son propre code pour réaliser toutes sorte d'applications web ou d'objet connecté. {{ :projets:serveurwebsurbatterie:carte.jpg?direct&400 |}} ===== Matériaux ===== Le circuit ne comporte que 5 composants : * un ESP8266 * une batterie lithium 18650 * un shield de charge pour la batterie basé sur le TP5470 * un interrupteur ON/OFF * un piezo Il est facilement réalisé sur une plaque proto en époxy ou bakélite pour plus de durabilité. {{ :projets:serveurwebsurbatterie:noel_schema.png?direct&400 |}} ===== Code ===== Le code est ici réparti en plusieurs fichiers : * le code arduino qui gère le wifi, le serveur web, valide les réponses et joue la mélodie en PWM sur le piezo * le code HTML/JS assure l'affichage graphique et l'interface utilisateur (UI) * les librairies externes ([[https://getbootstrap.com | bootstrap]] et [[https://jquery.com/ | jQuery]]) qui permettent d'obtenir facilement une interface web //responsive// sont stockées sous forme de zip sur le **SPIFFS** ==== Le SPIFFS ==== Les ESP8266 comportent le plus souvent 4Mo de mémoire flash qui peut être répartie en une section réservée au code et une réservée au SPIFFS. Le SPIFFS ou //SPI FileSystem// est une des manières de gérer une partie de la mémoire flash comme s'il s'agissait d'un disque dur rudimentaire contenant plusieurs fichiers. Ces fichiers peuvent alors être téléversés sur l'ESP 8266 à l'aide d'un [[https://github.com/esp8266/arduino-esp8266fs-plugin | plugin pour l'IDE d'arduino]] Lors du téléversement du code depuis l'IDE d'arduino, il est nécessaire de lui indiquer la taille allouée au SPIFFS (ici 1Mo ou plus) : une fois la carte **LOLIN/WEMOS D1** sélectionnée, le sous-menu **outils->flash size** permettra d'allouer de la mémoire au SPIFFS {{ :projets:serveurwebsurbatterie:spiffs.png?direct&400 |}} Une fois le plugin installé et la taille du SPIFFS alloué, il est possible de téléverser les fichiers contenus dans le répertoire **data** à l'intérieur du projet via le menu **outils->sketch data upload** Le téléversement peut échouer si le moniteur série est lancé, pensez à le fermer avant de téléverser. {{ :projets:serveurwebsurbatterie:spiffupload.png?direct&400 |}} ==== Code Arduino==== Pour téléverser le code depuis Arduino, la librairie ESP8266 ainsi que le plugin SPIFFS doivent être préalablement installés. Le code initialise le SPIFFS, indique les routes vers les librairies statiques stockées dans le SPIFFS, crée un réseau WIFI sans mot de passe, stocke et vérifie les bonnes réponses et joue la mélodie sur le piezo via la librairie "notes.h" qui converti chaque note en fréquence en Hz. Il est commenté ligne par ligne (en anglais) ++++ Code ESP8266| /*Copyright 2019 Reso-nance Numérique This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -------------- Pinout -------------- pin 12 (GPIO18) ------> Piezo + (put a 220 Ohm resistor between piezo- and gnd) this sketch needs at least 1M SPIFF (the code uses ~29ko of FLASH and SPIFFS files needs ~197ko) */ #include // manage the softAP functionnality #include // self explanatory #include // for the SPIFFS (SPI file system) #include "pitches.h" // convert human readable musical notes into pitches in hertz #define SERIAL_DEBUG #define BUZZER_PIN D2 IPAddress apIP(10, 0, 0, 1); // Defining a static IP address: local & gateway // Default IP in AP mode is 192.168.4.1 const char *ssid = "JoyeuxNoel"; // const char *password = "joyeuxnoel"; const String goodAnswers[]={"0", "2", "1", "3", "1", "3", "0", "1", "3", "0"}; // in the order of the questions const unsigned int answerCount = 10; // since answers are stored as const Strings, we cannot use the sizeof(goodAnswers)/sizeof(String) trick here int wish_melody[] = { // "we wish you a merry christmas" notes. One is off, to be corrected... NOTE_B3, // theses notes will be converted to pitch in Hz by the pitches.h library NOTE_F4, NOTE_F4, NOTE_G4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_A4, NOTE_A4, NOTE_B4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_B3, NOTE_B3, NOTE_D4, NOTE_G4, NOTE_E4, NOTE_F4 }; int wish_tempo[] = {// relative note durations defining the rythme of the melody 4, 4, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 8, 8, 4, 4, 4, 2 }; ESP8266WebServer server(80); #ifdef SERIAL_DEBUG // I defined theses two functions to avoid using "#ifdef... #endif" each time #define debugPrint(x) Serial.print (x) #define debugPrintln(x) Serial.println (x) #else #define debugPrint(x) #define debugPrintln(x) #endif void handleNotFound() {// 404 manager, no fancy html here, just plain text sent by the server String message = "File Not Found\n\n"; message += "URI: "; message += server.uri();// the unreacheable address message += "\nMethod: "; message += ( server.method() == HTTP_GET ) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for ( uint8_t i = 0; i < server.args(); i++ ) { message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n"; } server.send ( 404, "text/plain", message ); } void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); pinMode(BUZZER_PIN, OUTPUT); pinMode(BUZZER_PIN, LOW); #ifdef SERIAL_DEBUG Serial.begin(115200); #endif debugPrintln(); debugPrintln("Configuring access point..."); //set-up the custom IP address WiFi.mode(WIFI_AP_STA); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); // subnet FF FF FF 00 or 255.255.255.0 WiFi.softAP(ssid); // WiFi.softAP(ssid, password); // we can add a password if needed WiFi.hostname("quizz"); // on mac and linux clients, you may reach it by http://hostname.local IPAddress myIP = WiFi.softAPIP(); debugPrint("AP IP address: "); debugPrintln(myIP); SPIFFS.begin(); // initiate the SPI filesystem // server routes, much like PhP, each URL is linked to a function server.onNotFound ( handleNotFound ); server.on("/", fileindex); server.on("/index.html", fileindex); server.on("/bootstrap.min.css", bootstrapCSS); server.on("bootstrap.min.css", bootstrapCSS); server.on("/popper.min.js", popper); server.on("/bootstrap.min.js", bootstrapJS); server.on("bootstrap.min.js", bootstrapJS); server.on("jquery-3.3.1.min", jquery); server.on("/jquery-3.3.1.min", jquery); server.on("/bootstrap-theme.min.css", bootstrapThemeCSS); server.on("bootstrap-theme.min.css", bootstrapThemeCSS); server.on("/favicon.ico", favicon); server.on("/verify", validateAnswers); server.begin(); debugPrintln("HTTP server started"); } void loop() { server.handleClient();// shortest loop ever, aren't libraries a wonderful thing ? } void validateAnswers(){ // this function is called when the user click on the validate button on the UI String questionsID[answerCount];// this array will contain the questions ID as Strings (ie : {"1", "2"...}) unsigned int validatedAnswers = 0;// this will increment each time an answer is counted as valid for (unsigned int i=0; i ++++ ==== HTML/JS ==== Pour plus de flexibilité, le quizz est stocké dans un tableau javascript sous la forme d'un objet par question : [{question:"texte de la première question", answer:["réponse une", "réponse deux"]}, {question:"texte de la seconde question", answer:["réponse une", "réponse deux"]}, ...] Le code HTML est généré dynamiquement pour créer une div de la classe **well** dans un [[https://www.w3schools.com/bootstrap/bootstrap_jumbotron_header.asp | jumbotron]] dans laquelle chaque réponse est représentée par un bouton radio. Un tableau est mis à jour avec chaque bouton radio coché pour chaque question dès que l'utilisateur choisit une réponse. Ce tableau est envoyé sous forme de requête POST contenant toutes les réponses (///verify?1=0&2=1&3=0...//) au serveur qui répond en **JSON** le nombre de réponses correctes et le nombre de questions totales. L'interface web affiche alors un message indiquant ces statistiques. Si toutes les réponses sont validées, un message de félicitations est lu et le piezo joue alors la mélodie deux fois. Les codes HTML et JS étant très courts, ils sont rassemblés dans un seul et même fichier (commenté en anglais) : ++++ Code HTML et JS| Joyeux Noël !

sauras-tu répondre correctement à toutes ces questions ?

++++