Temperature average (digital)

Hi there,

So I'm trying to get the average temperature, I already tried the 'Smoothing' tutorial with digitalRead instead of analogRead, but it only prints '0' and '1', not the average temperatures haha.

This currently is my code:

#include <OneWire.h>
#include <DallasTemperature.h>
 
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
 
// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

void setup() {
  // start serial port
  Serial.begin(9600);
  Serial.println("Temperatuur sensor by MAI©: 1min");

  // Start up the library
  sensors.begin();
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
   // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = digitalRead(2);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  Serial.println(average);
  delay(1000);        // delay in between reads for stability
}

Currently only working with seconds (delay of 1000), but at the end I'll calculate the average of 15 minutes (where the sensor measures every 1 mintute).

Thanks!

but it only prints '0' and '1'

That's not surprising.

  // read from the sensor:
  readings[readIndex] = digitalRead(2);

You aren't reading the temperature from the sensor. You are reading the state of the digital pin to which the sensor is connected - not the same thing at all.
There are any number of examples on this forum of how to read the temperature using the Dallas Temperature library. Search.

Just to clarify. Are you using a DS18B20 or other sensor that the Dallas library is designed to work with?

Pete

MichaelW1998:
Hi there,

So I'm trying to get the average temperature, I already tried the 'Smoothing' tutorial with digitalRead instead of analogRead, but it only prints '0' and '1', not the average temperatures haha.

First of all, you are reading your temperature sensor wrong. A simply digitalRead of a pin will only give you a LOW or HIGH (that is, only a 0 or a 1).

For averaging, try this:

// these are OUTSIDE the functions to be public accessable
double accumulator = 0.0;
uint32_t readings = 0;

double collect_data (double value)
{
    accumulator += value; // add to accumulator
    readings++; // increment count
    return (accumulator / readings); // return current average
}

This will accept any number of readings (up to 4 billion!) and return the average whenever you want it.

You can even read the CURRENT average, then let it keep running and read ANOTHER average LATER.

Hope this helps.

Krupski:
First of all, you are reading your temperature sensor wrong. A simply digitalRead of a pin will only give you a LOW or HIGH (that is, only a 0 or a 1).

For averaging, try this:

// these are OUTSIDE the functions to be public accessable

double accumulator = 0.0;
uint32_t readings = 0;

double collect_data (double value)
{
    accumulator += value; // add to accumulator
    readings++; // increment count
    return (accumulator / readings); // return current average
}




This will accept any number of readings (up to 4 billion!) and return the average whenever you want it.

You can even read the CURRENT average, then let it keep running and read ANOTHER average LATER.

Hope this helps.

So, I add the double accumulator and uint32_t above my void setup, and the double collect_data below my loop. So, what should I put in my loop to do this?
I'm sorry, little bit noob with Arduino coding haha.

BTW, my sensor is a Dallas DS18B20. So as seen in my original code, I can print the temperature with: Serial.print(sensors.getTempCByIndex(0)); //

Thanks!

MichaelW1998:
BTW, my sensor is a Dallas DS18B20. So as seen in my original code, I can print the temperature with:

Serial.print(sensors.getTempCByIndex(0)); //

Yes, that's how you would get (and print) the temperature value (in degC) from the DS18B20. But, that's not what you're doing in the original code that you posted. As pointed out by @el_supremo, you're simply reading a DIGITAL value from DIGITAL PIN 2. The only possible results are 1 or 0. I'd concentrate on getting the right temperature reading first before worrying about averaging.

gfvalvo:
Yes, that's how you would get (and print) the temperature value (in degC) from the DS18B20. But, that's not what you're doing in the original code that you posted. As pointed out by @el_supremo, you're simply reading a DIGITAL value from DIGITAL PIN 2. The only possible results are 1 or 0. I'd concentrate on getting the right temperature reading first before worrying about averaging.

Yes I got it to print and show the temperature reading. I even got it to print 2 readings with 2 sensors, on the same pin (with one_wire).
But I still have the same question:

So, I add the double accumulator and uint32_t above my void setup, and the double collect_data below my loop. So, what should I put in my loop to do this?

Averaging an array of readings has the disadvantage of using up RAM for the array, and having to
sum all the values everytime (though there are tricks to finesse that).

There's a much simpler way to low-pass filter an incoming value by using a simple
digital filter with a single value as state.

float average ;
#define k 0.1  // the filter coefficient, 0.1 means a scale of 10 samples, 0.01 would be 100 samples

void loop () 
{
  float reading = ???? ; // whatever code reads the current value
  average += k * (reading - average) ;  // simple 1st order digital low pass filter
  delay (10) ;    // sample rate set by a delay
}

If you want to average N values everytime you read the sensor, there's no need
to store them:

float take_averaged_reading ()
{
  float sum = 0.0 ;
  for (byte i = 0 ; i < N ; i++)
    sum += ???? ; // whatever code reads the sensor
  return sum / N ;
}

After 10 reads - very stable median values for DS18B20 with ESP8266 Web Server
Data wire is connected to GPIO 2
Show one decimal in the web server (see attach)
EXAMPLE: // tempC+/-x.xx calibration value =+0.50 celsius
// tempF+/-x.xx calibration value =+0,82 fahrenheit

04:14:49.453 ->
04:14:49.487 -> Connecting to WiFi
04:14:49.977 -> ..
04:14:50.485 -> 192.168.0.106
04:14:51.241 -> Temperature Celsius: 20.79
04:14:51.309 -> Temperature Fahrenheit: 69.46
04:14:51.377 -> Temperature Celsius: 20.78
04:14:51.445 -> Temperature Fahrenheit: 69.45
04:14:51.648 -> Temperature Celsius: 20.77
04:14:51.716 -> Temperature Fahrenheit: 69.44
04:15:02.128 -> Temperature Celsius: 20.77
04:15:02.162 -> Temperature Fahrenheit: 69.43
04:15:12.127 -> Temperature Celsius: 20.76
04:15:12.161 -> Temperature Fahrenheit: 69.42
04:15:14.099 -> Temperature Celsius: 20.76
04:15:14.133 -> Temperature Fahrenheit: 69.41
04:15:19.505 -> Temperature Celsius: 20.74
04:15:19.539 -> Temperature Fahrenheit: 69.41
04:15:24.972 -> Temperature Celsius: 20.74
04:15:25.006 -> Temperature Fahrenheit: 69.40
04:15:35.167 -> Temperature Celsius: 20.73
04:15:35.201 -> Temperature Fahrenheit: 69.40
04:15:41.778 -> Temperature Celsius: 20.73
04:15:41.812 -> Temperature Fahrenheit: 69.36
04:15:52.029 -> Temperature Celsius: 20.74
04:15:52.064 -> Temperature Fahrenheit: 69.36
04:15:54.678 -> Temperature Celsius: 20.74
04:15:54.745 -> Temperature Fahrenheit: 69.36
04:16:04.870 -> Temperature Celsius: 20.73
04:16:04.904 -> Temperature Fahrenheit: 69.37
04:16:14.859 -> Temperature Celsius: 20.73
04:16:14.927 -> Temperature Fahrenheit: 69.35
04:16:24.869 -> Temperature Celsius: 20.73

sketch_feb18a-medieCF.ino (5.89 KB)