Media Valori TMP36

Ciao,
Sto creando un termometro con un display e un sensore TMP36.
La lettura della temperatura con un intervallo di 1 secondo viene eseguita correttamente ma quando cerco di fare una media di 8 misure il valore che leggo dal terminate e completamente errato (oltre i 200).

#include <LiquidCrystal.h>
#define rs 12
#define en 11
#define d4 5
#define d5 4
#define d6 3
#define d7 2
#define LED 13

int sensorPin = 0;
float temp = 0;
int misure[8];
int i;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


void setup() {
  
  Serial.begin(9600);
 
   
  lcd.begin(16, 2);
  pinMode (LED, OUTPUT);

}

void loop() 
{
  for(int i=0;i<=7;i++);{
  
  sensorPin = analogRead(0);
  
  misure[i] = (0.488 * sensorPin - 50);
  temp = temp + misure[i];
}

  temp = temp/8.0;
  Serial.println(temp);
  delay(1000);
  

}

Lo sketch attualmente è incompleto; cerco di affrontare un problema alla volta.

Qualcuno potrebbe aiutarmi a capire dove sbaglio?
Scusatemi sono un neofito di Arduino e forse sarò un po' duro di comprendonio.

Grazie

A parte l'uso dell'array che così è inutile, il problema è che non azzeri mai la variabile temp. Metti un temp = 0; prima del for e vedi se migliora.

probabilmente dovresti inserire anche un ritardo tra una lettura e un'altra nel ciclo for. Come detto prima l'array non ha senso.

Nonostante @fratt e @nello791 abbiano ragione verificate la connessione e lo stato del tmp36 perchè quel codice funziona correttamente e non dà mai valori così alti. Il codice non è il problema.
Il sensore si surriscalda?
Saluti.

Se al codice tolgo la funzione che fa la media di 8 valori il terminale mi dà i valori corretti. Ecco perché ho pensato che il problema fosse lo sketch. Ho provato anche le soluzioni precedenti ma non ho risolto. Forse non ho capito bene come usare i cicli for.

Grazie

Sei sicuro che senza la media funziona?
Ho notato solo adesso che fai la lettura sul pin 0... e non credo vada bene.
Devi usare uno dei pin da A0 a A5.
E aggiungi l'azzeramento della variabile prima del for.
E verifica che il TMP sia collegato correttamente.
E se riesci posta uno schema di come hai collegato il tutto.

Non è quello il problema, analogRead() può funzionare anche indicando il canale da leggere (es. 0 invece di A0):

int analogRead(uint8_t pin)
{
        uint8_t low, high;

#if defined(analogPinToChannel)
#if defined(__AVR_ATmega32U4__)
        if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#endif
[etc...]

Come già più volte detto l'array è inutile di per se, tanto più che è un array di int in cui si cerca di salvare un float.

Ciao, Ale.

Quando si effettua una lettura analogica, l'ottimizzatore IDE comprende che si riferisce alla porta A0 ed esegue la conversione automaticamente. Ma penso come dovresti affermarlo per chiarezza e comprensione.

@ilguargua e @gonpezzi grazie della spiegazione, non lo sapevo.

Se volete avere una funzione che esegue una buona media vi consiglio di tradurre con google e leggere la pagina seguente: LINK
Saluti.

Per verificare l'integrità del circuito ho provato questo sketch:

//variabili globali
int val_Adc = 0;
float temp = 0;

void setup()
{
  Serial.begin(9600);  //init seriale
}

void loop()
{
  
  val_Adc = analogRead(0);  //leggo dalla porta A0
                            
                            
  temp = ((val_Adc * 0.00488) - 0.5) / 0.01;//converto il segnale acquisito 
                                            //in un valore espresso in gradi 
                                            //centigradi invio il dato sulla
                                            //seriale
  Serial.println(temp);
  
  delay(500);  //ritardo di mezzo secondo
}

Tutto funziona correttamente. Qualcuno mi può indirizzare a qualche sito dove spiegano o danno qualche esempio per fare la media dei valori letti da una qualsiasi sonda. Scusatemi ma sono un neofita di Arduino e forse ho bisogno di entrare nei meccanismi un po' alla volta.

Ci sono vari modi per fare la stessa cosa.
Questo è uno dei tanti. Vedi se funziona (non l'ho provato) e se capisci come funziona.

#define PINTEMP A0  // definisco il pin del sensore

//variabili globali
int val_Adc = 0; //valore letto
float temp = 0;  // temperatura
float media = 0; // media
byte conta = 0;  // contatore letture
const float massimo = 8.0;  // numero di valori su cui fare la media

void setup()
{
  Serial.begin(9600);  //init seriale
}

void loop()
{
  
  val_Adc = analogRead(PINTEMP);  //leggo dalla porta A0
  delay(10);  //ritardo tra una lettura e la successiva
                            
  temp = ((val_Adc * 0.00488) - 0.5) / 0.01;//converto il segnale acquisito 
                                            //in un valore espresso in gradi 
                                            //centigradi
  media += temp; // aggiungo la temperatura appena letta alla media

  conta++; // aumento il contatore

  // controllo se sono arrivato al numero che mi serve
  if (conta >= massimo) {

    media /= massimo; // calcolo la media

    Serial.println(media);  // stampo la media

    conta = 0; // azzero il contatore
    media = 0; // azzero la media
    
    delay(500);  //ritardo di mezzo secondo
  }
}

Ripeto quanto detto nel post #4, quel codice funziona ma contiene un piccolo e sanguinoso piccolo errore nascosto che dopo vani tentativi di ricreare un nuovo codice finalmente è venuto alla luce.

Quell'errore è senza dubbio quello che ti ha dato problemi con il for e sicuramente di dichiarare la variabile "i" due volte, sia all'inizio come globale che all'interno del for come locale e con questo rispondo al tuo post #5.
Nella tua dichiarazione for:

 for(int i=0;i<=7;i++)**;**{

Cosa diavolo fa quel ";" dipinge?. :face_with_symbols_over_mouth:Toglilo!
In questo modo funzionerà correttamente, anche se non capisco perché salvi i valori in una matrice se non li leggi in seguito.

Togliendo questo e seguendo i consigli di @fratt e @nello791 come dicevo prima l'idea originale potrebbe essere così:

#include <LiquidCrystal.h>
#define rs 12
#define en 11
#define d4 5
#define d5 4
#define d6 3
#define d7 2
#define LED 13

int sensorPin = 0;
float temp = 0;
int misure;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode (LED, OUTPUT);
}

void loop() {
  temp = 0;
  for (int i = 0; i <= 7; i++) {
    sensorPin = analogRead(0); 
    misure = (0.488 * sensorPin - 50);
    temp = temp + misure;
    delay (50);
  }
  temp = temp / 8.0;
  Serial.println(temp);
  delay(1000);
}

Saluti.

1 Like

Grazie.
Avevo provato i precedenti consigli... Ho bisogno di dare una logica alle cose senó non le ricordo.

Grazie ancora e scusate la mia inesperienza.