// import des librairies
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h> // Pour faire un serveur web
#include <ESP8266mDNS.h> // Pour le DNS du serveur web
#include <ESP8266HTTPUpdateServer.h> // Pour la mettre à jour le programme par le réseau
#include <TimeLib.h>
#include <Wire.h> // Pour communiquer avec l'écran par l I2C
#include <NtpClientLib.h> // https://github.com/gmag11/NtpClient Pour avoir la date et l'heure
#include <Ephemeris.h> // https://github.com/MarScaper/ephemeris Pour calculer l'heure du lever et coucher du soleil en fonction de sa position géographique
#include <LiquidCrystal_I2C.h> // https://github.com/johnrickman/LiquidCrystal_I2C Pour utiliser l'écran LCD I2C
#include "DHT.h" // https://github.com/adafruit/DHT-sensor-library Pour lire les sondes DHT
//*****************************************************************************************************\\
//****************** Partie à modifier avec vos paramètres ******************************************\\
//*****************************************************************************************************\\
const char* ssid = "XXXXX"; // Le noms de votre réseau wifi
const char* password = "YYYYY"; // La clé de votre réseau wifi
const char* serveur = "OOOOO"; // L'adresse IP de votre serveur web (NAS, Raspberry pi ou hébergeur)
const char* host = "terranodemcu"; // le noms qui remplace l'IP pour la fonction update
const char* update_path = "/update"; // le chemin pour le fichier d' update
const char* update_username = "xxxxx"; // On défini ici le login pour la fonction update
const char* update_password = "yyyyy"; // On défini ici le mot de passe pour la fonction update
char* ville = "Varage"; // On donne le noms de sa position géographique
float lat = 43.605201; // On donne sa latitude (https://www.coordonnees-gps.fr/)
float lon = 5.955421; // On donne sa longitude
char* serveurNTP = "fr.pool.ntp.org"; // Le serveur NTP que l'on va interrogé
const byte timeZone = 1; // GMT +1 (paris)
const long interval = 10000; // interval des relevés (pour la fonction millis)
unsigned int targetJour = 28; // la température désiré le jour
unsigned int targetNuit = 23; // la température désiré la nuit
// pour la fontion événement les prenoms, dates anniversaires et heure d'avertissement
const char* noms[] = {"manu", "sosso", "yohan", "clara"};
int dateanniv[] = {2612, 1008, 2806, 2206};
int heureanniv[] = {730, 800, 1600, 1630, 1930, 2000};
// jour et heure d'avertissement du repas des serpents
int daterepas[] = {1, 8, 16, 24};
int heurerepas[] = {830, 2030};
// les GPIO utilisé :
// pour la com I2C
const byte Sda = 2; // D4
const byte Scl = 4; // D2
// défini le capteur DHT22
const char DHTTYPE = DHT22; // DHT11, DHT21 ou DHT22
// Pins des sondes
const byte DHTPINPC = 14; // D5
const byte DHTPINPF = 0; // D3
// Pins des relais
const byte lum = 16; // D0
const byte chauff = 5; // D1
// On défini le bouton
const byte buttonPin = 12; // D6
// Détecteur de sécheresse
const byte PinHumi = 13; // D7
byte secheresse;
// Le buzzer
const byte buzzerPin = 15; // D8
// Les LEDs
const byte ledPin1 = 1; // D9
const byte ledPin2 = 3; // D10
//*****************************************************************************************************\\
//*****************************************************************************************************\\
// les notes de musique
#define NOTE_B0 31
#define NOTE_C1 33
#define NOTE_CS1 35
#define NOTE_D1 37
#define NOTE_DS1 39
#define NOTE_E1 41
#define NOTE_F1 44
#define NOTE_FS1 46
#define NOTE_G1 49
#define NOTE_GS1 52
#define NOTE_A1 55
#define NOTE_AS1 58
#define NOTE_B1 62
#define NOTE_C2 65
#define NOTE_CS2 69
#define NOTE_D2 73
#define NOTE_DS2 78
#define NOTE_E2 82
#define NOTE_F2 87
#define NOTE_FS2 93
#define NOTE_G2 98
#define NOTE_GS2 104
#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS 455
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GSH 830
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978
// TIMEOUT de la connexion NTP
#define NTP_TIMEOUT 1500
// On défini le serveur web pour l' update
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
// On définie l'écran avec son adresse 0x27 pour le mien
LiquidCrystal_I2C lcd(0x27, 16, 2);
byte UTCOffset; // Offset pour prendre en ompte l'heure d'été pour le calcule du levé et couché du soleil
bool wifiFirstConnected, syncEventTriggered, ledState, flag_killer = false; // les flags dont on a besoin a l'état false
NTPSyncEvent_t ntpEvent; // pour stocker le retour des événements déclenché
unsigned long previousMillis = 0; // variable de temps pour la fonction millis
unsigned int Hnow, Hmatin, Hsoir, Hjour, Mjour, Hnuit, Mnuit; // les variables de temps pour nos calculs
// On défini les sondes
DHT dhtPC(DHTPINPC, DHTTYPE);
DHT dhtPF(DHTPINPF, DHTTYPE);
// On défini les variables pours les datas des sondes
float tC,hC,tF,hF;
// On définie les variables où seront stockées les caractères perso
const byte HEAD = 1;
const byte TAIL = 2;
const byte CLEAR = 3;
const byte SKULL = 4;
const byte BONES = 5;
const byte ACCENT = 6;
const byte COEUR = 7;
const byte REPAS = 8;
// Le dessin des caractères HEAD TAIL CLEAR (https://maxpromer.github.io/LCD-Character-Creator/)
uint8_t snakeHead[8] = {0x11, 0xa, 0x1f, 0x15, 0xa, 0x11, 0xe};
uint8_t snakeTail[8] = {0x4, 0xe, 0x1b, 0x1b, 0xe, 0xe, 0x4};
uint8_t noSnake[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
uint8_t tete[8] = {0x0, 0x0, 0x0, 0x1F, 0x15, 0x1F, 0x11, 0x1F};
uint8_t os[8] = {0x11, 0x0E, 0x0E, 0x11, 0x0, 0x0, 0x0, 0x0};
uint8_t eAigu[8] = {0x01, 0x02, 0x0, 0x0E, 0x11, 0x1F, 0x10, 0x0F};
uint8_t heart[8] = {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0};
uint8_t bell[8] = {0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4};
// Compteur de la fonction "sec" et "beep"
unsigned int alarm, compteur = 0;
// On déclare les variables temps pour gérer la boucle des événements
unsigned long tempsanniv, tempsrepas;
// fonction de connexion
void onSTAGotIP (WiFiEventStationModeGotIP ipInfo) { // lorsque l'on a une IP
wifiFirstConnected = true; // on active le flag de première connexion
}
// fonction de deconnexion
void onSTADisconnected (WiFiEventStationModeDisconnected event_info) { // si on est déconnecté
NTP.stop(); // on stop la synchro au serveur NTP
WiFi.reconnect (); // on lance la reconnexion au wifi
}
// fonction de traitement des event avec le serveur NTP
void processSyncEvent (NTPSyncEvent_t ntpEvent) {
if (ntpEvent == timeSyncd) { // si le serveur NTP nous repond correctement
NTP.getTimeDateString (NTP.getLastNTPSync ()); // on synchronise l'heure
if (NTP.isSummerTime ()) { // si c'est l'heure d'été
UTCOffset = 2; // l'ofset vaut 2
} else {
UTCOffset = 1; // l'ofset vaut 1
}
// on calcule le vevé et couché
printRiseAndSet(ville, lat, lon, UTCOffset, day(),month(),year());
// on met le flag des chansons et événements à false au cas ou il a été activé
flag_killer = false;
}
}
// fonction pour mettre 0 devant les nombres de 0 a 9, pour être sur 2 chiffres.
void printDigits(int digits){
if(digits < 10) {
lcd.print('0');
}
lcd.print(digits);
}
// fonction qui affiche l'heure
void digitalClockDisplay(){
printDigits(hour());
lcd.print(":");
printDigits(minute());
lcd.print(":");
printDigits(second());
}
// fonction qui affiche la date
void digitalDateDisplay(){
printDigits(day());
lcd.print("/");
printDigits(month());
lcd.print("/");
printDigits(year());
}
// la fonction qui calcul le lever et coucher du soleil en fonction de sa position et de la date
void printRiseAndSet(char *city, FLOAT latitude, FLOAT longitude, int UTCOffset, int day, int month, int year) {
Ephemeris::setLocationOnEarth(latitude,longitude); // definie notre location
SolarSystemObject sun = Ephemeris::solarSystemObjectAtDateAndTime(Sun,day,month,year,0,0,0); // pour avoir le levé et couché du soleil
if( sun.riseAndSetState == RiseAndSetOk ) { // si notre location est correcte
int hours,minutes;
FLOAT seconds;
Ephemeris::floatingHoursToHoursMinutesSeconds(Ephemeris::floatingHoursWithUTCOffset(sun.rise,UTCOffset), &hours, &minutes, &seconds); // on réupère l'heure du levé
Hjour = hours;
Mjour = minutes;
Hmatin = hours * 100 + minutes; // mise en forme pour les calculs (8:00 devient 800)
Ephemeris::floatingHoursToHoursMinutesSeconds(Ephemeris::floatingHoursWithUTCOffset(sun.set,UTCOffset), &hours, &minutes, &seconds); // on réupère l'heure du couché
Hnuit = hours;
Mnuit = minutes;
Hsoir = hours * 100 + minutes; // mise en forme pour les calculs
}
}
// La fonction qui s'occupe du chauffage et de la lumière
void terrarium() {
byte target;
// Pour faciliter les calcul (21h03 devient 2103)
Hnow = hour() * 100 + minute(); // Heure actuelle
if ( Hnow > Hmatin && Hnow < Hsoir ) { // Si c'est le jour
target = targetJour; // La consigne du chauffage est targetJour
digitalWrite(lum, LOW); // on coupe le relais, ce qui alume la lumière
}
else { // Sinon , donc c'est la nuit
target = targetNuit; // La consigne du chauffage est targetNuit
digitalWrite(lum, HIGH); // on active le relais, ce qui coupe la lumière
}
// On lis la sondes point chaud
hC = dhtPC.readHumidity();
tC = dhtPC.readTemperature();
// Lire la sonde point froid
hF = dhtPF.readHumidity();
tF = dhtPF.readTemperature();
// si la temperature au point chaud est supérieur à la target OU si il y a un échèc de leture de la sonde
if (tC > target + 0.25 || isnan(tC)) {
digitalWrite(chauff, HIGH); // on active le relais, ce qui coupe le haffage
}
// si la temperature au point chaud est inférieur à la target
if (tC < target - 0.25) {
digitalWrite(chauff, LOW); // on coupe le relais, ce qui allume le chauffage
}
if ( isnan(tC) || isnan(tF) ) { // si il y a un échèc de leture de la sonde
return; // on quitte la fonction terrarium
}
// si la lecture de la sonde est ok on continue
WiFiClient client; // Création de la connexion TCP
const int httpPort = 80; // constante pour le port 80
if (!client.connect(serveur, httpPort)) { // si on n'arrive pas a se onnecter au serveur distant
return; // on quitte la fonction terrarium
}
// si on la connexion au serveur distant est ok
// on envoi toutes ces datas par l'URL et par GET au fichier sonde.php sur le serveur (dans le dossier terranodemcu)
client.print(String("GET /terranodemcu/sondes.php?tempC=") + String(float (tC)) + "&humiC=" + String(float(hC)) +
"&tempF=" + String(float(tF)) + "&humiF=" + String(float(hF)) + "&Hjour=" + String(int(Hjour)) +
"&Mjour=" + String(int(Mjour)) + "&Hnuit=" + String(int(Hnuit)) + "&Mnuit=" + String(int(Mnuit)) +
" HTTP/1.1\r\n" + "Host: " + serveur + "\r\n" + "Connection: close\r\n\r\n");
client.flush(); // on vide le buffer
}
// La fonction bouton qui lance l'affichage LCD et coupe les chansons ou événement si il est appuyé pendant une chanson.
void bouton() {
int reading = digitalRead(buttonPin); // on lit l'état du bouton
if (reading == 0) { // si on appuye
flag_killer = true; // on passe ce flag à true, il sert à tuer une chanson ou un événement
affichage(); // on lance l'affichage
}
}
// la fontion qui vérifie qu'il y a de l'eau
void sec() {
secheresse = digitalRead(PinHumi); // on lit la valeur du détecteur
if (secheresse) { // si la valeur du détecteur vaut 1 c'est qu'il n'y a plus d'eau
// pour éviter de lancer l'alarme sur une fausse détection
alarm++; // on incrémente le compteur
if (alarm > 2) { // au 3 eme tour de boucle
eau(); // on lance la fonction eau
alarm = 0; // on remet le compteur alarm à 0
}
} else {
alarm = 0; // si la valeur du détecteur vaut 0 alarm vaut 0;
}
}
// la fontion qui affiche qu'il n'y a pas d'eau et lance la chanson Starwars
void eau() {
lcd.backlight();
lcd.setCursor(1,0);
lcd.write(SKULL);
lcd.setCursor(4,0);
lcd.print("Il n'y a");
lcd.setCursor(14,0);
lcd.write(SKULL);
lcd.setCursor(1, 1);
lcd.write(BONES);
lcd.setCursor(3,1);
lcd.print("plus d'eau");
lcd.setCursor(14,1);
lcd.write(BONES);
Hnow = hour() * 100 + minute(); // Heure actuelle
if ( Hnow > 700 && Hnow < 2200 ) { // Si c'est le jour
Starwars(); // On lance l'alarme
} else { // Sinon on me laisse dormir
delay(1500);
}
lcd.clear();
lcd.noBacklight();
}
// le setup
void setup () {
// On déclare les GPIO pour l' I2C (D1 et D2 par défaut)
Wire.begin(Sda,Scl);
// On initialise le LCD
lcd.begin();
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Debut de l '");
lcd.setCursor(1,1);
lcd.print("initialisation");
delay(2000);
static WiFiEventHandler e1, e2; // on déclare 3 event sur le wifi: e1 e2 et e3
e1 = WiFi.onStationModeGotIP (onSTAGotIP); // la fonction de connexion bis est associé a l'evenement Wifi e1
e2 = WiFi.onStationModeDisconnected (onSTADisconnected); // la fonction de déconnexion est associé a l'evenement Wifi e2
WiFi.mode (WIFI_STA); // on definie le mode de Wifi
WiFi.begin (ssid, password); // on demarre la connexion au réseau Wifi
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
}
// on definie notre synchro
NTP.onNTPSyncEvent ([](NTPSyncEvent_t event) { // quand un evenement se produit
ntpEvent = event; // on definie nos event
syncEventTriggered = true; // on passe le flag syncEventTriggered a vrai
});
MDNS.begin(host);
MDNS.addService("http", "tcp", 80);
// On déclare le buzzer en sortie
pinMode(buzzerPin, OUTPUT);
// On déclare les pins des relais en sortie
pinMode(lum, OUTPUT);
pinMode(chauff, OUTPUT);
// On initialise les DHT
dhtPC.begin();
dhtPF.begin();
// On déclare le GPIO du bouton et du détecteur de sécheresse en entrée avec la résistance de PULLUP:
pinMode(buttonPin, INPUT_PULLUP);
pinMode(PinHumi, INPUT_PULLUP);
// les LED , après la déclaration des LED en sortie, on aura plus rien sur le port série
// car elles sont branché sur le TX RX du NodeMCU il faut donc commenté ces 2 lignes pour le débug
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
// Création des caractères perso
lcd.createChar(HEAD, snakeHead);
lcd.createChar(TAIL, snakeTail);
lcd.createChar(CLEAR, noSnake);
lcd.createChar(SKULL, tete);
lcd.createChar(BONES, os);
lcd.createChar(ACCENT, eAigu);
lcd.createChar(COEUR, heart);
lcd.createChar(REPAS, bell);
// on defini la fonction de mise à jour avec nos paramètre (le serveur, le chemin, le login et mdp)
httpUpdater.setup(&httpServer, update_path, update_username, update_password);
// on associe la page handle_Root a la racine du serveur web
httpServer.on("/", handle_root);
// on associe les page chansons a des alias
httpServer.on("/Star", handle_Star);
httpServer.on("/Happy", handle_Happy);
httpServer.on("/Game", handle_Game);
// on démarre le serveur web
httpServer.begin();
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Fin de l' ");
lcd.setCursor(1,1);
lcd.print("initialisation");
delay(2000);
lcd.clear();
lcd.noBacklight();
}
// la boucle
void loop () {
MDNS.update(); // On maintient notre nom d'hote
httpServer.handleClient(); // On l'ance l'écoute sur le serveur
bouton(); // On check le bouton
if (wifiFirstConnected) { // Si le flag de la première connexion est activé
wifiFirstConnected = false; // On le bascule a false
NTP.setInterval (63); // On régle l'interval de synchonisation en seconde
NTP.setNTPTimeout (NTP_TIMEOUT); // On régle le timout de synchonisation
NTP.begin (serveurNTP, timeZone, true); // On démarre la syncho avec le serveur NTP toute les 63s
}
if (syncEventTriggered) { // Si une synchro est efféctuée
processSyncEvent (ntpEvent); // On lance la fonction qui traite le retour de la synchro (erreur ou réussite)
syncEventTriggered = false; // On repasse le flag syncEventTriggered a false
}
unsigned long currentMillis = millis(); // Variable currentMillis vaut millis() ( le temps depuis le debut du programme)
if (currentMillis - previousMillis >= interval) { // Sion dépasse ou atteint l'interval (donc ici toute les 10 secondes)
previousMillis = currentMillis; // On reset notre compteur temps
// on lance nos fonctions
terrarium();
sec();
evenement();
}
}
// intro animation LCD
void intro() {
lcd.setCursor(0,1);
lcd.write(HEAD);
delay(200);
for (int i=0; i<6; i++) {
int j = i+1;
lcd.setCursor(i,1);
lcd.write(TAIL);
lcd.setCursor(j,1);
lcd.write(HEAD);
delay(200);
}
lcd.setCursor(0,1);
lcd.write(CLEAR);
lcd.setCursor(6,1);
lcd.write(TAIL);
lcd.setCursor(7,0);
lcd.write(HEAD);
delay(200);
lcd.setCursor(0,0);
lcd.print("Terra");
for (int i=1; i<7; i++) {
int j = i+6;
int k = j+1;
lcd.setCursor(i,1);
lcd.write(CLEAR);
lcd.setCursor(j,0);
lcd.write(TAIL);
lcd.setCursor(k,0);
lcd.write(HEAD);
delay(200);
}
lcd.setCursor(7,1);
lcd.print("NodeMCU");
for (int i=7; i<9; i++) {
int j = i+6;
int k = j+1;
lcd.setCursor(i,0);
lcd.write(CLEAR);
lcd.setCursor(j,0);
lcd.write(TAIL);
lcd.setCursor(k,0);
lcd.write(HEAD);
delay(200);
}
lcd.setCursor(8,0);
lcd.write(CLEAR);
lcd.setCursor(15,0);
lcd.write(TAIL);
delay(200);
for (int i=9; i<16; i++) {
lcd.setCursor(i,0);
lcd.write(CLEAR);
delay(200);
}
lcd.clear();
}
//sortie animation LCD
void outro () {
lcd.setCursor(2,0);
lcd.print("Bye bye !!!");
lcd.setCursor(1,1);
lcd.print("Terra-NodeMCU");
delay(1500);
lcd.clear();
lcd.noBacklight();
}
// La fonction de l'affichage des datas des sondes en temps réel sur l'écran LCD ********
void affichage() {
// on allume le retro-éclairage
lcd.backlight();
delay(100);
// on lance l'animation d'introduction
intro();
// on lance l'animation
lcd.setCursor(0,0);
lcd.print("Nous sommes le :");
lcd.setCursor(0,1);
digitalDateDisplay();
delay(1500);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Il est :");
lcd.setCursor(0,1);
digitalClockDisplay();
delay(1500);
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Point chaud :");
lcd.setCursor(0,1);
lcd.print("Temp = ");
lcd.print(float (tC));
lcd.print(" ");
lcd.write(223);
lcd.print("C");
delay(1500);
lcd.setCursor(0,1);
lcd.print("Humi = ");
lcd.print(float (hC));
lcd.print(" %");
delay(1500);
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Point froid :");
lcd.setCursor(0,1);
lcd.print("Temp = ");
lcd.print(float (tF));
lcd.print(" ");
lcd.write(223); // caractère spécial du °
lcd.print("C");
delay(1500);
lcd.setCursor(0,1);
lcd.print("Humi = ");
lcd.print(float (hF));
lcd.print(" %");
delay(1500);
lcd.clear();
// on lance l'animation de sortie
outro();
}
// la fonction qui gére les événements
void evenement(){
int Hnow = hour() * 100 + minute();
int DMnow = day() * 100 + month();
int Dnow = day();
if (flag_killer == false) { // si le flag est false
for (int i = 0; i < (sizeof(dateanniv)/sizeof(int)); i++) { // pour chaque date du tableau dateanniv
if (DMnow == dateanniv[i]) { // si elle est égale à la date d'aujourd'hui
for (int j = 0; j < (sizeof(heureanniv)/sizeof(int)); j++) { // a chaque heure du tableau heureanniv on lancera la musique
if (Hnow == heureanniv[j]) {
if((millis() - tempsanniv) > 10000) {
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("happy birthday");
lcd.setCursor(0,1);
lcd.write(COEUR);
lcd.write(COEUR);
lcd.write(COEUR);
lcd.setCursor(5,1);
lcd.print(noms[i]);
lcd.setCursor(13,1);
lcd.write(COEUR);
lcd.write(COEUR);
lcd.write(COEUR);
HappyBirthday();
lcd.clear();
lcd.noBacklight();
tempsanniv = millis();
}
}
}
}
}
for (int i = 0; i < (sizeof(daterepas)/sizeof(int)); i++) { // pour chaque date du tableau daterepas
if (daterepas[i] == Dnow) { // si elle est égale à la date d'aujourd'hui
for (int j = 0; j < (sizeof(heurerepas)/sizeof(int)); j++) { // a chaque heure du tableau heurerepas on lancera la musique
if (Hnow == heurerepas[j]) {
if((millis() - tempsrepas) > 20000) {
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("c'est l'heure");
lcd.setCursor(0,1);
lcd.write(REPAS);
lcd.write(REPAS);
lcd.setCursor(4,1);
lcd.print("du repas");
lcd.setCursor(14,1);
lcd.write(REPAS);
lcd.write(REPAS);
GameOfThrones();
lcd.clear();
lcd.noBacklight();
tempsrepas = millis();
}
}
}
}
}
}
}
// la pages web d'accueil
void handle_root() {
char page[] = "<body style='background:#7F7F7F;'>"
"<center><h2 style='color:#EC7878;'>La fonction Update</h2></center><br/>"
"<center><p><a href=\"update\"><button style='background:#EC7878;border:2px solid black;font-size: 20px;padding: 20px 20px;border-radius: 25px;'>update du programme</button></a></p></center>"
"<center><h2>Commande des chansons</h2></center><br/>"
"<center><div>"
"<p><a href=\"Star\"><button>Starwars</button></a> <a href=\"Happy\"><button>Happy Birthday</button></a> "
"<a href=\"Game\"><button>Game Of Thrones</button></a></p>"
"</center></div>"
"</body>";
httpServer.send(200, "text/html", page); // repond avec la page web codee en HTML
}
// la pages web pour Starwars
void handle_Star() {
char page[] = "<body style='background:#7F7F7F;'>"
"<div style='margin-top:10%;'>"
"<center><h1>Starwars</h1></center><br/>"
"<center><p><a href=\"/\"><button>Home</button></a></p></center>"
"</div></body>";
httpServer.send(200, "text/html", page); // repond avec la page web codee en HTML
Starwars();
}
// la pages web pour Game Of Thrones
void handle_Game() {
char page[] = "<body style='background:#7F7F7F;'>"
"<div style='margin-top:10%;'>"
"<center><h1>Game Of Thrones</h1></center><br/>"
"<center><p><a href=\"/\"><button>Home</button></a></p></center>"
"</div></body>";
httpServer.send(200, "text/html", page); // repond avec la page web codee en HTML
GameOfThrones();
}
// la pages web pour Happy Birthday
void handle_Happy() {
char page[] = "<body style='background:#7F7F7F;'>"
"<div style='margin-top:10%;'>"
"<center><h1>Happy Birthday</h1></center><br/>"
"<center><p><a href=\"/\"><button>Home</button></a></p></center>"
"</div></body>";
httpServer.send(200, "text/html", page); // repond avec la page web codee en HTML
HappyBirthday();
}
// La fonction beep qui joue les notes et allume les leds
void beep(int note, int duree) {
int lecture = digitalRead(buttonPin);
if (lecture == 0) {
flag_killer = true;
}
if (flag_killer == true) {
noTone(buzzerPin);
} else {
tone(buzzerPin, note, duree);
// choix des leds à allumer en fonction de la valeur de 'compteur' et de la durée de la note
if(compteur % 2 == 0)
{
digitalWrite(ledPin1, !ledState);
delay(duree);
digitalWrite(ledPin1, ledState);
}
else
{
digitalWrite(ledPin2, !ledState);
delay(duree);
digitalWrite(ledPin2, ledState);
}
noTone(buzzerPin);
delay(50);
// On increment le compteur
compteur++;
}
}
////////////////////////// Les chansons ////////////////////////
//******* Starwars coté obscure****************
void firstSection()
{
beep(NOTE_A4, 500);
beep(NOTE_A4, 500);
beep(NOTE_A4, 500);
beep(NOTE_F4, 350);
beep(NOTE_C5, 150);
beep(NOTE_A4, 500);
beep(NOTE_F4, 350);
beep(NOTE_C5, 150);
beep(NOTE_A4, 650);
delay(500);
beep(NOTE_E5, 500);
beep(NOTE_E5, 500);
beep(NOTE_E5, 500);
beep(NOTE_F5, 350);
beep(NOTE_C5, 150);
beep(NOTE_GS4, 500);
beep(NOTE_F4, 350);
beep(NOTE_C5, 150);
beep(NOTE_A4, 650);
delay(500);
}
void secondSection()
{
beep(NOTE_A5, 500);
beep(NOTE_A4, 300);
beep(NOTE_A4, 150);
beep(NOTE_A5, 500);
beep(NOTE_GSH, 325);
beep(NOTE_G5, 175);
beep(NOTE_FS5, 125);
beep(NOTE_F5, 125);
beep(NOTE_FS5, 250);
delay(325);
beep(NOTE_AS, 250);
beep(NOTE_DS5, 500);
beep(NOTE_D5, 325);
beep(NOTE_CS5, 175);
beep(NOTE_C5, 125);
beep(NOTE_AS4, 125);
beep(NOTE_C5, 250);
delay(350);
}
void Starwars()
{
firstSection();
secondSection();
//Variant 1
beep(NOTE_F4, 250);
beep(NOTE_GS4, 500);
beep(NOTE_F4, 350);
beep(NOTE_A4, 125);
beep(NOTE_C5, 500);
beep(NOTE_A4, 375);
beep(NOTE_C5, 125);
beep(NOTE_E5, 650);
delay(500);
secondSection();
//Variant 2
beep(NOTE_F4, 250);
beep(NOTE_GS4, 500);
beep(NOTE_F4, 375);
beep(NOTE_C5, 125);
beep(NOTE_A4, 500);
beep(NOTE_F4, 375);
beep(NOTE_C5, 125);
beep(NOTE_A4, 650);
delay(650);
compteur = 0;
}
//******* GameOfThrones ****************
void GameOfThrones()
{
for(int i=0; i<3; i++)
{
beep(NOTE_G4, 500);
beep(NOTE_C4, 500);
beep(NOTE_DS4, 250);
beep(NOTE_F4, 250);
}
for(int i=0; i<3; i++)
{
beep(NOTE_G4, 500);
beep(NOTE_C4, 500);
beep(NOTE_E4, 250);
beep(NOTE_F4, 250);
}
beep(NOTE_G4, 500);
beep(NOTE_C4, 500);
beep(NOTE_DS4, 250);
beep(NOTE_F4, 250);
beep(NOTE_D4, 500);
for(int i=0; i<2; i++)
{
beep(NOTE_G3, 500);
beep(NOTE_AS3, 250);
beep(NOTE_C4, 250);
beep(NOTE_D4, 500);
}//
beep(NOTE_G3, 500);
beep(NOTE_AS3, 250);
beep(NOTE_C4, 250);
beep(NOTE_D4, 1000);
beep(NOTE_F4, 1000);
beep(NOTE_AS3, 1000);
beep(NOTE_DS4, 250);
beep(NOTE_D4, 250);
beep(NOTE_F4, 1000);
beep(NOTE_AS3, 1000);
beep(NOTE_DS4, 250);
beep(NOTE_D4, 250);
beep(NOTE_C4, 500);
for(int i=0; i<2; i++)
{
beep(NOTE_GS3, 250);
beep(NOTE_AS3, 250);
beep(NOTE_C4, 500);
beep(NOTE_F3, 500);
}
beep(NOTE_G4, 1000);
beep(NOTE_C4, 1000);
beep(NOTE_DS4, 250);
beep(NOTE_F4, 250);
beep(NOTE_G4, 1000);
beep(NOTE_C4, 1000);
beep(NOTE_DS4, 250);
beep(NOTE_F4, 250);
beep(NOTE_D4, 500);
for(int i=0; i<3; i++)
{
beep(NOTE_G3, 500);
beep(NOTE_AS3, 250);
beep(NOTE_C4, 250);
beep(NOTE_D4, 500);
}
compteur = 0;
}
//******* Happy Birthday ****************
void HappyBirthday()
{
beep(NOTE_G3, 200);
beep(NOTE_G3, 200);
beep(NOTE_A3, 500);
beep(NOTE_G3, 500);
beep(NOTE_C4, 500);
beep(NOTE_B3, 1000);
beep(NOTE_G3, 200);
beep(NOTE_G3, 200);
beep(NOTE_A3, 500);
beep(NOTE_G3, 500);
beep(NOTE_D4, 500);
beep(NOTE_C4, 1000);
beep(NOTE_G3, 200);
beep(NOTE_G3, 200);
beep(NOTE_G4, 500);
beep(NOTE_E4, 500);
beep(NOTE_C4, 500);
beep(NOTE_B3, 500);
beep(NOTE_A3, 750);
beep(NOTE_F4, 200);
beep(NOTE_F4, 200);
beep(NOTE_E4, 500);
beep(NOTE_C4, 500);
beep(NOTE_D4, 500);
beep(NOTE_C4, 1000);
compteur = 0;
}