Ciao a tutti,
vi ringrazio per le pronte risposte e per le indicazioni che mi avete offerto.
Ma devo dire che non mi è chiaro ancora l'approccio che devo usare per risolvere la problematica che sto riscontrando e che vi ho illustrato.
Mi sono documentato leggendo la documentazione di riferimento che mi avete fornito, ma ancora non mi è chiaro l'approccio che devo tenere.
Mi pare di intuire che il problema sia legato alla tensione di riferimento utilizzata da Arduino (io sto utilizzando Arduino UNO).
Ho letto l'articolo "Secret voltometer", ma da quando desumo, quanto scritto consente di ottenere un valore della tensione di riferimento in quel momento detenuta dal microcontrollore e verificare come e quanto sia alimentata in quel momento la scheda. Ma non riesco a comprendere come posso risolvere l'errata lettura della tensione erogata a un pin analogico.
L'errore di lettura lo rilevato eseguendo un piccolo esercizio di utilizzo del sensore di temperatura LM35DZ. Come scrivevo la tensione del Vout del sensore, rilevata con un multimetro, è perfettamente in linea con la temperatura ambientale rilevata con altri termometri piuttosto precisi di cui sono in possesso. Ma al di là della precisione dei termometri non riesco a capire come mai il valore letto (derivato) leggendo il pin analogico, che nel mio caso è il pin A0, sia inferiore di non poco.
Premesso che la tensione di alimentazione ottenuta dalla porta USB è di 5.06V eseguo il seguente calcolo:
vPin = analogPin(A0)*(5.06/1023) ottenendo una tensione stimata di 252mV.
analogPin(A0) = 51
Misurando con il multimetro la tensione presente sul Vout del sensore ottengo 267mV, assolutamente in linea con la temperatura ambientale presente nel momento della misura.
Preciso che le misure vengono effettuare nel codice campionando 10 misure intervallate da 600 millisecondi e effettuando la media.
Come potete vedere dal codice di seguito illustrato per ottenere valori "corretti" devo utilizzare un valore di 5,29 anziché di 5.
float tempC; //dichiarazione di variabile
int tempPin = A0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); //apertura porta seriale, set della velocità a 9600 bps
//analogReference(EXTERNAL);
}
void loop() {
// put your main code here, to run repeatedly:
int counter = 0;
float sumTemp = 0;
float avgTemp = 0;
float sumVoltage = 0;
float avgVoltage = 0;
int sensorValue = 0;
float avgSensorValue = 0;
int sumSensorValue = 0;
Serial.print(readVcc());
Serial.print("Sensor Value: ");
Serial.print(analogRead(tempPin));
Serial.println();
for(int i=0;i<100;i++){
counter++;
sensorValue = analogRead(tempPin); //lettura valore del sensore
sumVoltage = sumVoltage + (sensorValue * (5.29 / 1023.0));
tempC = (5.29 * sensorValue * 100.0)/1023.0; //conversione del dato analogico in temperatura
sumTemp = sumTemp+tempC;
sumSensorValue = sumSensorValue + sensorValue;
delay(600);
}
avgTemp = sumTemp/counter;
avgVoltage = sumVoltage / counter;
avgSensorValue = sumSensorValue / counter;
Serial.print("Avg. Voltage: ");
Serial.print(avgVoltage,4);
Serial.print(" T C: ");
Serial.print(avgTemp);
Serial.print(" Sensor Value avg: ");
Serial.print(avgSensorValue,4);
Serial.print(" T C: ");
Serial.print(avgSensorValue*0.506, 4);
Serial.println();
}
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
Leggendo la documentazione mi sembra di capire che per letture precise sia necessario fornire una tensione di riferimento precisa con il pin AREF o alimentando con una tensione maggiore di 5V in modo da fare intervenire lo stabilizzatore.
Vi chiedo scusa per l'argomento banale e/o già trattato ma non comprendo la natura di un errore così macroscopico.
Ringrazio d'avvero tutti.
Lorenzo