Problème de comparaison de température

Bonjour à tous,

Nous avons entrepris depuis quelques années la rénovation d'une vieille bâtisse en pierre coquillère. Celle-ci est agencée principalement autour d'un poêle à bois pour le séjour.
Afin de distribuer les calories exédentaires générées par le poêle vers d'autres pièces éloignées et séparées par des murs de 40cms d'épaisseur, j'ai entrepris de réaliser un système de chauffage central dont la chaleur est prélevée autour du poêle et du conduit d'évacuation.
Ce système est basé sur une régulation à base d'arduino, d'où ma requête :stuck_out_tongue_winking_eye:

Jusqu'à présent cette régulation fait pleinement son travail mais ayant constaté que le relai principal fonctionne pendant des heures après l'arrêt du poêle, j'ai essayé de mettre en place une comparaison de températures sur la sonde du poêle afin de stopper le circulateur lorsque la température est en constante baisse lorsque qu'elle se trouve dans le cas 2.

Je me suis basé une l'enregistrement de la valeur et sa comparaison à intervales régulier mais je rencontre les problèmes suivants :
1- je ne sais absolument pas si l'enregistrement de la valeur dans temperature [2] est effectif puisque celle-ci n'est pas remontée via le moniteur série ;
2- lorsque la partie commentée du cas 2 l'est, la température de la sonde S_RAD affiche bien la valeur (temperature[1]) ;
3- lorsque la partir commentée du cas 2 ne l'est pas pas, la température de la sonde S-RAD affiche -0.06 !!

Ci-dessous le code :

/*###################################################################################################*/
/* Régulation du chauffage central avec poêle à bois basé sur des capteurs DS18B20 */
/*###################################################################################################*/
 
/* Déclaration des librairies pour le bus 1-Wire et l'affichage LCD*/
#include <OneWire.h>
#include <Adafruit_GFX.h>//https://github.com/adafruit/Adafruit-GFX-Library
#include <LiquidCrystal.h>

/* Initialisation des paramètres LCD (entrées arduino)*/
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

/* Variables d'entrées (adresses des capteurs de température) */
/* identifiées grâce que code "Scanner_Identifier_Sonde_avec_OnWire.ino" */
/*const byte S_POELE[] = { 0x28, 0xC2, 0xA5, 0x4E, 0x11, 0x21, 0x01, 0x41 }; S4 - 41 par défaut*/
const byte S_POELE[] = { 0x28, 0xA2, 0xA6, 0x5B, 0x11, 0x21, 0x01, 0x75 }; //S6 pour test
const byte S_RAD[] = { 0x28, 0x7E, 0x3B, 0x66, 0x11, 0x21, 0x01, 0x42 }; // S5 - 42 par défaut

/* Configuration de l'entrée 2 comme INPUT du bus 1-Wire */
const byte DS18B20_PIN = 2;

/* Création de l'objet OneWire pour manipuler le bus 1-Wire */
OneWire ds(DS18B20_PIN);

/* Configuration des codes de retour de la fonction getTemperature() */
enum DS18B20_RCODES {
  READ_OK,          // Lecture ok
  NO_SENSOR_FOUND,  // Pas de capteur
  INVALID_ADDRESS,  // Adresse reçue invalide
  INVALID_SENSOR    // Capteur invalide (pas un DS18B20)
};

/* Variables de sortie (Electrovannes, Circulateurs) */
#define Circ_Poele 3 // Commande du circulateur de la boucle chaudière
#define Circ_Chauffage 4 // Commande du circulateur du circuit de chauffage
#define EV1_sejour 5 // Commande de l'électrovanne 1 (envoi chaleur vers SdB et séjour)
#define EV2_chambre 6 // Commande de l'électrovanne 2 (envoi chaleur vers chambre du fond)

/*Initialisation des paramètres de temps pour la comparaison de température*/
unsigned long lastMeasurementTime = 0; // Dernière mesure de temps (en temps Unix)
unsigned long interval = 300000; // Intervalle de mesure (5 min en millisecondes)

