Sensore di temperatura TMP36 e imprecisione

Ciao.Ho costruito un semplice termometro a semaforo utilizzando arduino micro e un sensore di temperatura TMP36. So che questo sensore non è particolarmente preciso,e ho quindi creato un ponticello tra il pin 3V3 e AREF per aumentare la precisione.Ho seguito una guida online. Quando vado a guardare il monitor seriale ,in una stanza dove ho 27 gradi misurati con termometro a mercurio,il sensore segna più di 32 gradi. Addirittura 5 gradi di imprecisione.Non è troppo? Inizia segnando una temperatura di 28,5 circa,che è assolutamente accettabile,per poi salire gradualmente durante la lettura a monitor.
Sto alimentando arduino con una porta usb del pc che eroga 5.09 volt,non so quanto può c'entrare.

Vi allego comunque il codice ,dovrebbe essere giusto.

void setup() {

  Serial.begin(9600);

  pinMode ( 7 , OUTPUT ); // rosso
  pinMode ( 19 , OUTPUT ); // arancione
  pinMode ( 4 , OUTPUT ); // verde
  

  digitalWrite ( 7, LOW );
  digitalWrite ( 4, LOW );
  digitalWrite ( 19, LOW );

  analogReference (EXTERNAL);

}

void loop() {

   delay(500);
  
  int val_Adc = 0;

  float temp = 0;

  for(byte ciclo = 0; ciclo < 100 ; ciclo ++)
  {
    val_Adc += analogRead(5);

    delay(10);
  }

  val_Adc /= 100;

  temp = ((val_Adc * 0.0032)-0.5)/0.01;
    
  Serial.print(temp);
  Serial.println(" gradi");

  if (temp < 25 ) // temperatura minore di 25°
    
  {   
   
   digitalWrite(7,LOW);
   digitalWrite(19,LOW);
   digitalWrite(4,HIGH);
   
  }
  
  else if (temp > 25 && temp < 34 ) // se la temperatura è compresa tra 25° e 34°
    
  {
    
   digitalWrite(7,LOW);
   digitalWrite(19,HIGH);
   digitalWrite(4,LOW);
    
  }
  
  else if (temp > 34 ) // temperatura di almeno 35°
    
  {
   
   digitalWrite(7,HIGH);
   digitalWrite(19,LOW);
   digitalWrite(4,LOW);
   
  }

  
   delay(1);
   

}

Qual è la tensione di uscita del sensore TMP36?

Utilizzare la formula riportata nella scheda tecnica e verificare che la tensione di uscita corrisponda alla temperatura in quell'istante.

Vo = 10mV/°C × T + 500mV

Qual è il valore ADC mostrato?

Controllerei anche il circuito, la parte hardware, perche' se sale gradualmente, potrebbe essere dovuto al fatto che si scalda lui stesso mentre funziona ... posta lo schema con i valori dei componenti.

La corrente di uscita del TMP36, ad esempio, non dovrebbe mai superare i 50uA, meglio se meno.

Usa un tipo dati adeguato per la variabile che dovrà contenere la somma delle letture analogiche come ad esempio unsigned long o float

Un int ti consente di accumulare valori positivi fino a 2^16/2 = 32768 , ma con una media di 100 letture ci vuole poco a superare questo valore ed andare in overflow.

@belmont1591 allora , a una temperatura di 29,5° misurata ho 0,8V di uscita sul sensore.

@cotestatnt Ho sostituito int con unsigned long e float,ma la misurazione rimane sballata.

L'ho fatto così. Ma nella realtà ho messo arduino dentro una scatoletta di plastica piccola, alla quale ho fatto 3 forellini per infilare i piedini del sensore. Il piedino a 5 volt è saldato direttamente su arduino, così come quello centrale. Il GND invece ha un piccolo filo che raggiunge il pin.
Non so, che riesca a scaldare data la vicinanza ad arduino? Ma il sensore in sé rimane comunque fuori dalla scatolina. Adesso mi hai fatto venire il dubbio. Tempo fa avevo creato un altro termometro, ma siccome era diversa la struttura ho portato il sensore fuori, lontano da arduino e non ho avuto problemi. La temperatura era molto simile a quella reale.

Secondo il datasheet:

la TMP36 fornisce 750mV a 25°C, con un incremento di 10mV/°C.
Con un riferimento a Vref, 750mV corrispondono a una lettura di
0,75/Vref*1024 = 768/Vref.
A 0°C si hanno 500mV (0,75-25*0,01=0,5), perciò
0,5/Vref*1024 = 512/Vref.
Ogni incremento di 1°C produrrà un incremento della lettura di:
0,01/Vref*1024 = 10,24/Vref.
Quindi:
temp=(analogRead(5)-512/Vref)/(10.24/Vref);
che è una semplificazione della formula da te usata.

