// // ######################### // # COMMANDE DES VOLETS # // ######################### // # Guy Magli 05.05.2019 # // # 16.07.2019 # // # 16.08.2019 # // # 04.11.2019 # // # 29.12.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. // // Pour faire face a des plantages interdisant toute manipulation des volets, // (ce qui est tres genant en deplacement), j'ai mis en place deux « protections ». // - des sequences de reboot dans le programme des qu'il semble bloque // - un reboot physique de la carte Arduino avec un programmateur electrique qui coupe // l'alimentation à 00h00, 06h00, 12h00 et 18h00, durant quinze minutes. // En cas de plantage complet du programme, suite a des problemes de connexion Internet, // il est alors relance. // // ! ======================== ! // ! LIBRAIRIES ET PARAMETRES ! // ! ======================== ! // #include // Peripheriques. #include // Connexion Internet. #include // Moteurs. #include // Reboot (en cas de probleme de connexion). // // ! ================================================= ! // ! 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, 0xED }; char cServer[] = "www.nomdedomaine.eu"; EthernetClient client; // // Servo moteurs. // Servo sMoteurSejour; Servo sMoteurBureau; // // Les positions initiales des volets. // String cVoletSejour = "H"; String cVoletBureau = "H"; String cVoletSejourComplet = "HAUT"; String cVoletBureauComplet = "HAUT"; String cAncienVoletSejour = "H"; String cAncienVoletBureau = "H"; // // La ligne qui a ete lue sur le Web. // String cLigne = ""; String cPluriel = ""; // Pour un eventuel accord du nombre. int iCaracteresLus = 0; int iLecture = 0; // Nombre de lecture des lignes sur le Web. int iEcriture = 0; // Nombre d'affichages de la situation (haut ou bas). int iTentatives = 0; // Tentatives d'ecriture sur le client. int iGet = 0; // Octets ecrits. int iHost = 0; // Octets ecrits. // // ! ===== ! // ! SETUP ! // ! ===== ! // void setup() { Serial.begin(9600); Serial.println(" "); Serial.println(": -------------------------------------------------------- :"); Serial.println(": TELECOMMANDE CONNECTEE DES VOLETS DU SEJOUR ET DU BUREAU :"); Serial.println(": -------------------------------------------------------- :"); Serial.println(" "); // // Debut de la connexion Internet. // if (Ethernet.begin(mac) == 0) // Cas d'erreur. { Serial.println("Erreur lors de la connexion Internet."); Serial.println(" "); reboot(); // On relance le systeme en cas de probleme de connexion au setup. } else // Confirmation. { Serial.println("Connexion Internet etablie avec succes."); Serial.println(" "); } // // Delai d'initialisation du bouclier. // delay(3000); // // Initialisation des servo-moteurs. // sMoteurSejour.attach(6); // Broches du moteur de la commande du sejour sMoteurBureau.attach(7); // et de la commande du bureau. // // Initialisation de la communication. // if (client.connect(cServer, 80)) { // // Commande GET de lecture du fichier texte contenant les positions. // iGet = client.println("GET /repertoire/Volets.txt HTTP/1.1"); iHost = client.println("host: nomdedomaine.eu"); client.println(); if (iGet * iHost == 0) // L'ecriture sur le client s'est mal passee. { reboot(); } delay(2000); } } // // ! ==== ! // ! LOOP ! // ! ==== ! // void loop() { // // Si la connexion a ete etablie, // s'il y a des donnees en attente, on les importe et on les memorise. // if (client.available()) { cLigne = ""; // // Commande GET de lecture du fichier texte contenant les positions. // delay(10000); // On ne lit les valeurs que toutes les dix secondes. iGet = client.println("GET /repertoire/Volets.txt HTTP/1.1"); iHost = client.println("host: nomdedomaine.eu"); client.println(); if (iGet * iHost == 0) // L'ecriture sur le client s'est mal passee. { reboot(); } client.println(); cLigne = ""; int iLen = client.available(); while (iLen > 0) // Il y a des donnees en attente. { byte buffer[80]; int t; if (iLen > 80) iLen = 80; client.read(buffer, iLen); for (t = 0; t < 80; t++) { cLigne = cLigne + (char)(buffer[t]); // Stockage. } iLen = client.available(); iLecture++; } Serial.println(cLigne); // // Interprete les donnees. // if (cLigne.indexOf("*HH*") > 0) // Recherche la chaine HH dans les octets lus. { cVoletSejour = "H"; cVoletBureau = "H"; cVoletSejourComplet = "HAUT"; cVoletBureauComplet = "HAUT"; } if (cLigne.indexOf("*HB*") > 0) // Idem pour HB. { cVoletSejour = "H"; cVoletBureau = "B"; cVoletSejourComplet = "HAUT"; cVoletBureauComplet = "BAS"; } if (cLigne.indexOf("*BH*") > 0) // Idem pour BH. { cVoletSejour = "B"; cVoletBureau = "H"; cVoletSejourComplet = "BAS"; cVoletBureauComplet = "HAUT"; } if (cLigne.indexOf("*BB*") > 0) // Idem pour BB. { cVoletSejour = "B"; cVoletBureau = "B"; cVoletSejourComplet = "BAS"; cVoletBureauComplet = "BAS"; } Serial.print("Les donnees sont : SEJOUR "); Serial.print(cVoletSejourComplet); Serial.print(" et BUREAU "); Serial.print(cVoletBureauComplet); Serial.println("."); iEcriture++; if (iEcriture - iLecture > 20) // Il y a un probleme grave de lecture sur Internet. { reboot(); } // // Agit si necessaire. // // SEJOUR // if (cAncienVoletSejour != cVoletSejour) // La position du volet du sejour a change. { cAncienVoletSejour = cVoletSejour; if (cVoletSejour == "H") // Il doit etre leve. { Serial.println("-----> Le volet du sejour est en train d'etre leve."); // // SEJOUR HAUT // // Il faut faire tourner le moteur vers le bouton "haut". for (int position = 93; position <= 105; position++) { sMoteurSejour.write(position); delay(30); } delay(3000); for (int position = 105; position >= 93; position--) { sMoteurSejour.write(position); delay(30); } } else // Il faut faire tourner le moteur vers le bouton "bas". { // // SEJOUR BAS // // Il faut faire tourner le moteur vers le bouton "bas". Serial.println("-----> Le volet du sejour est en train d'etre abaisse."); for (int position = 93; position >= 81; position--) { sMoteurSejour.write(position); delay(30); } delay(3000); for (int position = 81; position <= 93; position++) { sMoteurSejour.write(position); delay(30); } } } delay(5000); // // BUREAU // if (cAncienVoletBureau != cVoletBureau) // La position du volet du bureau a change. { cAncienVoletBureau = cVoletBureau; // // BUREAU HAUT // if (cVoletBureau == "H") { // Il faut faire tourner le moteur vers le bouton "haut". Serial.println("-----> Le volet du bureau est en train d'etre leve."); for (int position = 93; position <= 115; position++) { sMoteurBureau.write(position); delay(30); } delay(3000); for (int position = 115; position >= 93; position--) { sMoteurBureau.write(position); delay(30); } } // // BUREAU BAS // else // Il faut faire tourner le moteur vers le bouton "bas". { delay(3000); Serial.println("-----> Le volet du bureau est en train d'etre abaisse."); for (int position = 93; position >= 41; position--) { sMoteurBureau.write(position); delay(30); } delay(3000); for (int position = 41; position <= 93; position++) { sMoteurBureau.write(position); delay(30); } } } iTentatives = 0; // Une lecture s'est correctement deroulee. } else { iTentatives++; // Trop de tentatives de lecture ont echoue. if (iTentatives == 10000) { reboot(); } } } // // ! ========== ! // ! PROCEDURES ! // ! ========== ! // // : ------ : // : REBOOT : // : ------ : // void reboot() { wdt_enable(WDTO_15MS); while (1) { } }