Valori sballati da sensore temperatura

Buongiorno,

mi è arrivato pochi giorni fa lo starter kit con Arduino Uno e finora, per mancanza di tempo e per inesperienza, mi sto limitando a fare qualcosa dei programmi già presenti sul manuale. Il problema è sorto quando per la prima volta ho provato ad usare il sensore di temperatura incluso nel kit. Mandando sul monitor seriale i valori dell'analogRead (non le temperature, mi interessava solo vedere i valori provenienti dall'ADC, prima di calibrare il sensore sulla temperatura) ho visto che, con un delay di 1 secondo, venivano fuori numeri molto sballati. Io non mi aspettavo numeri sempre costanti ma i valori oscillavano di diverse decine e soprattutto ogni volta che facevo rigirare il programma dall'inizio mi uscivano valori diversi. Ora chiedo, è normale una tale imprecisione? Forse sono io che, non conoscendo bene l'elettronica, non so gestirla. Aspetto vostri preziosi chiarimenti. :)

Fai prima la conversione in temperatura, solo dopo puoi capire se ... i valori sballano veramente così tanto o se, un volta convertiti in temperatura, rientrano nel normale errore di precisione del sensore (se ti va bene ed hai un sensore abbastanza buono +/- 0.5 gradi , se ti va male ed il sensore non è un gran che, anche +/- 2 gradi ;) )

Guglielmo

Dato che si tratta di un work in progress, nel frattempo ho anche scritto il codice per la conversione. Ho usato le conversioni date dal manuale dato che credo siano quelle riportate da datasheet. Ora I valori sballano di qualche grado, anche se la cosa anomala è che non è che oscillano attorno ad una presunta media ma fanno magari una decina di secondi costanti, poi scendono di anche o 6 gradi e poi tornano su in eccesso. Insomma sarebbe un sensore precisissimo se mi spostassi su e giù da casa e cantina :) ma visto che sono inchiodato sul divano non mi spiego queste modulazioni. La cosa che tuttora non mi convince (tollerato il fatto che un sensore, seppur rudimentale, possa dare tutto questo errore) è perchè ogni volta che faccio girare da 0 il programma, è come se i valori shiftassero casualmente. L'oscillazione di lungo periodo rimane, solo che una volta è sui 20 gradi, un altra intorno allo 0... è una cosa che, con le conoscenze scarse che ho, non riesco a spiegarmi...

Ok, a questo punto servono due cose : XD

  1. Modello del sensore che stai usando e link a dove lo hai comprato

  2. copia qui il programma che hai scritto (...cortesemente racchiudilo tra i tag CODE ... sono quelli che quando sei in edit ti mette il bottone # che si trova come terzultimo della seconda fila).

Guglielmo

Grazie per l'interessamento! :P ecco il codice:

const int sensorPin=A0;
const int led=4;

void setup ()
{
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

void loop ()
{
  int sensorVal;
  float voltage, temperature;
  
  sensorVal=analogRead(sensorPin);
  voltage=(sensorVal/1024.0)*5.0;
  temperature=(voltage-0.5)*100;
  
  Serial.print("Valore: ");
  Serial.print(sensorVal);
  Serial.print("Temperatura: ");
  Serial.print(temperature);
  Serial.print("\n");
  
  if (sensorVal>140)
  {
    digitalWrite(led, HIGH);
  }
  delay(1000);
  digitalWrite(led,LOW);
}

Come dicevo le conversioni sono proprio riportate da manuale visto che non avevo necessità di uno studio approfondito...

per quanto riguarda il sensore è quello incluso nello starter kit (TMP 36GZ). Come dicevo so che non è certo un apparecchiatura sofisticata, infatti il problema è nato solo perchè stavo "giochicchiando" col kit, non ho certo intenzione di costruirci un termometro di precisione :) solo che mi chiedevo come fosse possibile che dei componenti, seppur scadenti ma comunque compresi in un prodotto ufficiale, fossero così inefficienti oppure se sono io che sbaglio qualcosa...

Mmm ... prova nel setup ad inserire anche la riga :

pinMode(sensorPin, INPUT);

così dichiari correttamente quel pin in INPUT, per il resto ... se i collegamenti sono giusti e la formula è quella ... non vedo particolari errori ... :roll_eyes:

Guglielmo

P.S. : vero che cambiando l'ordine dei fattori il risultato non cambia, ma logica vorrebbe che prendi i 5v li dividi in 1024 passi e moltiplichi per il valore letto : :)

voltage = 5.0 / 1023.0 * (float) sensorVal;

Se deve leggere un pin come analogico, non importa dichiararlo come input: ci pensa l'analogRead, nel core, ad agganciare il pin al mux analogico.

Casomai potrebbe fare un semplicissimo Serial.println(analogRead(sensorPin)) per vedere se viene letto correttamente qualcosa oppure no.

leo72: Se deve leggere un pin come analogico, non importa dichiararlo come input: ci pensa l'analogRead, nel core, ad agganciare il pin al mux analogico.

Yes, I know, but ... meglio educare gli utenti a fare le cose per bene ;)