/*initilation des variables de température*/
float temperature[0];


/*--------------------------------------------------------------*/
/* Fonction de lecture de la température via un capteur DS18B20 */
/*--------------------------------------------------------------*/
float getTemperature(const byte addr[]) {
  byte data[9];
  // data[] : Données lues depuis le scratchpad
  // addr[] : Adresse du module 1-Wire détecté
  
  /* Reset le bus 1-Wire et sélectionne le capteur */
  ds.reset();
  ds.select(addr);
  
  /* Lance une prise de mesure de température et attend la fin de la mesure */
  ds.write(0x44, 1);
  delay(800);
  
  /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
  ds.reset();
  ds.select(addr);
  ds.write(0xBE);
 
 /* Lecture du scratchpad */
  for (byte i = 0; i < 9; i++) {
    data[i] = ds.read();
  }
   
 /* Calcul de la température en degré Celsius */
  return (int16_t) ((data[1] << 8) | data[0]) * 0.0625; 
}
 

/*###########*/
/*   SETUP   */
/*###########*/
void setup() {

 //Initialisation USB
 Serial.begin(115200);
 Serial.println(F("Initialize System"));
 delay(2000);

 //Initialisation LCD (colonnes, lignes)
 lcd.begin(16, 2); 

//Initialisation des variables en sortie
  pinMode(Circ_Poele, OUTPUT);
  pinMode(Circ_Chauffage, OUTPUT);
  pinMode(EV1_sejour, OUTPUT);
  pinMode(EV2_chambre, OUTPUT);

  digitalWrite(Circ_Poele, HIGH); // ATTENTION !! Fonctionnement inversé HIGH-LOW du à la carte de relais
  digitalWrite(Circ_Chauffage, HIGH);
  digitalWrite(EV1_sejour, HIGH);
  digitalWrite(EV2_chambre, HIGH);
}

//affichage port série
void AffichageSerie() {
  Serial.print(F("T° sortie poêle : "));
  Serial.print(temperature[0], 2);
  Serial.print("°C | ");
  Serial.print(F("T° retour radiateurs : "));
  Serial.print(temperature[1], 2);
  Serial.println("°C");
  Serial.println(F("---"));
}

//affichage écran LCD
void AffichageLCD() {
  lcd.setCursor(0, 0);
  lcd.print("T° sortie poêle : ");
  lcd.print(temperature[0], 2);
  lcd.print("°C, ");  
  lcd.setCursor(0, 1);
  lcd.print("T° retour radiateurs : ");
  lcd.print(temperature[1], 2);
  lcd.print("°C, ");
}


