[résolu] TMP36

Bonjour,

Qu'est qui ne vas pas dans mon code ?
Avez vous une idée ?


SUJET résolu Tous mes remerciements :slight_smile:

mon code pour tester un TMP36 sans lissage donc valeurs brutes
Pour un thermostat, lisez les avis ci dessous

//test d'un TMP36GZ sur une uno
int tempPin = A1;
float volts = 0;
float degre = 0;


void setup() {
Serial.begin(9600); 

  //alim virtuel utilisant A0 et A1 histoire de planter le tmp 36GT9Z directement sur la carte uno
const int vcc = A0;
  pinMode(vcc,OUTPUT);
  digitalWrite(vcc,HIGH);
  const int gnd = A2;
  pinMode(gnd,OUTPUT);
  digitalWrite(gnd,LOW);
 

}

void loop() {
      tempPin=analogRead(A1);
      float volts = (tempPin * 5.0)/1024.0;
      degre=(1000*volts-500)/10;
delay (2000);
Serial.print("t°  ");
Serial.println(degre);
Serial.print("tension :  ");
Serial.println(volts);
Serial.print("valeur du CAN :  ");
Serial.println(tempPin);

}

JE vois quelques petits defauts:
*incoherence entre le commentaire sur l'alim virtuelle A0-A1 et le code A0 A2

  • le CAN/DAC a 1024 possibilités, pas 1044
    temPin ne peut être à la fois un numero de patte (A1)
    , comme déclaré en globale, et la valeur analogique (ça n'a pas de conséquence)

J'afficherais "volts" sur la jonction série (et même tempPin) , et je le calculerais par
float volts = (tempPin * 5.0)/1024.0;

dbrion06:
JE vois quelques petits defauts:
*incoherence entre le commentaire sur l'alim virtuelle A0-A1 et le code A0 A2

  • le CAN/DAC a 1024 possibilités, pas 1044
    temPin ne peut être à la fois un numero de patte (A1)
    , comme déclaré en globale, et la valeur analogique (ça n'a pas de conséquence)

J'afficherais "volts" sur la jonction série (et même tempPin) , et je le calculerais par
float volts = (tempPin * 5.0)/1024.0;

c'est bien A2 pas A1 mon alim virtuel, j'ai écris trop vite...

avec ton calcul plus propre j'ai toujours le même souci.

20.88
20.40
20.40
20.40
20.88
20.88
20.88
20.88
20.40
20.88
20.88
20.40
20.40
20.88
20.88
20.88
20.40
20.88
20.40
20.40
20.40
20.88
20.40
20.88
20.88
20.88
20.40
20.40
20.40
20.88
20.40
20.40
20.88
20.40
20.40
20.88
20.40

le code corrigé :

/test d'un TMP36GZ sur une uno


int tempPin = A1;
float volts = 0;
float degre = 0;


void setup() {
Serial.begin(9600); 

  //alim virtuel utilisant A0 et A1 histoire de planter le tmp 36GT9Z directement sur la carte uno
const int vcc = A0;
  pinMode(vcc,OUTPUT);
  digitalWrite(vcc,HIGH);
  const int gnd = A2;
  pinMode(gnd,OUTPUT);
  digitalWrite(gnd,LOW);
 

}

void loop() {
      tempPin=analogRead(A1);
      volts=(5.0/1044)*tempPin;
      float volts = (tempPin * 5.0)/1024.0;
delay (2000);
Serial.println(degre);
}

Tu as viré le calcul de degre

deuxièmement tu as deux variables volts, globale et locale.

void loop() {
      tempPin=analogRead(A1);
      volts=(5.0/1044)*tempPin;
      float volts = (tempPin * 5.0)/1024.0;
delay (2000);
Serial.println(degre);
}

ne calcule nulle part "degre"

Je ferais

void loop() {
      tempPin=analogRead(A1);
 
      float volts = (tempPin * 5.0)/1024.0;
       degre=(100.0*volts-50.0);
delay (2000);
Serial.print(tempPin); Serial.print("\t");
Serial.print(volts);Serial.print("\t"); //
Serial.println(degre);
}

Au fait, est ce que la température varie? (vos sorties ne m'ont pas choqué; si vous mettez votre capteur pès de glaçons ou d'une tasse de thé, je m'inquièterais, mais s'il est fixe...)

C’est pas corrigé : tu définis deux fois la variable volts. Il faut remplacer ces deux lignes

     volts=(5.0/1044)*tempPin;
     float volts = (tempPin * 5.0)/1024.0;

par

     volts = (tempPin * 5.0)/1024.0;

je me suis gouré en copiant collant. Bon, je reprends avec ctrl a ctrl c et ctrl v, ça m'évitera de me ridiculiser !

//test d'un TMP36GZ sur une uno


int tempPin = A1;
float volts = 0;
float degre = 0;


void setup() {
Serial.begin(9600); 

  //alim virtuel utilisant A0 et A1 histoire de planter le tmp 36GT9Z directement sur la carte uno
const int vcc = A0;
  pinMode(vcc,OUTPUT);
  digitalWrite(vcc,HIGH);
  const int gnd = A2;
  pinMode(gnd,OUTPUT);
  digitalWrite(gnd,LOW);
 

}

void loop() {
      tempPin=analogRead(A1);
      float volts = (tempPin * 5.0)/1024.0;
      degre=(1000*volts-500)/10;
delay (2000);
Serial.println(degre);
}

ce qui me chagrine, c'est ces variations 0.5 sans arrêt avec ou sans float !
Je me fait vieux ....

pomme-poire:
avec ton calcul plus propre j'ai toujours le même souci.

20.88

20.40
20.40
20.40
20.88
20.88
20.88

En fait, avec un capteur ayant un facteur d'échelle de 10mV par degrés et l'ADC ayant un LSB de 5mV, le bruit que tu rapportes correspond à la variation d'un LSB du codeur. Je dirais que c'est plutôt pas mal. Si tu veux lisser les valeurs il faut faire un filtrage.

qu'entend tu par filtrage ?

//test d'un TMP36GZ sur une uno


int tempPin = A1;
float volts = 0;
float degre = 0;


void setup() {
Serial.begin(9600); 

  //alim virtuel utilisant A0 et A1 histoire de planter le tmp 36GT9Z directement sur la carte uno
const int vcc = A0;
  pinMode(vcc,OUTPUT);
  digitalWrite(vcc,HIGH);
  const int gnd = A2;
  pinMode(gnd,OUTPUT);
  digitalWrite(gnd,LOW);
 

}

void loop() {
      tempPin=analogRead(A1);
      float volts = (tempPin * 5.0)/1024.0;
      degre=(1000*volts-500)/10;
delay (2000);
Serial.print("t°  ");
Serial.println(degre);
Serial.print("tension :  ");
Serial.println(volts);
Serial.print("valeur du CAN :  ");
Serial.println(tempPin);

}
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146
t°  21.29
tension :  0.71
valeur du CAN :  146

en laissant tourner ça se stabilise

Tu as toujours la possibilité d'utiliser la référence interne pour travailler avec un LSB plus petit. Mais cela réduit la dynamique. Et comme le LSB devient très petit tu vas avoir des problèmes avec la qualité de l'alimentation, le bruit ambiant capté par les fils, le bruit intrinsèque du codeur, ....

filtrage? une moyenne sur plusieurs échantillons par exemple

Vos valeurs, si vous estimez une température constante, ne me choquent en aucune façon... C'a éré dit.
il y a deux types de filtrage:
a) linéaire, par moyennes eventuellement pondérées
ex :
a1) une moyenne sur 8/10/16 mesures, eventuellement glissantes (si on utilise une puissance de deux, la division devient triviale)
a2) une simulation d'un réseau RC:
moy= 0.75 moy + 0.25mesure. (le bruit de quantification est atténué d'un facteur ~= 0.25)

b) un hysteresis, pour les afficheurs, où les frétillements des dernières décimales sont agaçants
float oldtempe; // une variable globale ou static
if (abs (tempe -oldtempe) > SEUIL {
oldtempe = tempe;
afficherSurLCD(oldtempe);
}

il faut me tutoyer. sinon ça me met mal à l'aise
je comprends mieux
pour un thermostat oui, faut faire comme ça sinon le chauffage ne va pas faire long feu !

Merci beaucoup à vous tous.

sujet résolu

Pour un thermostat il vaut mieux lisser ET mettre de l'hystérésis.

Tu as aussi la librairie pour les faignéants (dont je fais partie) : RunningAverage qui s’occupe de moyenner tes résultats :wink:

une librairie…cool