Go Down

Topic: Errore nella compilazione con TMP36 (Read 3811 times) previous topic - next topic

antoniocnn

Ciao tutti,
ancora una domanda.
Com'è possibile che il termostato di casa indica 23.3°C mentre il sensore mostra 20.3°C?
Posso aggiustare la tensione del pin Vout?

Grazie
Antonio

astrobeed

Com'è possibile che il termostato di casa indica 23.3°C mentre il sensore mostra 20.3°C?
Possibilissimo per tutta una serie di motivi, prima di tutto la precisione di questi sensori che tipicamente è +/- 1° (@25°), è chiaramente scritto sul data sheet, risoluzione e precisione sono due cose diverse, inoltre la lettura dipende dal valore di Aref, se alimenti tramite USB difficilmente sono 5V esatti, il che introduce un ulteriore fattore di errore.
Sommando gli effetti degli errori sul TMP36 e l'errore, che c'è sicuramente, sul sensore del termostato ecco che è possibile arrivare ad uno scarto di 3°, non ultimo il fatto che dentro casa è facile rilevare differenze di un paio di gradi tra punti diversi, la misura di paragone dovresti farla tenendo il TMP36 vicino al sensore del termostato.
Scientia potentia est

antoniocnn

#17
Jun 15, 2016, 09:11 am Last Edit: Jun 15, 2016, 09:19 am by antoniocnn
Possibilissimo per tutta una serie di motivi, prima di tutto la precisione di questi sensori che tipicamente è +/- 1° (@25°), è chiaramente scritto sul data sheet, risoluzione e precisione sono due cose diverse, inoltre la lettura dipende dal valore di Aref, se alimenti tramite USB difficilmente sono 5V esatti, il che introduce un ulteriore fattore di errore.
Alimento arduino con un alimentatore esterno, tengo il cavo USB collegato perché non dispongo di un lcd per cui uso il monitor seriale per monitorare la temperatura.

Sommando gli effetti degli errori sul TMP36 e l'errore, che c'è sicuramente, sul sensore del termostato ecco che è possibile arrivare ad uno scarto di 3°, non ultimo il fatto che dentro casa è facile rilevare differenze di un paio di gradi tra punti diversi, la misura di paragone dovresti farla tenendo il TMP36 vicino al sensore del termostato.
Proverò a tenere il transistor vicino al termostato per valutare meglio le differenze, tenendo conto delle indicazioni che mi hai dato.

Grazie
Antonio

SukkoPera

Invece di usare 5 nei calcoli, potresti utilizzare il Secret Voltmeter (magari tramite questa comoda libreria) e misurare la Vcc reale.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

astrobeed

magari tramite questa comoda libreria
In quella libreria, come in tutte le pagine web che parlano della cosa, c'è un grave errore, viene assunto in modo assoluto il valore di 1.1 V per il riferimento interno degli AVR.
Il generatore 1.1V degli AVR è tutto meno che preciso, il suo valore ha una tolleranza di +/-10%, ovvero la sua tensione può essere un qualunque valore compreso tra 1V e 1.2V, per poter usare in modo efficace il "voltmetro segreto" è necessario misurare la tensione del riferimento 1.1V e inserire il corretto valore nel calcolo.
Per misurare il valore del generatore a 1.1V basta attivarlo e fare la misura sul pin Aref con un buon multimetro elettronico, questo perché il pin viene fisicamente collegato al generatore interno quando è attivo.
Scientia potentia est

antoniocnn

Rieccomi con un nuovo quesito.
Volevo inserire nel monitor seriale il valore minimo e massimo della temperatura.
Qualcuno può indicarmi un semplice codice?

Grazie
Antonio

SukkoPera

In quella libreria, come in tutte le pagine web che parlano della cosa, c'è un grave errore, viene assunto in modo assoluto il valore di 1.1 V per il riferimento interno degli AVR.
In realtà nel costruttore puoi passarle un fattore di correzione Vcc_measured/Vcc_reported.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

antoniocnn

#22
Jun 16, 2016, 07:13 am Last Edit: Jun 16, 2016, 10:56 pm by antoniocnn
Ho notato che il valore di temperatura durante la giornata rimane pressocché costante per cui basta solo trovare il modo di correggere il valore di Vout. La mia idea, seppur strampalata, potrebbe essere quella di inserire un trimmer.
Attualmente utilizzo questa connessione
GND - GND
Vout - Analog Input A0
Vin - +5V

