Ciao a tutti,
sto realizzando un mini progetto con Arduino e sto utilizzando il sensore di temperatura TMP36 fornito nello starter kit.
Durante le misurazioni di temperatura, il sensore fornisce dei valori che continuano a variare nel tempo.
Per stabilizzare quindi questi valori, ho deciso di farne una media.
Il calcolo della media l'ho preso da qui Arduino - Smoothing.
Tuttavia ho dovuto modificare il codice ovvero sostituire alcune variabili int con delle variabili float.
Il codice che ho usato è questo
const int numReadings = 30;
int data[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
float total = 0; // the running total
float average = 0; // the average
int inputPin = A1;
void setup()
{
// initialize serial communication with computer:
Serial.begin(9600);
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++)
data[thisReading] = 0;
}
void loop() {
// subtract the last reading:
total= total - data[index];
// read from the sensor:
data[index] = analogRead(inputPin);
// add the reading to the total:
total= total + data[index];
// advance to the next position in the array:
index = index + 1;
// if we're at the end of the array...
if (index >= numReadings)
// ...wrap around to the beginning:
index = 0;
// calculate the average:
average = total / numReadings;
float temp = average* 0.4883 -50;
// send it to the computer as ASCII digits
Serial.print("Temperatura ");
Serial.print(temp);
Serial.println(" C");
delay(1); // delay in between reads for stability
}
Il mio problema è che se sono vicino al sensore, questo segna una temperatura di 26/27 gradi ma se mi allontano anche solo di un metro la temperatura si abbassa a 25.
Come mai oscilla così facilmente?
E come mai segna solo 25 gradi (quando in realtà ce ne sono 29...a Torino fa davvero caldo)?
Anche se nella guida di riferimento di Arduino non fa cenno di usare un condensatore, nel datasheet del sensore c'è scritto di usarne uno da 0.1 microF.
Io sinceramente non l'ho inserito nel circuito ma se volessi aggiungerlo, posso usare quello da 100 nF dello starter kit?
E come si capisce qual è il catodo e l'anodo?
Grazie mille dell'aiuto
30 letture sono davvero troppe: bastano 10 letture per ridurre il rumore della misura.
Hai fatto male a sostituire le variabili int con float: meglio fare una unica conversione da int (media) a float alla fine, essendo più veloce.
Non ha senso far ripetere il ciclo ogni 1ms (delay), poiché la temperatura non varia così rapidamente: ti consiglio di portare il ritardo a 100-1000 ms, oppure, meglio ancora usare millis per far ripetere il ciclo una volta al secondo.
Grazie mille per la risposta.
Ho dovuto fare la conversione perché altrimenti avevo valori assurdi (-50 gradi).
Purtroppo non ho con me Arduino ma appena avrò di nuovo tempo riprovo a sostituire i float con gli int e ti dico cosa mi viene.
Può essere che il problema sia in queste conversioni?
Per quanto riguarda il condensatore?
Il condensatore di bypass da 100n ceramico deve esserci, montato molto vicino al pin Vs.
Purtroppo il TMP36 ha un tensione di offset di 500mV = 0.5V di cui bisogna tener conto nel calcolo di conversione.
temp = ((val_Adc * 0.00488) - 0.5) / 0.01;
Quello dello starter kit non va bene?
Io pensavo di collegare questo, anche se non è ceramico Capacitor 100nF
Il fatto che debba essere ceramico è facilmente intuibile: se è ceramico non si scalda e quindi non influenza la lettura della temperatura del sensore.
Però non credo che un condensatore come quello dello starter kit si riscaldi di tanto.
Il fatto che non riesco a spiegarmi è come possa variare la temperatura quando qualcuno sia vicino al sensore.
Per la conversione ADC ho usato pure i 3.3V:
ho collegato l'uscita 3.3V di Arduino con il pin AREF e nel void setup ho inserito analogReference(EXTERNAL).
Successivamente ho modificato la formula per la conversione.
Tuttavia ho ancora la variazione di temperatura se mi sposto o meno dal sensore.
Ma perché il sensore risente della mia presenza?
Questo era nelle note del TMP36:
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 is manifested as abnormal dc shifts in the output voltage 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.
Il tuo corpo vicino al sensore non filtrato induce un disturbo derivato dalla rete elettrica o da Wi-Fi, GSM, cordless, ecc.
Ottimo.
Allora provo intanto con un condensatore non ceramico e vediamo se si ottengono miglioramenti.
Come si mettono questi condensatori?
Non riesco a distinguere anodo da catodo.
Anodo e Catodo sono riferiti ai diodi.
I condensatori non hanno polarità, salvo quelli elettrolitici.
Grazie mille Cyberhs.
Avevo usato un condensatore e c'era la polarità ma non sapevo riguardasse solo quelli elettrolitici.
Giovedì proverò ad inserire il condensatore e a sostituire nuovamente le variabili da float a int (tranne che per il valore di media).
Vediamo se cambia qualcosa.
Intanto grazie ancora per le risposte la disponibilità.
Ho fatto delle nuove prove con il condensatore dello starter kit e la temperatura sembra non oscillare più.
Ho pure sostituito le variabili float con le originali int e sembra funzionare tutto perfettamente.
L'unico difetto è questo:
senza analogReference(EXTERNAL) la temperatura oscilla tra i 30.57°C e i 31.06°C
con analogReference(EXTERNAL) la temperatura oscilla tra i 28.96°C e i 29.29°C
Ovviamente ho corretto la formula ma non capisco come mai ci siano 2°C di differenza.
Posta il codice ed indica qual'è la temperatura reale.
Il codice è questo
const int numReadings = 20;
int data[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int inputPin = A1;
void setup()
{
// initialize serial communication with computer:
Serial.begin(9600);
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++)
data[thisReading] = 0;
//analogReference(EXTERNAL);
}
void loop() {
// subtract the last reading:
total= total - data[index];
// read from the sensor:
data[index] = analogRead(inputPin);
// add the reading to the total:
total= total + data[index];
// advance to the next position in the array:
index = index + 1;
// if we're at the end of the array...
if (index >= numReadings)
// ...wrap around to the beginning:
index = 0;
// calculate the average:
average = total / numReadings;
float temp = average* 0.4883 -50;
//float temp = average* 0.3223 -50; //se attivo il referenceAnalog(EXTERNAL)
// send it to the computer as ASCII digits
Serial.print("Temperatura ");
Serial.print(temp);
Serial.println(" C");
delay(1); // delay in between reads for stability
}
La temperatura sembra essere 30.6°C
Non comprendo il significato di questo:
// subtract the last reading:
total= total - data[index];
anzi non comprendo proprio perché hai utilizzato un array!
total = 0;
for (byte i = 0; i < numReadings; i ++) {
total += analogRead(inputPin);
}
average = total / numReadings;
temp = (average * 5.0 / 1023 - 0.5) / 0.01; // Aref = 5V
temp = (average * 3.3 / 1023 - 0.5) / 0.01; // Aref = 3.3V