Thermostats , besoin d'augmenter la température graduellement dans le temps

Bonjour à tous,

Etudiant en Biologie marine et récent utilisateur d’Arduino, je suis actuellement en train de réaliser un projet pour lequel j’ai besoin d’acclimater des organismes d’une eau a 19°C jusqu’à une température de 23°C (Cela devrait prendre au moins 12h). Jusqu’à maintenant je dispose du script suivant qui me permet de réguler ma température mais celle-ci monte à la température max en moins d’une heure ce qui n’est pas souhaitable pour mes bestioles:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Time.h>
#include <RTClib.h> 
#include <SD.h>

const int onewirePin =  8;       // pin number for onewire temp sensor
const int heaterPin =  5;        // pin for heater relay

const int maxTemp = 22;          // temperature ar which heater turns off
const int minTemp = 23;          // temperature ar which heater turns on
const int valueLogInterval = 10000; // interval in miliseconds to log measurements (temp and waterheight)

float waterTemp;
RTC_Millis RTC;
const int chipSelect = 10; // select chip for SD card reader
OneWire oneWire(onewirePin); // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
void setup() {
  // put your setup code here, to run once:
pinMode(heaterPin, OUTPUT);
  digitalWrite(heaterPin,0);
  delay(2000);
  digitalWrite(heaterPin,HIGH);
delay(2000);
  digitalWrite(heaterPin,0);

  Serial.begin(9600);
  sensors.begin();
  RTC.begin(DateTime(__DATE__, __TIME__));
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  File dataFile = SD.open("TT7.txt", FILE_WRITE);
  if (dataFile) {
   dataFile.print("maxTemp=");dataFile.println(maxTemp);
   dataFile.print("minTemp=");dataFile.println(minTemp);
   dataFile.print("valueLogInterval=");dataFile.println(valueLogInterval);
   dataFile.close();
  }
  else {
    Serial.println("error opening file");
  } 
}


void loop() {
  // put your main code here, to run repeatedly:
String dataString = "";
  DateTime now = RTC.now();
  dataString = dataString + ";Date=" + String(now.year())+ String(now.month())+ String(now.day()) + ";Time = " + String(now.hour()) + ":" + String(now.minute()) + ":" + String(now.second());
  
  sensors.requestTemperatures();  
  waterTemp = sensors.getTempCByIndex(0);
  Serial.print(" | ");
  Serial.println(waterTemp);
  
 if (waterTemp < minTemp & digitalRead(heaterPin) == 0) {
    digitalWrite(heaterPin,HIGH);
    dataString = dataString + ";Heater ON";
      }
 if (waterTemp > maxTemp & digitalRead(heaterPin) == 1) {
    digitalWrite(heaterPin,LOW);
    dataString = dataString + ";Heater OF";
      }
      
 dataString = dataString + ";Temp = " + waterTemp + ";" + String(now.minute()) + ":" + String(now.second());

  File dataFile = SD.open("TT7.txt", FILE_WRITE);
   // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
     Serial.println(dataString);
    Serial.println("error opening log file on SD card.txt");
  } 
 delay(valueLogInterval);
 }

J’en ai discuté avec mon superviseur mais sollicite votre aide pour me permettre d’avancer un peu plus rapidement. Je pense qu’il faut rajouter des lignes indiquant que ma température max doit augmenter disons toutes les 30 min de 0.1°C mais je ne sais pas si cela est réalisable.

Merci d’avance pour votre aide

Bonjour et bienvenue,

une solution assez simple je pense :

  1. Apprendre à gérer une tache périodique avec par exemple Blink Without Delay.

  2. Faire une tache périodique (de période 30 mn) qui incrémente minTemp et maxTemp de 0.1 degré (si ne dépassent pas les valeurs limites)

Ton minTemp et ton maxTemp sont là pour amortir les oscillations, je te laisse les gérer, mais l’idée c’est de les initialiser à la valeur mini et de laisser la fonction périodique les faire évoluer toutes les 30 mn.

salut

il y a à mon avis un problème dans ton programme, la température n’est évaluée que toute les “valueLogInterval” ms. (1000, dans ton cas, soit une s )

Selon la puissance du chauffage, surtout si il faut faire des augmentation aussi faibles que 0.1°,tu risques de dépasser la consigne avant que le test ne se fasse. Surtout avec en plus le délai de chauffage du capteur etc etc
Cela dit, vouloir faire une précision à 0.1° avec un ds18b20, perso je n’y crois pas trop.