leo72: Casomai potrebbe fare un semplicissimo Serial.println(analogRead(sensorPin)) per vedere se viene letto correttamente qualcosa oppure no.

Al primo post ha appunto detto di aver fatto questa prova e di leggere dei valori piuttosto oscillanti ... ;)

Guglielmo

gpb01: Al primo post ha appunto detto di aver fatto questa prova e di leggere dei valori piuttosto oscillanti ... ;)

Ops... non ci avevo fatto caso.

@inshallo: Una domanda stupida, alimenti qualcos'altro, oltre a quel sensore, con l'Arduino? Per esperienza personale, posso dirti che questi sensori sentono anche oscillazioni minime sull'alimentazione. Fai anche una decina di letture sequenziali del sensore, facendo poi la media: questo aiuta l'ADC nella lettura.

Grazie ad entrambi per le risposte! :P

Come dicevo all'inizio ho provato a fare solo la lettura del pin (sapendo anche di fatto poi era solo una questione di proporzioni) e già da lì i valori mi sembravano fasulli. Giustamente Guglielmo mi ha consigliato di scrivere comunque le temperature, (credo) poichè magari un errore visibile dalla lettura analogica potrebbe aver avuto minor impatto sul conto della temperatura.

Riguardo al conto concordo anche io sul suo consiglio di mettere i fattori al contrario. Sul manuale la riportava così e io ho pensato che potesse avere una sua motivazione. Il mio dubbio era legato ad una propagazione degli errori. Da quello che so io un calcolatore effettua le moltiplicazioni nell'ordine in cui sono scritte e applica dei troncamenti ai decimali entro i limiti del numero di bit che ha a disposizione. Io ho pensato che, facendo 5/1024*5, il troncamento decimale della prima divisione fosse stato più influente che non dividere sensorVal/1024 (considerando che sensorVal è c.a. 150...). Comunque questa è stata una mia supposizione a posteriori per giustificare quanto scritto nel manuale. Se voi esperti mi dite che è preferibile l'approccio logico che è più chiaro e non influisce sul risultato, eseguo umilmente XD

Riguardo all'inizializzazione del pin analogico davvero ammetto la mia ignoranza, pensavo fosse implicito trattandosi di analogico. Grazie del consiglio, la prossima volta inizializzo tuuutto :)

Scusi Leo, non avevo visto la sua domanda. Al momento della prova l'unica cosa che c'era oltre al sensore era un led che avvisava quando l'analogRead saliva sopra un certo valore. L'ho messo per provare a farlo accendere quando si toccava il sensore. Dice che questo potrebbe influire sulle letture? Perchè se fosse così mi verrebbero dei dubbi. Come ho già scritto in un altro post un mio progetto futuro era quello di fare un datalogger con alcuni sensori. Non una centrale nucleare ma almeno 4 o 5 sensori. Se lei mi dice che già con un led può sballarsi tutto, con altri quattro sensori può succedere che una cella di carico mi indica la temperatura e un barometro mi segnala la radiazione incidente sull'apparecchio? XD

Inshallo94:
Scusi Leo, non avevo visto la sua domanda. Al momento della prova l’unica cosa che c’era oltre al sensore era un led che avvisava quando l’analogRead saliva sopra un certo valore.