float temp;
float Vref=1.100; // <<<<<<< Inserire il valore esatto di Vref misurato in Volt.
float deltaV_1grado=10.24/Vref;
uint32_t t_lett; // Per la lettura una volta al secondo.

void setup() 
{
  analogReference (INTERNAL); // Riferimento interno di Arduino Uno a 1,1V +/-10%.
  pinMode (7, OUTPUT); // rosso
  pinMode (19, OUTPUT); // arancione
  pinMode (4, OUTPUT); // verde
  Serial.begin(9600);
  analogRead(A5); // Scartiamo la prima lettura sull'ingresso A5.
}

void loop() 
{ 
  if(millis()-t_lett>999) // Una volta al secondo:
  {
    t_lett=millis();
    temp = (analogRead(5)-512.0/Vref) / deltaV_1grado;
    Serial.print(temp); Serial.println(" gradi");
    if (temp<25) // temperatura minore di 25°
    {   
       digitalWrite(7,LOW);
       digitalWrite(19,LOW);
       digitalWrite(4,HIGH); // Verde.
    }
    else if (temp>=25 && temp<34) // se la temperatura è compresa tra 25° e 34°
    {
       digitalWrite(7,LOW);
       digitalWrite(19,HIGH); // Arancione.
       digitalWrite(4,LOW);
    }
    else if (temp>=34) // temperatura di almeno 35°
    {
       digitalWrite(7,HIGH); // Rosso.
       digitalWrite(19,LOW);
       digitalWrite(4,LOW);
    }
  }
}

Il tuo codice, comunque, è corretto nei calcoli.

Prova anche la DS18B20, che esce in digitale risparmiandoti i calcoli e la dipendenza dalla stabilità della tensione di riferimento.

@Datman Ti ringrazio per tutto. Quindi secondo te la causa non è la vicinanza della scheda arduino o il fatto che si riscalda.
Appena torno a casa provo il codice e vedo come va.
Del DS18B20 ho letto qualcosa tempo fa,ma alla fine avevo un TMP36 in più e l'ho utilizzato. Ho visto che c'è la tipologia a sonda e anche a sensore come il TMP36. Tu quale intendi dei due?

Del DS18B20 trovi la versione in TO92, come un transistor, e quella incapsulata con il cavo a doppio isolamento che esce. Se non devi usarlo in immersione o in ambienti particolarmente umidi, puoi usare quello in TO92, che è più economico e ha una risposta più veloce.

Comunque anche il TMP36 deve funzionare...

Se decidi di passare nel dominio dei sensori digitali, ci sono sensori molto più "performanti" del DS18B20 in grado di darti anche una misura di diverse grandezze fisiche.
Ad esempio un Bosch BME280 può restituirti temperatura, umidità, pressione atmosferica e in modo indiretto anche l'altitudine (calcolando la differenza rispetto alla pressione atmosferica sul livello del mare).

Chiaramente dipende tutto dalla tua applicazione e da quali sono le esigenze, quindi prendila solo come un'informazione fine a se stessa.

Comunque vada, anche io sono dell'idea che il TMP36 deve funzionare.
Prova a semplificare lo sketch rimuovendo la media aritmetica e stampando tutti i valori intermedi dei calcoli effettuati: valore analogico, differenza di potenziale corrispondente e quindi il valore in temperatura calcolato.

Bisogna anche vedere quanto è preciso il 3v3 (o anche lo 1.1 se è per questo)

A 29.5 gradi, ammesso un errore di misura anche sul termometro campione, la tensione di 800 mV è accettabile

Magari è il 3v3 che sbarella
Considera che si tratta di un alimentatore, non di una sorgente di riferimento

Anche 1v1 in sé è stabile nel tempo, ma non preciso e serve di calibrare il programma

Sì, gli 1,1V sono molto stabili, ma con una accuratezza del +/-10%, quindi va fatta una taratura con un termometro campione o almeno con un buon multimetro digitale.

A maggior ragione pensa al 3v3
Inaccurato E instabile
Quindi....

Ho aggiornato il programma per inserire il valore esatto di Vref (1,1V nominali o altro stabile), dopo averlo misurato.

ma il 3v3 ponticellato con AREF in realtà non veniva usato per aumentare la precisione?

@Datman quindi il vref devo misurarlo da GND e piedino centrale del sensore?

Bisogna vedere se è stabile... Se non c'è nulla collegato, dovrebbe essere più stabile dei 5V da cui deriva.
Vref va misurato fra "Vref" e massa.

@Datman quindi tra AREF e massa? Li ho 3,3 volt

So che li hai, ma sono 3,300V stabili?

Stabili,non varia nemmeno di 0,1.Sto misurando AREF e massa dove ho collegato anche GND del sensore. Invece tra A5 e la stessa massa ho 0,80 - 0,82 volt. Cosa inserisco quindi in Vref a inizio codice?

100mV di variazione su 3,3V su Aref producono una variazione della temperatura misurata di oltre 3°C.
TMP36.zip (6.3 KB)