Volevo inserire nel monitor seriale il valore minimo e massimo della temperatura.
Qualcuno può indicarmi un semplice codice?

In realtà nel costruttore puoi passarle un fattore di correzione Vcc_measured/Vcc_reported.
Quale sarebbe?

Grazie
Antonio

brunello22


Code: [Select]
if ( TempC < MinTempC ) {
    MinTempC = tempC ;
  }
  if ( TempC > MaxTempC ) {
    MaxTempC = TempC ;
  }

antoniocnn

Code: [Select]
if ( TempC < MinTempC ) {
    MinTempC = tempC ;
  }
  if ( TempC > MaxTempC ) {
    MaxTempC = TempC ;
  }

Ho provato ma mi dice:
Code: [Select]

'MinTempC' was not declared in this scope
Antonio

Maurotec

Quote
Ho provato ma mi dice:
Code: [Select]


'MinTempC' was not declared in this scope
Ciò vuol dire che non l'hai dichiarata, stessa cosa per le altre variabili presenti nell'esempio.

Il codice che ti hanno suggerito, prima lo devi studiare, comprendere e poi adattare alle tue esigenze.

Quindi ti suggerisco di studiare l'esecuzione di codice condizionato tramite il costrutto if else if.

PS: Ci devi mettere del tuo.

antoniocnn

#26
Jun 17, 2016, 10:50 am Last Edit: Jun 17, 2016, 10:57 am by antoniocnn
Ciò vuol dire che non l'hai dichiarata, stessa cosa per le altre variabili presenti nell'esempio.

Il codice che ti hanno suggerito, prima lo devi studiare, comprendere e poi adattare alle tue esigenze.

Quindi ti suggerisco di studiare l'esecuzione di codice condizionato tramite il costrutto if else if.

PS: Ci devi mettere del tuo.
Obbiettivo raggiunto.
Condivido con la comunity il codice.

Code: [Select]

/*
 * FILE:    TMP36.16GIU16
 * PURPOSE: Temperature test program to show minimum and maximum
 * PROBE:   TMP36
 * AUTHOR:  Antonio Cannavale
 * COMFORT:
 *
 * TMP36 connected to Arduino as follow:
 * GND  - GND
 * Vout - Analog Input
 * Vin  - +5V
 */

int val_ADC = 0; // Set variable
float tempC = 0; // Set variable
float MaxTempC = 150; // Set variable maximum temperature
float MinTempC = -40; // Set variable nimimum temperature

void setup() { // Start setup
 Serial.begin(9600); // Start Serial Communication at boud rate 9600 to verify the output
 delay(500); // Delay to let system boot
 Serial.println("TEMPERATURE TEST PROGRAM");
 Serial.println("------------------------");
 Serial.println();
 Serial.println("Type ,\tmV ,\tT(C) ,\tMin(C)  Max(C)");
} // End setup

void loop() { // Start loop
  val_ADC = analogRead(0); // Getting voltage from sensor at Analog PIN A0
  tempC = (val_ADC*5.0/1023-0.5)/0.01; // 5.0=tensione ADC, 0.5=offset, 0.01=10mV/°C
  if (tempC>MinTempC) {
    MinTempC=tempC;
  }
  if (tempC<MaxTempC) {
    MaxTempC=tempC ;
  }
  Serial.print("TMP36,\t");
  Serial.print(val_ADC); // Print mV ADC value
  Serial.print(",\t");
  Serial.print(tempC); // Print celsius temperature
  Serial.print(",\t");
  Serial.print(MaxTempC);
  Serial.print(",\t");
  Serial.println(MinTempC);
  delay(120000); // Wait 2 minutes before accessing sensor again
} // End loop
Antonio

brunello22

io cambierei qualcosa..

Code: [Select]


/*
   FILE:    TMP36.16GIU16
   PURPOSE: Temperature test program to show minimum and maximum
   PROBE:   TMP36
   AUTHOR:  Antonio Cannavale
   COMFORT:

   TMP36 connected to Arduino as follow:
   GND  - GND
   Vout - Analog Input
   Vin  - +5V
*/

int val_ADC  ; // Set variable
float tempC  ; // Set variable
float MaxTempC   ; // Set variable maximum temperature
float MinTempC   ; // Set variable nimimum temperature

