temperatura ballonzolante TMP36

…bsera a tutti. Un semplicissmo codice per leggere la temperatura…ma ballonzola molto.
Perchè?
Suggerimenti per renderla più stabile?
Grazie

/*
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)
*/
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() 
{
 lcd.begin(16, 2);
 Serial.begin(9600);
}
void loop()
{
  int TEMP = analogRead(A0);
  // PRIMO METODO LETTURA  
  /*
  float volt = (TEMP/1020.0) * 4.9;
  float tempC = (volt - 0.5) * 100;
  */
  //SECONDO METODO LETTURA
  float tempC=((TEMP*0.00488)-0.5)/0.01;
  
  lcd.setCursor(0,0);
  lcd.print("Temperatura");
  lcd.setCursor(0,1);
  lcd.print(tempC);
  Serial.println(tempC);
  lcd.print(" C");
  delay(1000);
}

…ho trovato un altro codice…però però…vorrei ottimizzarlo anche magari con modifiche hardware

//
int temperaturaMassima = 27;
const int NRLETTURE = 12; // numero letture
const int SensorPin = A0; //variabile lettura sensore
float valori[NRLETTURE]; //array con i valori
int T_campionamento = 80; // tempo campionamento
float sommaGradi; //variabile somma
float mediaGradi; //variabile media
#include <LiquidCrystal.h> // includo la libreria del display lcd
 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //pin display LCD
 
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  Serial.begin(9600); //inizializzo la seriale
  lcd.print("--");
  lcd.setCursor(0,2);
  lcd.print("--");
  delay(3000);
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
 
 
}
 
void loop() {
 
  for ( int i = 0; i<=NRLETTURE;i++)
  {
    int sensorVal = analogRead(SensorPin);
 
  float voltage = (sensorVal /1024.0) * 5.0;
  float temperature = (voltage - .5) * 100;
    valori[i] = temperature;
    delay(T_campionamento);
  }
   sommaGradi = 0; // devi essere sicuro che il primo valore sia zero, altrimenti poi sballa tutto
  for(int i=0; i<NRLETTURE; i++) { //ciclo che somma i valori dell'array
    sommaGradi = sommaGradi + valori[i];
  }
     mediaGradi = sommaGradi / NRLETTURE; //divido la somma dei valori per il loro numero (media)
      lcd.clear(); //pulisco lo schermo
  Serial.print ("Gradi: "); //scrivo sul display la parola "gradi"
  Serial.println(mediaGradi); //scrivo la temperatura sulla seriale
  lcd.print("Temperatura:"); //scrivo sul display la parola "temperatura"
  lcd.setCursor(0,2); //sposto il cursore sulla seconda linea
  lcd.print(mediaGradi); //scrivo la temperatura
  lcd.print(" Gradi"); // scrivo sul display la parola "gradi"
if (mediaGradi >temperaturaMassima)
{
  digitalWrite(13,HIGH);
  Serial.println("Temperatura raggiunta!!!!");
}
  else {
   digitalWrite(13,LOW);
}
 
  delay(500);

    }

Dipende tutto quanto costante é la tensione di alimentazione. Ciao Uwe

uwefed: Dipende tutto quanto costante é la tensione di alimentazione. Ciao Uwe

Bgiorno Uwe, ora sto alimentando con i 5VCC di Arduino...quasi quasi provo ad inserire il "ref". Al momento è un monmtaggio sperimentale su millefori però devo utilizzarla come sonda per alcuni rilievi qundi salderò il TMP ad una cavetto di una 40 di cm. ...balla troppo più di un grado

Puoi anche provare semplicemente ad aggiungere un condensatore da 220μF in parallelo all'alimentazione ed ha fare più acquisizioni (es. 10 distanziate di 100 msec l'una dall'altra) calcolandone la media.

Il problema NON è nella stabilità dell'alimentazione verso il TMP36, quanto della MCU, che utilizza i 5V come Vref del ADC. Se questi non sono stabili, ecco che le misure oscillano.

Oppure, se il limite superiore di circa 60° ti basta (dato che lo 0° è a 500mV, ti rimane solo il range da 500mV a 1.1V, ovvero circa 600mV di scala verso i valori positivi di temperatura, pari appunto a circa 60°), potresti anche usare il riferimento interno da 1.1V che è piuttosto stabile (anche se non sempre esattamente a 1.1V, il che ti richiede una piccola correzione per avere la temperatura reale, correzione che comunque ... è quasi sempre necessaria per correggere piccole differenze di misura).

