Get Average Readings from DHT22

Hello guys! I am new to Arduino coding and I have a project that requires getting temperature readings from DHT22 and getting the average. I want to get the average thru the stored values of the reading in a dynamic array (since I assume that there will come a time that maybe one of the sensors is failing to read the temperature).

This is crucial because the average temperature will be used to activate a relay. Hence, I do not want to get a "nan" average whenever one of the sensors failed to read. Thanks in advance!

I want to get the average thru the stored values of the reading in a dynamic array

What about the array is to be dynamic? The size, which is what dynamic normally refers to? Or, the data in the array?

The size is fixed. Six temperature readings. However, the data or values are not since some of them might give a "nan" value which will result to "nan" average.

What I meant with dynamic is the number of dht22 readings might not be always six. It can be sometimes be lower than six (1, 2, 3, 4, 5, functioning well dht22 sensors)

Thanks PaulS for replying.

maybe a little bit off subject but it may save you some pain if you read a few posts on how to stabilize the reading on a dht22.

once I stabilized mine I found I didn't need to average anything and both sensors (used 2) were real close to reading the same. Then I just used one as a main and if it received a nan it swapped to the back-up. Your use maybe totally different but I thought it was worth mentioning.

Thanks gpop1. What was the code you used for making your other sensor as backup?

You can read the sensor, and store and count the value only if it is not a nan. That way, the nan readings will be discarded, and won't influence the average.

kinda hard to post my code as the names have been changed basically it

if (isnan(h) || isnan(t) || isnan(f)) {
  //  Serial.println("Failed to read from DHT sensor!");
  }

if its true then I move the second temp reading in to temp. else I move the first temp reading in to temp. same as humidity (I don't use isnan(t) as that's Celsius but I left that in the example)

this code came with the original example of dht

PaulS. I am still a beginner. What is the code for storing and counting values? The code I used is shown further below.

I included the Average library but it won’t work properly. An error occurred saying: "error: request for member ‘mean’ in ‘incubatorTemp’, which is of non-class type ‘float [6]’ "

#include <LiquidCrystal.h>
#include “DHT.h”
#include <Average.h>

// set the pins for DHT22 sensors
#define DHT1PIN 43
#define DHT2PIN 41
#define DHT3PIN 39
#define DHT4PIN 37
#define DHT5PIN 35
#define DHT6PIN 33

#define DHT1TYPE DHT22
#define DHT2TYPE DHT22
#define DHT3TYPE DHT22
#define DHT4TYPE DHT22
#define DHT5TYPE DHT22
#define DHT6TYPE DHT22

DHT dht1(DHT1PIN, DHT1TYPE);
DHT dht2(DHT2PIN, DHT2TYPE);
DHT dht3(DHT3PIN, DHT3TYPE);
DHT dht4(DHT4PIN, DHT4TYPE);
DHT dht5(DHT5PIN, DHT5TYPE);
DHT dht6(DHT6PIN, DHT6TYPE);

void setup() {

dht1.begin();
dht2.begin();
dht3.begin();
dht4.begin();
dht5.begin();
dht6.begin();

// LCD at start
lcd.begin(16, 2);
lcd.backlight();
}