pour résoudre ça il faudrait faire la temporisation en utilisant millis() pour que ce ne soit pas bloquant. Et ainsi pouvoir en imbriquer plusieurs : une avec le délai de log, et une avec le délai d’augmentation de température (puisqu’il faut augmenter la valeur de consigne toutes les 30 min)

Modifier ton code actuel sur la base des indication que je viens de donner ne devrait pas être trop compliqué.

Commence déja par remplacer le delay(valueLogInterval); par une temporisation utilisant millis()

EDIT : grilled par supercc, mais finalement on dit la même chose…

Bonjour,

il doit augmenté de 23°-19°/12h=0,33°

meme si vous modifier le const int valueLogInterval = 10000; en le divise par 12h ( comme il monte en 1h) ça donne 833 millis, mais sans tenir compte de la déperdition de "la boite, cuve ...", et donc ça ne résout pas le problème

Je pense qu'il faut voir également le volume chauffé et la puissance de l'élément chauffant.

Si il est surdimensionné il peut poser problème. Peut être voir du coté du PID également ?

@+

J4l13n: meme si vous modifier le const int valueLogInterval = 10000; en le divise par 12h ( comme il monte en 1h) ça donne 833 millis, mais sans tenir compte de la déperdition de "la boite, cuve ...", et donc ça ne résout pas le problème

Avec la structure actuelle du programme basée sur delay(), cela ne PEUT PAS fonctionner correctement dès lors que l'on va augmenter la valeur du delay --> pas de vérification de modification de T° durant toute la durée du delay, même si le chauffage est en fonction

Ah oui exact c'est pour ca que ca chauffe en 1heure la valeur ne sert que pour ecrire sur la SD...

ça chauffe en 1h parceque la consigne dans le programme c'est uniquement la valeur finale, elle n'évolue pas. donc 1h, c'est le temps qu'il faut pour chauffer avec la résistance utilisée.

mais le temps ne sert pas que d'intervalle de log sur la carte, c'est la "pulsation" de base du programme tel qu'il est écrit pour le moment : même la température n'est évaluée que toute les valueLogInterval millisecondes, si entre deux tours de boucle la température dépasse la consigne ou retombe en dessous, rien ne se passera quand même avant la prochaine échéance de valueLogInterval

bricofoy: Cela dit, vouloir faire une précision à 0.1° avec un ds18b20, perso je n'y crois pas trop.

bonjour Un DS18B20 est donné pour une précision de +/- 0.5° C entre -10 +85 °C Pas mal de gens s'arretent essentiellement sur la résolution de conversion du DS18B20 qui à 12 bits est un pas de 0.0625 °C

Compte tenu de l'exposé et des contraintes , AMHA je pense que la gestion de la montée en T° devra etre faite par PID "affiné" :grin:

Déjà , il n'y a aucun dimensionnement du volume d'eau (et de sa geometrie) à maintenir/stabiliser en T°

Pour aller dans le sens d'Artouste pour commencer un calcul simple.

Combien faut-il fournir de calories pour élever 1 litre d'eau de 1°C ? J'ai bien une petite idée mais mes années lycée sont très loin.

Il suffit de convertir les calories en joules (1 cal = 4,18 J) puis en déduire les watts en prenant le temps en compte. Et cela permettra de vérifier que l'organe chauffant est correctement dimensionné : c'est à dire ni sous dimensionné (apparemment ce n'est pas le cas) ni sur dimensionné ce qui rendrait la régulation plus délicate à maîtriser.

Pour connaître la réaction du bassin je disposerai plusieurs sondes DS18B20 et je lancerai un chauffage permanent jusqu'à obtenir la température de 23°C. Programme qui mesure en permanence les indications des sondes à intervalle régulier

Connaissant la température de départ et le nombre de cycle de mesure on peut contrôler le nombre de calories précédent qui peut être légèrement différent car maintenant on a un ensemble avec parois et déperdition de chaleur.

La puissance de chauffage est constante --> voir sur la doc du produit. On connaît le temps on en déduit les joules et donc les calories.

Une courbe de l'élévation en température en fonction du temps permettra de préparer la "PID affinée" d'Artouste.

Note sur les sondes : Comme pour tout capteur il faut bien distinguer la précision de la valeur affichée et la capacité à détecter des petits ecart sans erreur. Un thermomètre peut afficher 22 °C au lieu de 20 °C soit 2 degrés d'erreur mais être capable de discerner des écarts de 0,1 °C sans faire d'erreur.

Une sonde de température peut très bien se calibrer par programme après qu'elle ait été étalonnée en comparaison avec un thermomètre de précision.