void setup() { // Start setup
  Serial.begin(9600); // Start Serial Communication at boud rate 9600 to verify the output
  delay(500); // Delay to let system boot
  Serial.println("TEMPERATURE TEST PROGRAM");
  Serial.println("------------------------");
  Serial.println();
  Serial.println("Type ,\tmV ,\tT(C) ,\tMin(C)  Max(C)");
  val_ADC = analogRead(A0);
  tempC = (val_ADC * 5.0 / 1023.0 - 0.5) / 0.01;
  MaxTempC = MinTempC = tempC ;
} // End setup

void loop() { // Start loop
  val_ADC = analogRead(A0); // Getting voltage from sensor at Analog PIN A0
  tempC = (val_ADC * 5.0 / 1023 - 0.5) / 0.01; // 5.0=tensione ADC, 0.5=offset, 0.01=10mV/°C
  if (tempC < MinTempC) {
    MinTempC = tempC;
  }
  if (tempC > MaxTempC) {
    MaxTempC = tempC ;
  }
  Serial.print("TMP36,\t");
  Serial.print(val_ADC); // Print mV ADC value
  Serial.print(",\t");
  Serial.print(tempC); // Print celsius temperature
  Serial.print(",\t");
  Serial.print(MinTempC);
  Serial.print(",\t");
  Serial.println(MaxTempC);
  delay(12000000); // Wait 2 minutes before accessing sensor again
} // End loop

antoniocnn

#28
Jun 17, 2016, 10:56 pm Last Edit: Jun 17, 2016, 11:05 pm by antoniocnn
io cambierei qualcosa..
Molto bene.
Mi sembra meglio

Antonio

antoniocnn

#29
Jun 23, 2016, 03:33 pm Last Edit: Jun 25, 2016, 07:20 pm by antoniocnn
Ciao tutti,
sul sito adafruit ho trovato uno schema per migliorare la risposta in temperatura.
Eccovi il codice che condivido
Code: [Select]

/*
   FILE:    TMP36.24GIU16
   PURPOSE: Test program to show minimum and maximum temperature with average
   PROBE:   TMP36
   AUTHOR:  Antonio Cannavale
   COMFORT:
 
   Formula keys: aref_voltage=Volts ADC, 0.5=Volts offset, 0.01=10mV/°C
 
   TMP36 connected to Arduino as follow:
   GND  - GND
   Vout - Analog Input
   Vin  - AREF voltage
*/

#define aref_voltage 3.27 // We tie 3.3V to AREF and measure it with a multimeter!
int val_ADC; // Set variable voltage
float TempC; // Set variable temperature
float MaxTempC; // Set variable maximum temperature
float MinTempC; // Set variable nimimum temperature

void setup() { // Start setup
  Serial.begin(9600); // Start Serial Communication
  analogReference(EXTERNAL);
  delay(500); // Delay to let system boot
  Serial.println("TEMPERATURE TEST PROGRAM");
  Serial.println("------------------------");
  Serial.println();
  Serial.println("Type ,\tmV ,\tT(C) ,\tMin(C)  Max(C)");
  byte n_samples = 10; // Take N samples in a row, with a slight delay
  float average = 0;
    for (byte i=0; i<n_samples; i++) {
         average += analogRead(A0); // Getting voltage from sensor at Analog PIN A0
        _delay_us(200);
    }
  average /= n_samples;
  val_ADC = average; // Getting voltage from average
  TempC = (val_ADC*aref_voltage/1023-0.5)/0.01; // Formula
  MaxTempC=MinTempC=TempC;
} // End setup

void loop() { // Start loop
  byte n_samples = 10; // Take N samples in a row, with a slight delay
  float average = 0;
    for (byte i=0; i< n_samples; i++) {
         average += analogRead(A0);
        _delay_us(200);
    }
  average /= n_samples;
  val_ADC = average; // Getting voltage from average
  TempC = (average*aref_voltage/1023-0.5)/0.01; // Formula
  if (TempC<MinTempC) {
    MinTempC=TempC;
  }
  if (TempC>MaxTempC) {
    MaxTempC=TempC ;
  }
  Serial.print("TMP36,\t");
  Serial.print(val_ADC); // Print mV ADC value
  Serial.print(",\t");
  Serial.print(TempC); // Print celsius temperature
  Serial.print(",\t");
  Serial.print(MinTempC); // Print minimum celsius temperature
  Serial.print(",\t");
  Serial.println(MaxTempC); // Print maximum celsius temperature
  delay(120000); // Wait 2 minutes before accessing sensor again
} // End loop
Antonio

Go Up