Leggere la temperatura!

Ciao a tutti, oggi mi è arrivata la breadboard quindi ho buttato subito su il mio LM35DZ e ho scritto un pò di codice per leggere e convertire il tutto in gradi centigradi.

vi posto il codice per commentarlo insieme (sono alle prime armi) e capire se ho sbagliato qualcosa

int value; 
float temp;
void setup() {
Serial.begin(9600);

}

void loop()
{
 value = analogRead(A0);
 delay (1000);
 
temp = (value*4.88)/10;

Serial.println (temp); 
}

Allora ho ragionato così:

La variabile value la prendo int, tanto sarà sicuramente un numero intero compreso tra 0 1024
La variabile temp la prendo float perchè dopo aver eseguito i calcoli avrò un numero con la virgola

Leggo il mio ingresso con la cadenza di 1s, prendo il valore che vedo sull'ingresso e lo moltiplico per 5/1024 quindi ottengo la mia lettura in V, per passarla a mV moltiplico il valore per 1000 e ottengo 4,88.
Il sensore mi restituisce 10mV per ogni grado centigrado, quindi divido il mio risultato in mV per dieci ottenendo la mia temperatura in gradi centigradi.

I valori che vedo nella mia camera sono di circa 18.5 gradi, prossimi alla realtà ma non ho un termometro per fare la prova del 9 :confused:

Vedete qualcosa di strano? ho sbagliato qualcosa?
Illuminatemi! :grinning: :grinning:

Il ragionamento è corretto, però:

  • Non è detto che il riferimento siano esattamente 5.0V, dovresti usare il Secret Voltmeter per misurare effettivamente la tensione di alimentazione (che è la stessa di fondo scala dell'ADC, di default).
  • Il delay() lo metterei in fondo, almeno vedi subito il valore letto e processato.
  • Per diminuire gli errori di lettura dovresti leggere un tot di volte e fare la media.

SukkoPera:
Il ragionamento è corretto, però:

  • Non è detto che il riferimento siano esattamente 5.0V, dovresti usare il Secret Voltmeter per misurare effettivamente la tensione di alimentazione (che è la stessa di fondo scala dell'ADC, di default).
  • Il delay() lo metterei in fondo, almeno vedi subito il valore letto e processato.
  • Per diminuire gli errori di lettura dovresti leggere un tot di volte e fare la media.

Perfetto, più tardi applicherò le modifiche e vedremo che succede :smiley:

potresti usare la funzione modificata di map() che restituisce float, e usare direttamente i valori analogici da 0 a 1023.

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}


void loop(){
     ...
     ...
     ...
     float tmp=mapfloat(valoreLetto,0,1023,0,500);



}

Ciao!!!

Ho provato a fare la media, ci sono mooolte cose a me non chiare, posto il programmino e lo commentiamo insieme magari :slight_smile:

#define Num_Letture 10
 int Letture [Num_Letture]; 
 int Lett_Corr = 0;
 int Tot_Lett = 0;
 int Lett_Media = 0;

void setup() {
Serial.begin(9600);
for (int i = 0; i < Num_Letture; i++) 
Letture[i] = 0;
}

void loop() {
 Tot_Lett = Tot_Lett - Letture[Lett_Corr];
 Letture[Lett_Corr]= analogRead(A0);
 Tot_Lett= Tot_Lett + Letture[Lett_Corr];
 Lett_Corr = (Lett_Corr + 1);

 if (Lett_Corr >= Num_Letture) 
  Lett_Corr = 0;



 Lett_Media=Tot_Lett / Num_Letture;
 Serial.println (Lett_Media);   
}

ho preso spunto da internet,alcune cose non mi sono chiare.

Allora, definisco 10 come numero di letture,
definisco un insieme di valori in int:
letture = numero letture
lettura corrente = 0
lettura totale = 0
lettura media = 0

nel setup non mi è chiaro quella condizione in IF, non ho capito a cosa mi serve.

Nel loop vengono eseguiti i calcoli , ma non riesco a capire come inserire un ritardo tra una lettura ed un altra, tipo vorrei campionare una lettura ogni 200ms, quindi la media totale mi deve essere restituita dopo 2 secondi.
Quello che vorrei ottenere è fare la media di 10 valori campionati ongi 200ms o anche 100ms, in modo da avere il mio valore medio ogni 1s o 2s, poi resettare e iniziare da capo.

Ma, secondo me non ti serve un array per il calcolo della media, puoi trovare esempi online di media di numeri. Con un delay(200) ripetuto 10 volte, ottieni la stampa dei valori dopo 2 secondi.

Spero che tu non ti offenda, ma ti mostro un esempio...

nt valoriLetti=0;
int contatore=0;
float media=0;

void loop(){


        valoriLetti+=analogRead(pin);// equivale a valoriLetti=valoriLetti + nuovo valore
        contatore++; //aumento di uno
        delay(200);

       if(contatore>=10){// dopo dieci letture e trascorsi 2 secondi
          
               media=valoriLetti/10;
               Serial.println(media);
               
               /*azzero per nuova media */
               contatore=0;
               valoriLetti=0;
      }




}

Mai usare il delay se si puo' evitare, visto che forse deve fare altre cose oltre a leggere la temperatura

#define Num_Letture 10
int Letture [Num_Letture];
int Lett_Corr = 0;
int Tot_Lett = 0;
int Lett_Media = 0;
unsigned long previousMillis = 0;
unsigned long currentMillis ;
const long intervallo = 200; // intervallo in millisecondi

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < Num_Letture; i++)
    Letture[i] = 0;
}

void loop() {
  // inserire qui altro codice a piacere

  currentMillis = millis();
  if (currentMillis - previousMillis >= intervallo ) {
    previousMillis = currentMillis;
    Letture[Lett_Corr] = analogRead(A0);
    Tot_Lett = Tot_Lett + Letture[Lett_Corr];
    Lett_Corr ++ ; // incrementa il conteggio delle letture
  }

  if (Lett_Corr >= Num_Letture) {
    Lett_Media = Tot_Lett / Num_Letture;
    Serial.println (Lett_Media);
    Lett_Corr = 0;
    Tot_Lett = 0 ;
  }
}

torn24:
Ma, secondo me non ti serve un array per il calcolo della media, puoi trovare esempi online di media di numeri. Con un delay(200) ripetuto 10 volte, ottieni la stampa dei valori dopo 2 secondi.

Spero che tu non ti offenda, ma ti mostro un esempio...

nt valoriLetti=0;

int contatore=0;
float media=0;

void loop(){

valoriLetti+=analogRead(pin);// equivale a valoriLetti=valoriLetti + nuovo valore
        contatore++; //aumento di uno
        delay(200);

if(contatore>=10){// dopo dieci letture e trascorsi 2 secondi
         
              media=valoriLetti/10;
              Serial.println(media);
             
              /*azzero per nuova media */
              contatore=0;
              valoriLetti=0;
      }

}

grazie a tutti per le risposte, Torn24 mi hai illuminato, era proprio quello che volevo. Semplice da capire ed efficace, ecco come ho strutturato il programma

int val_letti = 0;
int contatore = 0;
float media = 0;
float temp = 0;

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

void loop() {
  val_letti = val_letti + analogRead(A0);
  contatore++;

  delay(200);

  if (contatore >= 10){
     media = val_letti / 10;
     temp = (media * 4.88) / 10 ;
     Serial.print (temp);
     contatore = 0;
     val_letti = 0;
     media=0;
}
}

Ho pensato di azzerare anche la media :slight_smile: