// // ######################### // # DETECTION DES SEISMES # // ######################### // # Guy Magli 09.12.2019 # // # 12.02.2019 # // ######################### // # Conception, cablages # // # mises a jour, # // # contact... # // # www.magli.fr # // ######################### // // Afin d'eviter les problemes d'affichage et d'impression les signes diacritiques // ont ete retires des commentaires et des chaines de caracteres. // // ! ======================== ! // ! LIBRAIRIES ET PARAMETRES ! // ! ======================== ! // #include #include #include #include // Pour le reboot. #include // Pour utilisation de l'horloge RTC. #include // Pour l'eeprom. // // ! ================================================= ! // ! VARIABLES GLOBALES, CONSTANTES ET INITIALISATIONS ! // ! ================================================= ! // // : -------------------- : // : Le bouclier Internet : // : -------------------- : // // Adresse Mac du bouclier. // Cette adresse figure sur le bouclier Internet. // Elle peut etre modifiee. // Elle doit etre modifiee si vous avez deja une carte reseau avec la meme adresse MAC. // Par exemple { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE }; puis { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF }; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEA }; // Attention : l'adresse doit etre libre (voir IPSCAN ci-dessous) // Adresse IP du bouclier. IPAddress ip(192, 168, 1, 35); // Definie (libre) grace a IPSCAN. Voir la page ci-dessous // www.advanced-ip-scanner.com/fr int iPortBox = 25; // Pour l'envoi des courriels. int iPort = 10350; // Pour la lecture des informations depuis une page Web. // Choisir un port disponible (< 65535) // J'ai pris les deux derniers nombres de l'IP (1 et 35) // multiplies par 10 (10 et 350) EthernetServer server(iPort); char cServerEnvoi[] = "smtp.bbox.fr"; // A changer selon votre box. Voir la page ci-dessous. EthernetClient cClientEnvoi; // Pour l'envoi des mails. // // Pour les connecteurs de la carte. // int iBuzzer = 22; // Alarme sonore. int iDetecteur = 23; // Branchement sur le coupe-circuit du detecteur de seismes. RTC_DS1307 RTC; // Constante pour le module horloge int iTentativesConnexion = 0; // Pour le test de la connexion Internet. int iTentativesLecture = 0; // Id. String cDestinataire = ""; // Pour l'envoi des courriels. String cPrenom = ""; // Id. // Pour les calculs sur les dates et les heures. DateTime now; unsigned long iHeures = 0; // Nombre d'heures. unsigned long iMinutes = 0; // Idem pour les minutes. unsigned long iSecondes = 0; // Idem pour les secondes. unsigned long iJours = 0; // La date. unsigned long iMois = 0; // Le mois. unsigned long iAnnees = 0; // L'annee. // // Divers // int t, g; // Pour les boucles // // ! ===== ! // ! SETUP ! // ! ===== ! // void setup() { Wire.begin(); RTC.begin(); // // Pour la communication via la console. // Serial.begin(9600); Serial.println(" "); Serial.println("BOITIER DE DETECTION DES SEISMES "); Serial.println(" "); // // Pour le buzzer // Serial.print("Test du buzzer sur le connecteur "); Serial.println(iBuzzer); Serial.println(" "); pinMode(iBuzzer, OUTPUT); for (g = 0; g < 2; g++) { for (t = 0; t < 20; t++) { digitalWrite(iBuzzer, HIGH); delay(10); digitalWrite(iBuzzer, LOW); delay(10); } delay(100); } Serial.println(" "); // // Debut de la connexion Internet. // Serial.println("Initialisation de la connexion Internet."); Serial.println(" "); Ethernet.begin(mac); // // Delai d'initialisation du bouclier. // delay(3000); // // Lecture des informations de l'EEPROM // // DANGER : Ne mettre qu'une seule fois // EEPROM.write(1, iJours); EEPROM.write(2, iMois); EEPROM.write(3, iAnnees); EEPROM.write(4, iHeures); EEPROM.write(5, iMinutes); EEPROM.write(6, iSecondes); RTC.adjust(DateTime(2020, 2, 12, 06, 45, 24)); // Serial.print("Le dernier seisme a ete enregistre le "); Serial.print(EEPROM.read(1)); Serial.print("."); Serial.print(EEPROM.read(2)); Serial.print("."); Serial.print(EEPROM.read(3)); Serial.print(" a "); Serial.print(EEPROM.read(4)); Serial.print(":"); Serial.print(EEPROM.read(5)); Serial.print(":"); Serial.println(EEPROM.read(6)); Serial.println(" "); // // Affichage de l'heure // litLaDateEtLHeure(); Serial.print("Debut de la surveillance le "); Serial.print(iJours); Serial.print("."); Serial.print(iMois); Serial.print("."); Serial.print(iAnnees); Serial.print(" a "); Serial.print(iHeures); Serial.print(":"); Serial.print(iMinutes); Serial.print(":"); Serial.println(iSecondes); Serial.println(" "); // // Pour la coupure du detecteur de seismes . // pinMode(iDetecteur, INPUT_PULLUP); // Serial.print("Attente du signal sur le connecteur "); Serial.println(iDetecteur); Serial.println(" "); } // // ! ==== ! // ! LOOP ! // ! ==== ! // void loop() { bool bCourrielEnvoye = false; if (digitalRead(iDetecteur) == false) // On vient de couper la ligne, il y a eu un seisme. { litLaDateEtLHeure(); Serial.println("Le detecteur vient de rompre le signal."); Serial.println(" "); Serial.print("Le "); Serial.print(iJours); Serial.print("."); Serial.print(iMois); Serial.print("."); Serial.print(iAnnees); Serial.print(" a "); Serial.print(iHeures); Serial.print(":"); Serial.print(iMinutes); Serial.print(":"); Serial.println(iSecondes); Serial.println(" "); // On enregistre les valeurs dans l'eeprom. Serial.println("Enregistrement de la date et de l'heure."); Serial.println(" "); EEPROM.write(1, iJours); EEPROM.write(2, iMois); EEPROM.write(3, iAnnees); EEPROM.write(4, iHeures); EEPROM.write(5, iMinutes); EEPROM.write(6, iSecondes); // On envoie les courriels d'alerte. if (bCourrielEnvoye == false) // Aucun courriel n'a encore été envoyé { Serial.println("Envoi de deux courriels a Guy et Marite"); Serial.println(" "); //EnvoiCourrielAlerte("maritemagli@gmail.com", "Marite"); EnvoiCourrielAlerte("guymagli@gmail.com", "Guy"); bCourrielEnvoye = true; } Serial.println("Signal sonore durant dix secondes."); // On declenche le buzzer durant dix secondes environ. for (t = 0; t < 1000; t++) { digitalWrite(iBuzzer, HIGH); delay(10); digitalWrite(iBuzzer, LOW); delay(10); } } EthernetClient client = server.available(); if (client) { boolean bLigneVide = true; // La requete se terminera par une ligne blanche. while (client.connected()) { if (client.available()) { char c = client.read(); // Si une ligne est terminee et vide alors on envoie la reponse. if (c == '\n' && bLigneVide) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); client.print("<"); // Balise repere pour le debut (R) de la valeur des coups par minute en Celsius (TC). client.print(EEPROM.read(1)); client.print("."); client.print(EEPROM.read(2)); client.print("."); client.print(EEPROM.read(3)); client.print(" "); client.print(EEPROM.read(4)); client.print(":"); client.print(EEPROM.read(5)); client.print(":"); client.print(EEPROM.read(6)); client.print(">"); // Fin client.println("
"); break; } if (c == '\n') { // Une nouvelle ligne commence. bLigneVide = true; } else if (c != '\r') { // Cette ligne n'est pas vide. bLigneVide = false; } } } // Delai de reception. delay(1); // Fin de la connexion. client.stop(); } } // // ! ========== ! // ! Procedures ! // ! ========== ! // // : ---------------------------- : // : ENVOI D'UN COURRIEL D'ALERTE : // : ---------------------------- : // byte EnvoiCourrielAlerte(String cDestinataire, String cPrenom) { Serial.print("Envoi du courriel d'alerte a "); Serial.print(cPrenom); Serial.println(" pour l'informer du seisme."); String cTexteCourriel = ""; // Le texte du courriel. if (cClientEnvoi.connect(cServerEnvoi, iPortBox) == 1) { Serial.println("-> Connexion Internet correcte."); Serial.println(" "); } else { Serial.println("-> Connexion Internet INCORRECTE pour l'envoi du courriel d'alerte."); Serial.println(" "); return 0; } if (!receptionCaracteres()) return 0; cClientEnvoi.println("EHLO 192.168.1.35"); // Arduino IP if (!receptionCaracteres()) return 0; cClientEnvoi.println("MAIL From: "); if (!receptionCaracteres()) return 0; cClientEnvoi.print("RCPT To: <"); cClientEnvoi.print(cDestinataire); cClientEnvoi.println(">"); if (!receptionCaracteres()) return 0; cClientEnvoi.println("DATA"); if (!receptionCaracteres()) return 0; cClientEnvoi.print("To: <"); cClientEnvoi.print(cDestinataire); cClientEnvoi.println(">"); cClientEnvoi.println("From: [Ne pas repondre] "); cClientEnvoi.print("Subject: ALERTE SEISME (id="); cClientEnvoi.print(millis() / 100); cClientEnvoi.println(")\r\n"); cTexteCourriel = "Attention " + cPrenom + ".\r\n\r\n"; cTexteCourriel.concat("Un seisme vient d'etre detecte."); cTexteCourriel.concat("\r\n\r\n"); now = RTC.now(); cTexteCourriel.concat("Date : "); cTexteCourriel.concat(iJours); cTexteCourriel.concat("."); cTexteCourriel.concat(iMois); cTexteCourriel.concat("."); cTexteCourriel.concat(iAnnees); cTexteCourriel.concat("\r\n"); cTexteCourriel.concat("Heure : "); cTexteCourriel.concat(iHeures); cTexteCourriel.concat(":"); cTexteCourriel.concat(iMinutes); cTexteCourriel.concat(":"); cTexteCourriel.concat(iSecondes); cTexteCourriel.concat("\r\n"); cTexteCourriel.concat("\r\n"); cTexteCourriel.concat("Ce courriel est systematiquement complete d'une alerte sonore dans le bureau.\r\n\r\n"); cTexteCourriel.concat("\r\n"); cTexteCourriel.concat("Il est obligatoire de presser les deux boutons RESET du detecteur et de la carte pour stopper le signal sonore.\r\n\r\n"); cClientEnvoi.println(cTexteCourriel); cClientEnvoi.println("."); if (!receptionCaracteres()) return 0; cClientEnvoi.println("QUIT"); if (!receptionCaracteres()) return 0; cClientEnvoi.stop(); return 1; Serial.println("-> Courriel d'alerte envoye."); Serial.println(" "); } // // : ------------------------ : // : RECEPTION DES CARACTERES : // : ------------------------ : // byte receptionCaracteres() { byte codeDeReponse; byte octet; int compteur = 0; while (!cClientEnvoi.available()) { delay(1); compteur++; // Si on ne recoit rien if (compteur > 10000) { cClientEnvoi.stop(); return 0; } } codeDeReponse = cClientEnvoi.peek(); while (cClientEnvoi.available()) { octet = cClientEnvoi.read(); } if (codeDeReponse >= '4') { abandon(); return 0; } return 1; } // // : ------- : // : ABANDON : // : ------- : // void abandon() { byte octet = 0; int compteur = 0; cClientEnvoi.println(F("QUIT")); while (!cClientEnvoi.available()) { delay(1); compteur++; // Si on ne recoit rien if (compteur > 10000) { cClientEnvoi.stop(); return; } } while (cClientEnvoi.available()) { octet = cClientEnvoi.read(); } cClientEnvoi.stop(); } // // : ----------------- : // : Lit le module RTC : // : ----------------- : // void litLaDateEtLHeure() { now = RTC.now(); // On lit l'heure et on extrait iHeures = now.hour(); // l'heure, iMinutes = now.minute(); // les minutes, iSecondes = now.second(); // les secondes, iJours = now.day(); // la date du jour, iMois = now.month(); // le mois, iAnnees = now.year() - 2000; // l'annee. } // // : ------ : // : REBOOT : // : ------ : // void reboot() { wdt_enable(WDTO_15MS); while (1) { } }