Guglielmo

Bgiorno Guglielmo...smanetto un pò e vi aggiorno. Grazie ad entrambi per i chiarimenti.

update: con l'elettrolitico è molto più stabile. IN effetti avevo letto della stabilità e sarei dovuto arrivarci da solo. MI metto una sufficenza...scarsa. Che ne dici Gugliemo?

vince59: update: con l'elettrolitico è molto più stabile. IN effetti avevo letto della stabilità e sarei dovuto arrivarci da solo. MI metto una sufficenza...scarsa. Che ne dici Gugliemo?

Ahahahahahahah ... ok ... :D

... se in più fai la media di un 10/15 misure, lo rendi ancora più stabile ... ;)

Guglielmo

Gugliemo...

perchè la IDE 1.8.5. non mi riconosce la libreria che invece è ricnosciuta dalla IDE 1.0.6?

Libreria? Che libreria ? da dove l'hai scaricata/installata ?

Guglielmo

P.S.: ... e comunque, dalla 1.0.6 alla 1.8.5 ... moltissime cose sono cambiate e tante cose vanno corrette.

si Guglielmo me ne sono accorto. Utilizzo arduino su un muletto sony xp/sp3 ed ogni tanto mi tocca litigare con le IDE. Utilizzo la vecchia 1.0.6 e vado tranquillo…in pratica la 1.8.5 trovava qualcosa da qualche parte che nongli andava giù.

Guglielmo ora sono soddisfatto della stabilità della sonda. Ora devo provare a collegarne due per rilevare la T in entrata ed uscita. Immagino si sufficente solo duplicare la lettura/conversione su un secondo pin analogico…giusto?

vince59: Ora devo provare a collegarne due per rilevare la T in entrata ed uscita. Immagino si sufficente solo duplicare la lettura/conversione su un secondo pin analogico....giusto?

SI, ma ricorda, per precauzione, al cambio di pin analogico, [u]di scartare la prima lettura[/u]. Se fai un po' di ricerche qui sul forum trovi anche qualche discussione con la spiegazione in dettaglio del perché ;)

Guglielmo

...il codice è pronto devo trovare nei cassetti un altro tmp36.

DOMANDA: volendo correggere il rilevamento del tmp36 (leggo un pò meno se comparato ad altri strumenti) dove mi conviene intervenire nella formula?

... direttamente sul risultato finale. Prendi un termometro di cui sei certo, verifica la differenza ed applicala al valore calcolato (... del resto, il TMP36, ha una "accuratezza" di +/- 2° C, quindi, normalmente, occorre applicare una correzione).

Guglielmo

Bjour…questo è il semplice codice per un termometro a due sonde (potrebbe essere semplicemente adattato per farne un termostato). Ancora non ho trovato nei cassetti del garage il secondo TMP ma il codice sembra girare bene.
Ciò premesso grazie a tutti voi odio il delay (del campionamento) :slight_smile: che quindi vorrei sostituire con un millis (di cuiormai sono un esperto :confused: )
Ho provato con diversi approcci a posizionare il millis nel codice (prima del loop, prima di ogni cilco di misurazione, allafine del loop) ma non sono riuscito a farlo girare in modo appropriato. Dove devo inserirlo?
Una cosa che non mi spego è perchè inviando il segnale del sensore ad entrambi i pin (A0 ed A1) mi vengono indicate due temperature diverse di circa due gradi

const int NRLETTURE = 10;    // numero letture
const int NRLETTURE2 = 10;
const int SensorPin = A0;    //variabile lettura sensore
const int SensorPin2 = A1;   // seconda variabileb sensore due
float valori[NRLETTURE];     //array con i valori
float valori2[NRLETTURE2];
int T_campionamento = 50;    // tempo campionamento
int T_campionamento2 = 50;
float sommaGradi;            //variabile somma
float mediaGradi;            //variabile media
float sommaGradi2;
float mediaGradi2;
#include <LiquidCrystal.h>             // include la libreria del display lcd
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //pin display LCD

//long previousMillis = 0;
//long interval = 50;