No, no, tranquillo … Leo parlava di carichi che comunque possono influenzare, anche se minimamente, l’alimentazione … es. un motorino, un servo, … non un piccolo LED :slight_smile:

Invece è ottima l’idea di Leo di fare la media di una serie di letture … vedi se il risultato è più stabile … :slight_smile:

Guglielmo

Ah per fortuna... mi stava per crollare tutta la fiducia riposta in Arduino :) detto questo mi sembra un ottima idea un campionamento mediato, grazie della dritta! Domani provo a riprendere il tutto che ora non posso e vi faccio sapere. Tuttavia la mia più grande perplessità rimane: con le medie posso arginare le oscillazioni momentanee durante l'esecuzione, anche se certo mi sembra comunque strano visto che come dicevo i valori non sono tipo variabili attorno ad una media ma oscillanti a "gruppi". Ma come è possibile che spegnendo e riaccendendo l'Arduino è come se la taratura si spostasse di qualche decina di passi?

Puoi mettere un piccolo schema dei collegamenti elettrici che hai fatto ? Magari aiuta ... ;)

Guglielmo

Edit : Hai guardato il datasheet ?

A pagina 10 c'è uno schemino con un condensatore e dice chiaramente :

"Note the 0.1 ?F bypass capacitor on the input. This capacitor should be a ceramic type, have very short leads (surface-mount is preferable), and be located as close as possible in physical proximity to the temperature sensor supply pin. Because these temperature sensors operate on very little supply current and may be exposed to very hostile electrical environments, it is important to minimize the effects of radio frequency interference (RFI) on these devices. The effect of RFI on these temperature sensors specifically and on analog ICs in general [u]is manifested as abnormal dc shifts in the output voltage[/u] due to the rectification of the high frequency ambient noise by the IC. When the devices are operated in the presence of high frequency radiated or conducted noise, a large value tantalum capacitor (±2.2 ?F) placed across the 0.1 ?F ceramic capacitor may offer additional noise immunity."

Ho anche trovato QUESTA vecchia discussione in cui PaoloP fa delle interessanti considerazioni su quel sensore e da anche una formula di calcolo corretta e che lavora direttamente in milliVolt.

Dai una letta veloce alla prima pagina ... alla fine della quale mi sembra tutto funzioni ;)

Guglielmo

Buonasera a tutti!

Ho seguito i vostri consigli. In particolare ho messo in parallelo all’ingresso il condensatore e modificato il codice e con la media delle temperature e con la formula letta sull’altro post. Premetto che ho spudoratamente copiato tale formula poichè in questi giorni (esami… sigh…) purtroppo il tempo per leggere il datasheet e ricavarmi da me le formule non è molto. :~ Ecco il codice:

const int sensorPin=A0;

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

void loop ()
{
  int sensorVal,i=0;
  float temperature,somma=0,media=0;
  
  for (i=0;i<10;i++)
  {
    sensorVal=analogRead(sensorPin);
    temperature=sensorVal*0.4883-50;
    somma=somma+temperature;
    delay(10);
  }
  
  media=somma/10;
  Serial.print("Temperatura: ");
  Serial.print(media);
  Serial.print("\n");
  
  delay(1000);
 
}

Questa volta i risultati credo siano migliori anche se permane un problema. All’inizio i valori erano intorno alla 20ina di gradi, perfettamente compatibili con la reale temperatura. Poi sono scesi di 5 gradi per stabilizzarsi sui 15. La cosa positiva è che almeno ora rimangono costanti anche nel lungo periodo! :slight_smile: Forse erano proprio errori dovuti alle oscillazioni di corrente modulate dal condensatore. In teoria, e ripeto in teoria, ora dovrebbe essere solo un problema di taratura… o almeno spero :slight_smile:

PS: purtroppo mi è difficile illustrare i collegamento con il software apposito visto che non l’ho ancora scaricato e come dicevo il tempo è molto poco. Cmq sostanzialmente non ho fatto altro che aggiungere il condensatore tra la terra e il Vin del sensore…