// --- Programme Arduino --- // Copyright finizi - Créé le 14/07/2012 // www.DomoEnergyTICs.com // Code sous licence GNU GPL : // 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 3 of the License, // or 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, see . // /* ****************************************************************************************************************************************************** ** ** Utilisation des broches ** ** Analogiques ** 4 : => Solar Relai pompe de circulation ** ** Digitales ** 3 : => bus OneWire ** ****************************************************************************************************************************************************** */ /* ****************************************************************************************************************************************************** ** ** Début du code ** . Includes ** . Defines ** . Variables globales ** . Objets ** ****************************************************************************************************************************************************** */ #include // Pour le WatchDog #include // Pour les capteurs de température /* ** Déclaration des constantes et des paramètres */ #define paramLongSun 600000 // en millisecondes : Durée de fonctionnement à partir de laquelle on considère que le fonctionnement est établi depuis longtemps (600000 = 10 minutes) #define paramDeltaTempStart 8.0 // en degrés : Ecart de température nécessaire pour la mise en route de la pompe #define paramDeltaTempStop 4.0 // en degrés : Ecart de température minimum pour le fonctionnement de la pompe #define etatInconnu 0 // L'état est inconnu. C'est la valeur par défaut. C'est donc l'état au démarrage #define etatArret 4 // Le circuit est plein, prêt à fonctionner. La pompe est à l'arrêt #define etatSoleil 5 // La pompe fonctionne et le soleil chauffe les panneaux #define etatLongSoleil 6 // La pompe fonctionne et le soleil chauffe les panneaux depuis plus de paramLongSoleil #define etatManuOff 8 // Toute l'installation est mise à l'arrêt #define etatManuPump 9 // La pompe de circulation est en marche forcée #define onewireModeLecture 0xBE // Code pour initier la lecture des capteurs OneWire #define onewireModeMesure 0x44 // Code pour déclencher la lecture des capteurs OneWire #define onewireNb 2 // Nombre de capteurs OneWire gérés const int pinOneWire = 3; // Broche utilisée pour lire les températures disponibles via des composant One-Wire DS18B20 const int pinRelayPump = A4; // Commande du relai de pompe de circulation #define relayOn 0 #define relayOff 255 /* ** Déclaration des variables et initialisations */ int etat = etatInconnu; int lastEtat = etatInconnu; float tempPanel = -99.9; float tempBottom = -99.0; // Adresses matérielles des capteurs One-Wire <== Là, il faut mettre les adresses des capteurs réellement utilisés static byte onewireSensorSerial[onewireNb][8] = { { 0x28, 0x55, 0x63, 0x02, 0x04, 0x00, 0x00, 0x06 }, // Température à l'intérieur des panneaux solaires { 0x28, 0x55, 0x75, 0x02, 0x04, 0x00, 0x00, 0x40 }, // Bas du ballon d'eau chaude }; // Chaines d'état à afficher (certaines seront utilisées plus tard) const String etatsText[10] = { "Inconnu", // #define etatInconnu 0 "Vide", // #define etatVide 1 "Remplissage", // #define etatRemplissage 2 "Vidange", // #define etatVidange 3 "Arret", // #define etatArret 4 "Soleil", // #define etatSoleil 5 "SoleilLong", // #define etatLongSoleil 6 "ClosingValve", // #define etatClosingValve 7 "ManuOff", // #define etatManuOff 8 "ManuPompe" // #define etatManuPump 9 }; const float temperatureMini = -40.0; // Température en dessous de la quelle elle n'est pas prise en compte const unsigned long temperatureReadInterval = 10L * 1000L; // Temps entre 2 lectures de température unsigned long pumpStartTime = 0; // Temps écoulé, en millisecondes, depuis le démarrage de la pompe de circulation unsigned long temperatureTime = 0; // Temps écoulé, en millisecondes, depuis la dernière lecture des températures /* ** Création des objets */ OneWire oneWire(pinOneWire); // On défini la broche utilisée pour OneWire /* ****************************************************************************************************************************************************** ** ** setup ==> Fonction obligatoire d'initialisation ** ****************************************************************************************************************************************************** */ void setup() { // Initialisation du WatchDog. Se déclenche au bout de 8 secondes d'inactivité wdt_enable(WDTO_8S); // Initialiser les broches pour que le relai soit inactif au démarrage analogWrite(pinRelayPump, relayOff); // Initialiser les autres broches comme broche de commande pinMode(pinRelayPump, OUTPUT); // Ouvrir tous les relais (ne plus rien alimenter) stopPump(); // Effectue une première mesure pour alimenter les capteurs de température for (int i = 0; i <= onewireNb; i++) { onewireMesureTemp(onewireSensorSerial[i]); } delay(2000); for (int i = 0; i <= onewireNb; i++){ onewireMesureTemp(onewireSensorSerial[i]); } delay(1000); etat = etatInconnu; lastEtat = etatInconnu; } /* ****************************************************************************************************************************************************** ** ** loop ==> Fonction obligatoire. Boucle infinie de fonctionnement ** ****************************************************************************************************************************************************** */ void loop() { // Reset du watchDog : C'est reparti pour 8 secondes wdt_reset(); /************************************************************* ** ** Lecture de tous les capteurs */ boolean temperatureRead = 0; if ( (temperatureTime == 0) || ( (millis() - temperatureTime > temperatureReadInterval) && (millis() >= temperatureTime) ) ) { temperatureTime = millis(); /// Lecture des températures tempPanel = onewireMesureTemp(onewireSensorSerial[0]); tempBottom = onewireMesureTemp(onewireSensorSerial[4]); temperatureRead = true; } /************************************************************* ** ** Actions à mener en fonction des mesures effectuées et de l'état en cours */ switch(etat) { case etatManuOff: // ==> L'installation a été mise à l'arrêt manuellement // Ne rien faire et laisser ainsi break; case etatManuPump: // ==> La pompe est en marche forcée (mise en marche manuelle) // Ne rien faire et laisser ainsi break; case etatArret: // ==> la pompe est à l'arrêt // Vérifier si les condition de mise en route sont remplies if (tempPanel >= tempBottom + paramDeltaTempStart) { startPump(); } break; case etatSoleil: // ==> La pome de circulation est en route de façon NON prolongée // Vérifier si la pompe doit être arrêtée if (tempPanel <= tempBottom + paramDeltaTempStop) { stopPump(); etat = etatArret; } // Vérifier si le régime de croisière est atteint if ( (millis() - pumpStartTime > paramLongSun) && (millis() >= pumpStartTime) ) { pumpStartTime = 0; etat = etatLongSoleil; } break; case etatLongSoleil: // ==> La pome de circulation est en route de façon prolongée et est donc en régime de croisière // Vérifier si l'écart de température entre les panneaux et le bas du ballon d'eau chaude est suffisante if (tempPanel <= tempBottom + paramDeltaTempStop) { stopPump(); etat = etatArret; } break; case etatInconnu: // ==> Survient normalement au démarrage stopPump(); etat = etatArret; break; } // Enregistrer l'état pour la boucle suivante lastEtat = etat; // Attendre un peu avant de boucler (une demi seconde) delay(500); } /* ****************************************************************************************************************************************************** ** ** Fonctions diverses ** ****************************************************************************************************************************************************** */ /* ** Fonction pour arrêter la pompe de circulation. L'installation devient alors à l'arrêt */ void stopPump() { analogWrite(pinRelayPump, relayOff); pumpStartTime = 0; etat = etatArret; } /* ** Fonction pour démarrer la pompe de circulation. L'installation devient alors en fonctionnement */ boolean startPump() { analogWrite(pinRelayPump, relayOn); pumpStartTime = millis(); etat = etatSoleil; return(true); } /* ** Fonction pour lire une température sur le capteur dont l'adresse est en paramètre */ float onewireMesureTemp(byte addr[8]) { byte data[12]; // Tableau de 12 octets pour lecture des 9 registres de RAM et des 3 registres d'EEPROM du capteur One Wire int tempet = 0; // variable pour resultat brute de la mesure float tempetf = 0.0; // variable pour resultat à virgule de la mesure oneWire.reset(); oneWire.select(addr); oneWire.write(onewireModeMesure, 1); // oneWire.reset(); oneWire.select(addr); oneWire.write(onewireModeLecture); // Récupération des valeurs de la RAM du capteur // Lire les 9 octets de la RAM (appelé Scratchpad) for ( int i = 0; i < 9; i++) { // 9 octets de RAM stockés dans 9 octets data[i] = oneWire.read(); // lecture de l'octet de rang i stocké dans tableau data } tempetf = ((data[1] << 8) | data[0]) * 0.0625; return (tempetf); }