Régulation de température

Bonjour,

Pour les besoins d'une manipulation (propagation de la chaleur dans une barre métallique), je dois contrôler la température à une des extrémités d'une barre pour qu'elle soit le plus possible constante (après un temps de chauffe bien entendu).
Ma source est constituée d'une résistance reliée à une alimentation : une puissance de 40W (20V, 2A) me donne une température finale adaptée à la taille de ma barre et obtenir à l'autre extrémité une température constante (celle de la pièce).
Pour réguler la température, j'ai commencé par ajouter un relais mais les oscillations sont trop importantes (~1.5V d'écart) : j'ai essayé de modifier plusieurs paramètres mais sans grand succès.

Mon code :

//chargement des librairires nécessaires
#include <OneWire.h>
#include <DallasTemperature.h>



//définition des constantes du programme
const unsigned long BAUD = 250000; //débit de la liaison série
#define ONE_WIRE_BUS  7  //broche de connexion des capteurs température



//déclaration de l'objet one wire qui permet de gérer le bus one wire
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

byte nbTemperature ;  //variable qui contiendra le nombre de capteurs détecté
unsigned long tempsZero;
unsigned long tempsCourant;


//variable pour le délai
unsigned int delai = 2000;
unsigned int delaiRegul = 10000;

//température de consigne
const float tempConsigne = 80.0;
const float ecartTemp = 0.6 ;
const float ecartTempMontee = 2;

//variable pour 1ere montee temp
boolean testMontee = 0;
boolean testMontee2 = 0;
boolean testRelais;

//variable
byte relais = 2;

void setup()
{
  Serial.begin(BAUD);
  pinMode(relais, OUTPUT);
  sensors.begin();

  //mise à zéro du compteur temps
  tempsZero = millis();

  //on récupère le nombre de capteurs détecté par le système et on l'affiche
  nbTemperature = sensors.getDeviceCount() ;
  //Serial.println("Nombre de capteurs de température : " + String(nbTemperature)) ;

  //affichage des en-tête
  Serial.print("t");  // donne la date en seconde
  Serial.print('\t');

  /*for (int i = 1 ; i <= nbTemperature ; i++)
    {
    Serial.print("T");
    Serial.print(i);
    Serial.print('\t');
    }
  */
  Serial.println("T");


  Serial.print("s");  // donne la date en seconde
  Serial.print('\t');

  /*for (int i = 1 ; i <= nbTemperature ; i++)
    {
    Serial.print("°C");
    Serial.print('\t');
    }

    Serial.println("");*/
  Serial.println("°C");
}

void loop()
{
  sensors.requestTemperatures();

  //calcul du temps courant
  tempsCourant = millis() - tempsZero;
  Serial.print(tempsCourant / 1000); //affichage en secondes
  Serial.print('\t');

  //Mesure des températures sur le nombre de sondes détectés
  for (int i = 0 ; i < 1 ; i++)
  {
    float temperature = sensors.getTempCByIndex(i);
    if (i != nbTemperature - 1)
    {
      Serial.print(temperature);
      Serial.print('\t');
    }
    else
    {
      Serial.println(temperature);
    }
  }
  float temperature = sensors.getTempCByIndex(0);
  if (testMontee == 0)
  {

    if (temperature <= tempConsigne - ecartTemp)
    {
      digitalWrite(relais, HIGH);
      testRelais = 1;
    }
    else
    {
      digitalWrite(relais, LOW);
      testRelais = 0;
      testMontee = 1;
    }
  }
  if (testMontee == 1)
  {

    if (temperature <= tempConsigne - ecartTemp)
    {
      digitalWrite(relais, HIGH);
      testRelais = 1;
    }
    else
    {
      digitalWrite(relais, LOW);
      testRelais = 0;
    }
    if (temperature >= tempConsigne +  ecartTemp)
    {
      digitalWrite(relais, LOW);
      testRelais = 0;
    }
    else
    {
      digitalWrite(relais, HIGH);
      testRelais = 1;
    }
  }

  /*
    if (testMontee2 == 1)
    {
      if (sensors.getTempCByIndex(0) < tempConsigne+0.5)
      {
        digitalWrite(relais, HIGH);
        testRelais = 1;
      }

      else
      {
        digitalWrite(relais, LOW);
        testRelais = 0;
      }
    }
  */

  //Serial.print(testMontee);
  //Serial.print("\t");
  //Serial.println(testRelais);
  //délai entre deux mesures
  delay(delai);
}