void setup() 
{
  lcd.begin(16, 2);        // set up the LCD's number of columns and rows:
  Serial.begin(9600);      //inizializzo la seriale
  lcd.print("Created by: ");
  lcd.setCursor(0,2);
  lcd.print("ppregeo");
  //delay(3000);
}
void loop() {
  for ( int i = 0; i<=NRLETTURE;i++)
  {
    int sensorVal = analogRead(SensorPin);
    float voltage = (sensorVal /1024.0) * 5.0; //dividendo per 1024.0 da una lettura inferiore.
    float temperature = (voltage - .5) * 100;
    //float temperature = ((sensorVal * 0.00488) - 0.5) / 0.01;
    valori[i] = temperature;
    delay(T_campionamento);

    /* int sensorVal2 = analogRead(SensorPin2);
     float voltage2 = (sensorVal2 /1024.0) * 5.0;
     float temperature2 = (voltage2 - .5) * 100;
     valori[i] = temperature2;
     delay(T_campionamento); */
  }
  sommaGradi = 0;                        // il primo valore deve essere sia zero, altrimenti poi sballa tutto
  for( int i = 0; i<=NRLETTURE; i++)     //ciclo che somma i valori dell'array
  {  
    sommaGradi = sommaGradi + valori[i];   //sommaGradi2 = sommaGradi2 + valori[i]; 
  }
  mediaGradi = sommaGradi / NRLETTURE;   //media valori
  for ( int i = 0; i<=NRLETTURE2;i++)
  {
    int sensorVal2 = analogRead(SensorPin2);
    float voltage2 = (sensorVal2 /1024.0) * 5.0;
    float temperature2 = (voltage2 - .5) * 100;
    valori[i] = temperature2;
    delay(T_campionamento2); 
  }
  sommaGradi2 = 0;
  for( int i = 0; i<=NRLETTURE2; i++)        //ciclo che somma i valori dell'array
  {  
    sommaGradi2 = sommaGradi2 + valori[i]; 
  }
  mediaGradi2 = sommaGradi2 / NRLETTURE2; //divido la somma dei valori per il loro numero (media)     
  //--------------- prova delay ---------------- 
  //    unsigned long currentMillis = millis();
  //    if (currentMillis - previousMillis > interval) {
  //    previousMillis = currentMillis;
  //    } 
  //delay(T_campionamento);
  //--------------------------------------------
  lcd.clear();                              //pulire lo schermo
  Serial.print ("Temp IN:    ");            //scrive sul display la parola "gradi"
  Serial.println (mediaGradi);
  Serial.print ("Temp OUT:   ");
  Serial.println (mediaGradi2);
  Serial.print ("diff:       ");
  Serial.println (mediaGradi-mediaGradi2);
  Serial.println ("---------------------------------------------");
  //lcd.setCursor(1,1);
  lcd.print("In ");                    
  //lcd.setCursor(4,1);                //sposto il cursore sulla seconda linea
  lcd.print(mediaGradi);               //scrivo la temperatura
  lcd.print(" d ");
  lcd.print(mediaGradi-mediaGradi2);
  lcd.setCursor(0,2);
  lcd.print("Out ");
  lcd.print(mediaGradi2);
}

…ora è perfetto. Sono due LM35 dato che non avevo due TMP35.
Ecco il codice se dovesse servire a qualcuno…anche come termostato

const int NRLETTURE = 10;    // numero letture
const int NRLETTURE2 = 10;
const int SensorPin = A0;    //variabile lettura sensore
const int SensorPin2 = A1;   // seconda variabileb sensore due
float valori[NRLETTURE];     //array con i valori
float valori2[NRLETTURE2];
int T_campionamento = 50;    // tempo campionamento
int T_campionamento2 = 50;
float sommaGradi;            //variabile somma
float mediaGradi;            //variabile media
float sommaGradi2;
float mediaGradi2;
#include <LiquidCrystal.h>             // include la libreria del display lcd
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //pin display LCD

//long previousMillis = 0;
//long interval = 50;