void loop()
{
float t1 = dht1.readTemperature();
float t2 = dht2.readTemperature();
float t3 = dht3.readTemperature();
float t4 = dht4.readTemperature();
float t5 = dht5.readTemperature();
float t6 = dht6.readTemperature();

// make an array of temp and RH readings
float incubatorTemp = {t1, t2, t3, t4, t5, t6};

//Display temp in LCD
lcd.setCursor(0, 1);
lcd.write(1);
lcd.setCursor(2, 1);
lcd.print(incubatorTemp.mean);

Once you determine the current reading is in range:

averageThermister=(averageThermister*8+valueThermister)/9;

if you want to average the last 9 readings. if you want to average the last 5 readings, use 4 and 5 in the code.

Originally, I used this code:

  float incubatorTemp = ((t1 + t2 + t3 + t4 + t5 + t6) / 6);

the problem with this is that if one of the t readings give a value of "nan", then the incubatorTemp will also give "nan" value. And again, this is the problem I want to solve.

I want to get only the average of temperature readings only from sensors which gave values. Thanks

its easy to write a if/elseif to remove one sensor but that just leads to a problem if more than one fails

so im guessing that you need to make the divide number a byte then any nan is replaced with a zero and the divide number is reduced by one.

I think this would work if place directly after the reads

x = 6;
if (isnan(t1) {
t1 = 0;
x - 1;
}
if (isnan(t2) {
t2 = 0;
x - 1;
}
if (isnan(t3) {
t3 = 0;
x - 1;
}
if (isnan(t4) {
t4 = 0;
x - 1;
}
if (isnan(t5) {
t5 = 0;
x - 1;
}
if (isnan(t6) {
t6 = 0;
x - 1;
}

float incubatorTemp = ((t1 + t2 + t3 + t4 + t5 + t6) / x);

gpop1 thanks a lot! Should I also include x = 6 within each if statements or just after the void loop()?

program reads top to bottom so just make it a byte or int where it is. As the program read down it will reset to 6 every pass then remove one for every sensor until it does the final calculation. (it has to be after the sensor reads and before you use incubatorTemp any where else)

gpop1 i tried using your suggestion but I SOMETIMES get an average value ranging from 17 to 29 degrees Celsius for DHT22 compared to a DS18b20 reading which is 34 degrees Celsius (which is probable since I am just in my room without an air conditioning unit). ONLY FEW INSTANCES happened where the value of average temp from DHT22 is close enough to DS18b20 temp reading.

  float t1 = dht1.readTemperature();
  float h1 = dht1.readHumidity();
  float t2 = dht2.readTemperature();
  float h2 = dht2.readHumidity();
  float t3 = dht3.readTemperature();
  float h3 = dht3.readHumidity();
  float t4 = dht4.readTemperature();
  float h4 = dht4.readHumidity();
  float t5 = dht5.readTemperature();
  float h5 = dht5.readHumidity();
  float t6 = dht6.readTemperature();
  float h6 = dht6.readHumidity();

  int x = 6;
  if (isnan(t1) || isnan(h1)) {
  t1 = 0;
  h1 = 0;
  x - 1;
  }
  
  if (isnan(t2) || isnan(h2)) {
  t2 = 0;
  h2 = 0;
  x - 1;
  }
  
  if (isnan(t3) || isnan(h3)) {
  t3 = 0;
  h3 = 0;
  x - 1;
  }
  
  if (isnan(t4) || isnan(h4)){
  t4 = 0;
  h4 = 0;
  x - 1;
  }
    
  if (isnan(t5) || isnan(h5)) {
  t5 = 0;
  h5 = 0;
  x - 1;
  }
  
  if (isnan(t6) || isnan(h6)) {
  t6 = 0;
  h6 = 0;
  x - 1;
}

float incubatorTemp = ((t1 + t2 + t3 + t4 + t5 + t6) / x);
float incubatorRH = ((h1 + h2 + h3 + h4 + h5 + h6) / x);

What do you think might be the problem with the code? Thanks!

You need to not just check for NaNs.

If you get a strange reading, you should ignore it.

These devices sometimes output 0 or 85C, for some reason I can't recall right now. You should ignore those.

michinyon, Yes I want to IGNORE THOSE BY NOT INCLUDING SUCH VALUES IN GETTING THE AVERAGE. DO YOU KNOW HOW? Thank you!

My DHT22s are not functioning well even though they are calibrated. How can I get the mean, mode, and median of temperature readings with a "NaN" member? Hoping for code suggestions. Thanks in advance!

newbie18:
My DHT22s are not functioning well even though they are calibrated. How can I get the mean, mode, and median of temperature readings with a “NaN” member? Hoping for code suggestions. Thanks in advance!

Internally the DHT22 sensors are providing 10 bit integer numbers as a temperature.

But “NaN” is a thing for “float” variables only.
So you never get “NaN” from the sensor, that value is created by your code only.

So I see two possibilities to prevent dealing with “NaN”:

  1. Throw away your existing DHT code that provides ‘float’ results. Use code that perhaps provide the temperature as an “int” in the unit “tenths of degrees”.

  2. Ignore “NaN” results and do not try further calculations on that weird sensor readings.

Go back a few steps.

A single dht22 can read as solid as a rock with no nan's

the arduino needs to be power from a external source around 9v not from the usb

You need a 100uf cap across the positive and negative of the arduino

The negative of the of the dht22 needs to go to the arduino negative pin or as close as possible rather than being landed at the bread board with other items sharing the same ground

There has to be a resistor on the dht data pin pulling it high most people suggest a 4.7kohm

only read the dht22 every second as its a slow sensor

do not read it for the first 2 second on start up or do not use that reading as it takes a few seconds to stabilize

make a test script and just work with one sensor to see how stable you can make it. It should be real stable with less than 0.2 F movement between reads