Merci pour votre aide

Je dirai qu'il est trop tôt pour parler de code.
Parlons matériel et principes physiques.
En théorie la commande par tout ou rien n'est pas ce qui est le plus adapté pour avoir une régulation très précise mais ce n'est pas pour autant qu'il faut la rejeter.

Ôtons un doute : tu parles de 1,5 V d'écart : ne serait-ce pas plutôt 1,5 °C d'écart ?
Question quelle précision recherches-tu ? Répondre la meilleure n'est pas une réponse.
Quelle anticipation fais-tu ?
La transmission de chaleur est un phénomène lent, quand on coupe la source de chaleur elle ne s'arête pas instantanément il faut tenir compte de cette inertie et couper la source de chaleur avant d'atteindre la valeur de consigne comme la réactiver par anticipation quand la température diminue.

Une sonde de température a aussi sont propre temps de réponse il faut le connaître pour en tenir compte.
Qu'est ce qui dit que la température renvoyée par la sonde, qui semble être un DS18B20, est fiable ?

Je ne mets pas en doute tes choix matériels, je pose des questions.

68tjs:
Ôtons un doute : tu parles de 1,5 V d'écart : ne serait-ce pas plutôt 1,5 °C d'écart ?

Oui bien sûr, une erreur de frappe : il s'agit bien de 1.5°C;
Mon idéal serait d'avoir un écart au maximum de 0.5°C par rapport à la consigne (soit un delta de 1°C);
la "vraie" valeur de la température m'importe finalement peu : ce qui m'intéresse est d'avoir une température constante à un bout de ma barre métallique.
Pour prendre en compte l'inertie thermique, je prévois d'arrêter de chauffer quand la température est proche de la valeur de consigne

Pour prendre en compte l'inertie thermique, je prévois d'arrêter de chauffer quand la température est proche de la valeur de consigne

Oui mais cela va dépendre de la capacité calorique de l'objet à chauffer et de la source de chaleur.

Ce qui veut dire gros calcul de spécialistes en thermique ou si tu en connais autant que moi dans ce domaine de l'expérimentation méthodique avec traçage de courbes pour aider à y voir plus clair.

Sinon à la place du relai que pense-tu d'un transistor mosFet de puissance (attention au choix du Vgs_theshold) qui serait commandé en PWM ? Je pense que la commande devrait être plus souple qu'en tout ou rien.
Attention je ne dis pas qu'il faut immédiatement remplacer le relai par un transistor, il faut déjà faire les expérimentations. Je dis simplement que si tu devais changer de principe et que si tu commandes en Chine cela va bientôt être leur nouvel an et c'est la plus mauvaise saison pour espérer recevoir rapidement sa commande, dans ce domaine aussi il faut de l'anticipation. :grin:

Bonjour,

Je suis plus du côté expérimental que théorique : je fais les essais et réévalue les constantes pour essayer d'approcher ce que je cherche à obtenir.

Bonne idée pour le mosfet et programmation par pwm cependant, mes connaissances en électronique s'arrêtent ici : je connais quelques grandes lignes des transistors mais pas beaucoup (juste quelques généralités), en particulier, je n'ai pas suffisamment de connaissance pour connaître les caractéristiques qui correspondent à telle application.
Aurais tu un transistor à me conseiller ?

Un IRLZ44N se trouve très facilement pour une poignée de centimes.

Brancher la charge entre le drain (OUT) et le + de l'alimentation.

Bonjour,

Le schéma complet est-il celui-là en pièce jointe ?

Au niveau compréhension :
on utilise le MOSFET comme un interrupteur commandé par la tension issue de l'Arduino : si on a 5V alors l'interrupteur source-drain est fermé et donc le courant circule dans la résistance de chauffage ?
La résistance de 220 ohm sert je suppose à limiter le courant liée à la borne Arduino ?
La résistance de 100k correspond à une résistance de pull-down ?

Au niveau programmation, j'utilise le même principe que ce que j'ai posté en 1 (pour le relais) ?

Question subsidiaire : cette méthode est sans doute généralisable à tout composant qui demande un peu de courant (moteur, électroaimant, ...) ?

alimentation_mosfet.pdf (28.2 KB)

Bonjour,