/*############*/
/*    LOOP    */
/*############*/
void loop() {

/* Lecture des températures des sondes */
  temperature[0] = getTemperature(S_POELE);
  temperature[1] = getTemperature(S_RAD);

/*Si le temps écoulé depuis la dernière mesure dépasse l'intervalle, actualisation du dernier temps de mesure et stockage valeur de S_POELE */
  if (millis() - lastMeasurementTime >= interval) {
    temperature[2] == temperature[0];
    lastMeasurementTime = millis();
  }

/* Cas 1 : S_POELE < 25°c (poêle éteint) */
  if (temperature[0] < 25){
    digitalWrite(Circ_Poele, HIGH);
    digitalWrite(Circ_Chauffage, HIGH);
    digitalWrite(EV1_sejour, HIGH);
    digitalWrite(EV2_chambre, HIGH);
    AffichageSerie();
    AffichageLCD();
  }

/* Cas 2 : 25°c < S_POELE < 35°c */
  else if (temperature[0] > 25 && temperature[0] < 35){
/*  if (temperature[0] < temperature[2]){ //Si température mesurée temp[0] inférieure à la température enregistrée temp[2] depuis le délai écoulé, délai renseigné dans les variables
      digitalWrite(Circ_Poele, HIGH);
      digitalWrite(Circ_Chauffage, HIGH);
      digitalWrite(EV1_sejour, HIGH);
      digitalWrite(EV2_chambre, HIGH);
    }
    else{*/ // Si température mesurée temp[0] supérieure à la température temp[2] enregistrée depuis le délai écoulé
      digitalWrite(Circ_Poele, LOW);
      digitalWrite(Circ_Chauffage, HIGH);
      digitalWrite(EV1_sejour, HIGH);
      digitalWrite(EV2_chambre, HIGH);
    //}
    AffichageSerie();
    AffichageLCD();
  }

Auriez-vous une idée de l'erreur que j'aurai pu commettre ? je n'arrive pas à comprendre pourquoi ce disfonctionnement !

Merci par avance.

Suite du code puisque cela semble limité en nombre de caratères ...

    
/* Cas 3 : S_POELE > 35°c et S_RAD < 35°c */
  else if (temperature[0] > 35 && temperature[1] < 35) {
    digitalWrite(Circ_Poele, LOW);
    digitalWrite(EV1_sejour, LOW);
    digitalWrite(EV2_chambre, HIGH);
    delay(10000);
    digitalWrite(Circ_Chauffage, LOW);
    AffichageSerie();
    AffichageLCD();
  }

/* Cas 4 : S_POELE > 35°c et S_RAD > 35°c */
  else if (temperature[0] > 35 && temperature[1] > 35) {
    digitalWrite(Circ_Poele, LOW);
    digitalWrite(Circ_Chauffage, LOW);
    digitalWrite(EV1_sejour, LOW);
    digitalWrite(EV2_chambre, LOW);
    AffichageSerie();
    AffichageLCD();
  }
}

Bonsoir,

Ne serait-ce pas à cause de la définition

/*initialisation des variables de température*/
float temperature[0];

qui alloue un tableau de zéro élément alors que l'on trouve un accès au 2nd et 3rd élément ;-((

/* Lecture des températures des sondes */
  temperature[0] = getTemperature(S_POELE);
  temperature[1] = getTemperature(S_RAD);
...
  temperature[2] == temperature[0];

Une définition de

/*initialisation des variables de température*/
float temperature[3];

devrait améliorer la chose

A suivre...

Bonjour,

Je n'avais effectivement pas totalement compris la définition du tableau :unamused:, surtout qu'en l'état cela fonctionne :thinking:

C'est ce que je trouve bizarre, les 2 valeurs de température S_POELE (temperature[0]) et S_RAD (temperature[1]) sont bien remontées via le moniteur série !

merci pour cette piste, je vais tester ça.

Juste pour rendre le code plus compréhensible tu pourrais définir 2 valeurs en début de code

#define CIRCULATION_ACTIVE LOW
#define CIRCULATION_INACTIVE HIGH

et ton code devient tout de suite clair même sans commentaire

digitalWrite(Circ_Poele, CIRCULATION_INACTIVE);

[quote="tchobec, post:6, topic:1327796"] Je n'avais effectivement pas totalement compris la définition du tableau :unamused:, surtout qu'en l'état cela fonctionne :thinking: [/quote] Entre les crochets on définit combien d'éléments le tableau doit contenir. Cela permet au compilateur de réserver en mémoire la place nécessaire pour y placer lesdites valeurs. Mais le compilateur ne vérifie pas si l'on essaye de lire/écrire plus de données que ce que l'on a annoncé dans la définition du tableau. Ce qui peut conduire à des erreurs souvent difficiles à cerner car, si on écrit plus de valeurs que prévu, on risque d'écraser d'autres variables qui pourraient se trouver en mémoire juste derrière le tableau.

Merci pour le complément d'information afin de rendre le code plus clair, ainsi que pour la compréhension du fonctionnement des tableaux.

J'ai trouvé mon erreur :

un malheureux signe "=" en trop ! ça fonctionne nettement mieux maintenant.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.