Ho un comportamento strano durante la lettura di una DS18B20, ovvero ho letture "altalenanti".
Il collegamento della sonda è stato fatto nel seguente modo:
Condensatore da 100nF tra GND e +5V
Resistenza 4K7 tra +5V e pin di lettura
Pin di lettura colleagato al pin 10 di Arduino.
Ho provato più di una sonda per eliminare il dubbio che si trattasse di una sonda guasta e ho fatto il test con un Arduino mini, con un Arduino Uno e con un 328 in configurazione minima su breadboard con medesimi risultati
In pratica leggo una volta al minuto la temperatura e la metto in un array, dopo 12 letture scarto la massima e la minima rilevate e faccio la media delle altre.
Quello che ottengo ogni 12 minuti sono dati tipo:
27.5
25
27.5
25.1
27.8
25.3
A qualcuno è capitata una situazione simile?
Il codice che uso per rilevare la temperatura è questo (ho rimosso le parti non necessarie/inerenti al problema)
#define PIN_TEMP_SENSOR 10
#define TEMP_SENSOR_RESOLUTION 10
#define TEMP_SENSOR_INDEX 0
OneWire tempSensorOneWire(PIN_TEMP_SENSOR);
DallasTemperature tempSensor(&tempSensorOneWire);
DeviceAddress sensorDeviceAddress;
const byte maxTempReads = 12;
unsigned long lastTempMillis;
unsigned long temperatureReadInterval = 60000;
byte numTempRead = 0;
float arrTempRead[maxTempReads];
float currentTempRead;
float tempCorrection = 0.0f;
void setup()
{
tempSensor.begin();
tempSensor.getAddress(sensorDeviceAddress, TEMP_SENSOR_INDEX);
tempSensor.setResolution(sensorDeviceAddress, TEMP_SENSOR_RESOLUTION);
}
void loop() {
#ifdef ENABLE_WATCHDOG
wdt_reset();
#endif
readTemp(false);
}
byte getMaxTempValueIndex()
{
byte attIdx = 0;
float maxValue = -99.0f;
byte retValue = 0;
while (attIdx < maxTempReads)
{
if (arrTempRead[attIdx] > maxValue)
{
retValue = attIdx;
maxValue = arrTempRead[attIdx];
}
attIdx++;
}
return retValue;
}
byte getMinTempValueIndex()
{
byte attIdx = 0;
float minValue = 299.0f;
byte retValue = 0;
while (attIdx < maxTempReads)
{
if (arrTempRead[attIdx] < minValue)
{
retValue = attIdx;
minValue = arrTempRead[attIdx];
}
attIdx++;
}
return retValue;
}
void readTemp(boolean bForce)
{
if (bForce || (millis() - lastTempMillis > temperatureReadInterval))
{
tempSensor.requestTemperatures();
arrTempRead[numTempRead++] = tempSensor.getTempCByIndex(TEMP_SENSOR_INDEX);
if (numTempRead > maxTempReads || bForce)
{
if (bForce)
{
currentTempRead = arrTempRead[0];
}
else
{
currentTempRead = 0.0f;
if (digitalRead(PIN_DEBUG_MODE) == LOW)
{
Serial.print(F("Array temp readed: "));
}
byte maxValueIdx = getMaxTempValueIndex();
byte minValueIdx = getMinTempValueIndex();
for (byte arrIdx = 0; arrIdx < maxTempReads; arrIdx++)
{
if (digitalRead(PIN_DEBUG_MODE) == LOW)
{
Serial.print(arrIdx);
Serial.print(F(": "));
Serial.print(arrTempRead[arrIdx]);
Serial.print(F(" ("));
}
if (arrIdx != maxValueIdx && arrIdx != minValueIdx)
{
currentTempRead += arrTempRead[arrIdx];
if (digitalRead(PIN_DEBUG_MODE) == LOW)
{
Serial.print(currentTempRead);
Serial.print(F(") - "));
}
}
else
{
if (digitalRead(PIN_DEBUG_MODE) == LOW)
{
Serial.print(F("scartato) - "));
}
}
}
currentTempRead = currentTempRead / (maxTempReads - 2);
if (digitalRead(PIN_DEBUG_MODE) == LOW)
{
Serial.print(F("average: "));
Serial.println(currentTempRead);
}
//Rounding to one decimal place
currentTempRead = round(currentTempRead * 10.0f) / 10.0f;
}
if (digitalRead(PIN_DEBUG_MODE) == LOW)
{
Serial.print(F("Temp: "));
Serial.println(currentTempRead);
}
currentTempRead += tempCorrection;
if (digitalRead(PIN_DEBUG_MODE) == LOW)
{
Serial.print(F("Temp corrected: "));
Serial.println(currentTempRead);
}
numTempRead = 0;
sendDeviceStatus();
}
lastTempMillis = millis();
}
}