Je ne suis pas trop spécialiste du logiciel, mais je vais tenter quelques remarques qui vont dans le sens de ce que signalent mes "petits camarades" :

  • Le principe de remplacement du relais par un transistor est sans doute une très bonne idée car cela permet des réponses plus rapides aux écarts de température.
  • De plus cela ouvre la porte à un modulation fine du procédé de chauffage en permettant éventuellement d'appliquer un chauffage de puissance dépendant de l'écart de température avec la consigne. (PWM)
    Quand au programme proprement dit, on pourrait améliorer la lisibilité et la structuration en utilisant de manière systématique le découpage en fonctions.

Serge .D

aligote:

  • De plus cela ouvre la porte à un modulation fine du procédé de chauffage en permettant éventuellement d'appliquer un chauffage de puissance dépendant de l'écart de température avec la consigne. (PWM)

Tu évoques ici un régulateur type PID ?

aligote:
Quand au programme proprement dit, on pourrait améliorer la lisibilité et la structuration en utilisant de manière systématique le découpage en fonctions.

C'est un programme brut de décoffrage qui me servait de test de la manipulation : je me doute, mais ne me suis pas penché sur une optimisation, car je n'arrivais pas à obtenir ce que je souhaitais
Merci pour ton retour !

Bonjour

  • De plus cela ouvre la porte à un modulation fine du procédé de chauffage en permettant éventuellement d'appliquer un chauffage de puissance dépendant de l'écart de température avec la consigne. (PWM)

Tu évoques ici un régulateur type PID ?

Vu l'inertie du système à asservir le terme I (Intégral) ajouté au P (proportionnel) paraissent suffire
Le PWM ouvre la voie à ce type de régulation

Au niveau compréhension :
on utilise le MOSFET comme un interrupteur commandé par la tension issue de l'Arduino : si on a 5V alors l'interrupteur source-drain est fermé et donc le courant circule dans la résistance de chauffage ?
La résistance de 220 ohm sert je suppose à limiter le courant liée à la borne Arduino ?
La résistance de 100k correspond à une résistance de pull-down ?

Oui pour tout.
La grille d'un MOSFET a une capacité importante, sans la résistance de 220Ω le courant d'appel lors des commutation serait trop important pour l'ARDUINO.

al1fch:
Bonjour
Tu évoques ici un régulateur type PID ?
Vu l'inertie du système à asservir le terme I (Intégral) ajouté au P (proportionnel) paraissent suffire
Le PWM ouvre la voie à ce type de régulation

Je suis assez d'accord.

Je pense aussi à une remarque à propos d'une sonde Dallas qui peut présenter un temps de réponse assez long. On peut se poser la question, est-il préférable d'avoir une mesure de température relativement précise mais après un délai de plusieurs dixièmes de secondes plutôt qu'une mesure un peu moins précise mais plus rapidement ?
Serge .D

La qualité de la régulation dépend prioritairement de la qualité du capteur de température.
La Ds18B20 est très répandue dans le monde arduino mais ce n'est probablement pas la plus adaptée a ce projet.
L'inertie de l'enveloppe en résine de la puce n'est pas spécifiée, peut-être qu'en interrogeant Maxim il serait possible d'avoir de la documentation.
Les thermocouples sont plus délicats à mettre en œuvre et demandent des composants annexes mais la masse de la soudure étant très faible il me semble qu'ils devraient être plus agiles.
Si la soudure est en contact direct avec la barre c'est mieux pour le temps de réponse mais il faut que la barre soit isolée des autres potentiels, c'est probablement pas simple à faire.

Bonjour,

Je reviens vers vous car j'ai enfin pu me procurer le transistor IRLZ44.
J'ai fait le branchement, le montage fonctionne : j'obtiens (logiquement) des oscillations de la température autour d'une valeur. Toutefois, l'amplitude des oscillations est bien moins importante : c'est beaucoup mieux !

j'aimerais, comme il l'a été suggéré, améliorer le contrôle de la température en utilisant un système PID, enfin PI puisque si j'en crois les réponses de al1fch et aligote cela est suffisant compte tenu de l'inertie du système.
J'ai commencé à chercher de la documentation à droite à gauche mais je ne vois pas le paramètre qu'il faut prendre comme commande.

Pourriez-vous m'aiguiller à mettre en œuvre cette PI ?

Merci

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