void setup() 
{
  lcd.begin(16, 2);        // set up the LCD's number of columns and rows:
  Serial.begin(9600);      //inizializzo la seriale
  lcd.print("Created by: ");
  lcd.setCursor(0,2);
  lcd.print("ppregeo");
  //delay(3000);
}
void loop() {
  for ( int i = 0; i<=NRLETTURE;i++)
  {
    int sensorVal = analogRead(SensorPin);
    //float voltage = (sensorVal /1024.0) * 5.0; //dividendo per 1024.0 da una lettura inferiore.
    //float temperature = (voltage - .5) * 100;
    float temperature = (sensorVal * 4.88)/10;
    valori[i] = temperature;
    delay(T_campionamento);

    /* int sensorVal2 = analogRead(SensorPin2);
     float voltage2 = (sensorVal2 /1024.0) * 5.0;
     float temperature2 = (voltage2 - .5) * 100;
     valori[i] = temperature2;
     delay(T_campionamento); */
  }
  sommaGradi = 0;                        // il primo valore deve essere sia zero, altrimenti poi sballa tutto
  for( int i = 0; i<=NRLETTURE; i++)     //ciclo che somma i valori dell'array
  {  
    sommaGradi = sommaGradi + valori[i];   //sommaGradi2 = sommaGradi2 + valori[i]; 
  }
  mediaGradi = sommaGradi / NRLETTURE;   //media valori
  for ( int i = 0; i<=NRLETTURE2;i++)
  {
    int sensorVal2 = analogRead(SensorPin2);
    //float voltage2 = (sensorVal2 /1024.0) * 5.0;
    //float temperature2 = (voltage2 - .5) * 100;
    float temperature2 = (sensorVal2 * 4.88)/10;
    valori2[i] = temperature2;
    delay(T_campionamento2); 
  }
  sommaGradi2 = 0;
  for( int i = 0; i<=NRLETTURE2; i++)        //ciclo che somma i valori dell'array
  {  
    sommaGradi2 = sommaGradi2 + valori[i]; 
  }
  mediaGradi2 = sommaGradi2 / NRLETTURE2; //divido la somma dei valori per il loro numero (media)     
  //--------------- prova delay ---------------- 
  //    unsigned long currentMillis = millis();
  //    if (currentMillis - previousMillis > interval) {
  //    previousMillis = currentMillis;
  //    } 
  //delay(T_campionamento);
  //--------------------------------------------
  lcd.clear();                              //pulire lo schermo
  Serial.print ("Temp IN:    ");            //scrive sul display la parola "gradi"
  Serial.println (mediaGradi);
  Serial.print ("Temp OUT:   ");
  Serial.println (mediaGradi2);
  Serial.print ("diff:       ");
  Serial.println (mediaGradi-mediaGradi2);
  Serial.println ("---------------------------------------------");
  //lcd.setCursor(1,1);
  lcd.print("In ");                    
  //lcd.setCursor(4,1);                //sposto il cursore sulla seconda linea
  lcd.print(mediaGradi);               //scrivo la temperatura
  lcd.print(" d ");
  lcd.print(mediaGradi-mediaGradi2);
  lcd.setCursor(0,2);
  lcd.print("Out ");
  lcd.print(mediaGradi2);
}

Mi sembra un po' ... prolisso e spreca memoria ...

Cosa salvi a fare le letture in un vettore? :o Sommale ad ogni lettura della temperatura e alla fine dividi per il numero di letture.

Ricordati una lettura a vuoto ogni volta che passi da un pin analogico ad un altro ...

Guglielmo

Grazie Guglielmo. Proverò a modificare il codice come da te suggerito. Mi sono reso conto che in effetti spreca memoria…
Pe la lettura a vuoto ho cercato ma non ho trovato nulla.

vince59: Grazie Guglielmo. Proverò a modificare il codice come da te suggerito. Mi sono reso conto che in effetti spreca memoria...

... ricordati che esiste l'operatore += che fa la somma ed assegna assieme ;)

vince59: Pe la lettura a vuoto ho cercato ma non ho trovato nulla.

... credo fosse nel datasheet o in qualche application note. Tu comunque, ogni volta che passi da un canale all'altro, fai semplicemente una analogRead() del nuovo canale a vuoto (senza assegnarla a nulla) e poi inizi il tuo FOR di N letture.

Guglielmo

Guglielmo, puoi per favore darmi qualche indicazione su come "ricostruire" il codice utulizzando l'operatore +=. NOn mi è chiaro come va costruito... grazie

A = A+2;

A+=2;

Sono equivalenti.
Non c’é bisogno di ripetere la variabile una seconda volta.

Ciao Uwe