Multiple Temp Measurements

Hello, another newbie. I am trying to make some measurements on multiple DHT11 Temp/Humidity sensors. I am getting them to read okay, but having some programming language/logic issues. The output I am seeing has several issues…
1) My implementation of a “Stack”, is not consistently adding new items, and pushing the old items out. I have 4 sensors, and for each sensor I want to average the Temp read over 5 measurements. So have two arrays Temp[Sensor#][Meas#] and Humid[Sensor#][Meas#] . Sensor is #0-3, and Meas# is 0-4. The values stored should be floating point numbers.
2) For the Temperature the “stack” feature is working somewhat, but not for the Humidity measurement.
3) The value showing up for the Average, does not seem to be very accurate.
The code is here…

//  Sketchname "Multiple_DHT11_Sensor_Script_V3"
//  Modified the original script from the following Author...
//    FILE: dht11_test.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: DHT library test sketch for DHT11 && Arduino
//     URL:
//
// Released to the public domain
//
//  7/24/14:   Verified this was working with 2 DHT11 sensors
//  Aug:  Verify this was working with 4 DHT's... now working to get output to display properly, and add averaging function..

#include <dht.h>

// Declare Four DHT11 sensor objects
dht DHT11_1;
dht DHT11_2;
dht DHT11_3;
dht DHT11_4;

//  Define port # on which communication will take place
#define DHT11_PINA 5
#define DHT11_PINB 4
#define DHT11_PINC 3
#define DHT11_PIND 6

//  Eventualy should read/store this on SD card or EEPROM
float TOffset1=-2.0;    //Calibration Offet in C & %
float TOffset2=0;
float TOffset3=0;
float TOffset4=0;
float HOffset1=-3.0;
float HOffset2=0;
float HOffset3=0;
float HOffset4=0;

//  Definitions for the data, and averaging function
float Fahren, Celcius, DewPoint,Humidity;
float Temp[3][4];    //First digit Sensor#0-3, 2nd digit, one of 5 temps to be averaged (a stack sort of)
float Humid[3][4];  // Ditto
int ValPtr=0;      // pointer into the stack (if needed)



void setup()
{
  Serial.begin(115200);
  Serial.println("DHT Multi-Sensor TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT_LIB_VERSION); 
  Serial.print("Statistics - Error:  Temperature= ");
  Serial.print(char(177));Serial.print("2 ");
  Serial.print(char(176));
  Serial.print("C, Humidity= ");
  Serial.print(char(177));Serial.println("5% RH");
  Serial.println();
  //Serial.println("Sensor#,\tstatus,\tHumidity (%),\tTemperature (C),(F)\tDewPoint\n");
}//=================================================================

void loop()
{
   // READ DATA from Sensor #1
  Serial.print("DHT11-1, \n");
  int Change=false;
  
  int chk1 = DHT11_1.read11(DHT11_PINA);

  Celcius = (float) DHT11_1.temperature,2;
  Humidity =(float) DHT11_1.humidity,1;
  ShowResults(chk1,Celcius,Humidity,1);    // Pass: result data, Temp, Humidity, Sensor#

  Serial.print("Temperature #1="); Serial.print(Celcius);Serial.print("\t");
  if (Celcius != Avg(0,0, Celcius)) {
    Change=true;
  }
 
  Serial.print("Humidity    #1="); Serial.print(Humidity);;Serial.print("\t");
  if (Humidity != Avg(0,1, Humidity)) { 
    Change=true;
  }

  
  
  
     // READ DATA from Sensor #2
  Serial.print("DHT11-2, \n");
  int chk2 = DHT11_2.read11(DHT11_PINB);
 
  Celcius = (float) DHT11_2.temperature,2;
  Humidity =(float) DHT11_2.humidity,1;
  ShowResults(chk2,Celcius,Humidity,2);

  Serial.print("Temperature #2="); Serial.print(Celcius);Serial.print("\t");
  if (Celcius != Avg(1,0, Celcius)) {
    Change=true;
  }
  Serial.print("Humidity    #2="); Serial.print(Humidity);;Serial.print("\t");
  if (Humidity != Avg(1,1, Humidity)) { 
    Change=true;
  }
 
  
  // READ DATA from Sensor #3
  Serial.print("DHT11-3, \n");
  int chk3 = DHT11_3.read11(DHT11_PINC);       
  //Duplicate above when fully debuged...
  
  // READ DATA from Sensor #4
  Serial.print("DHT11-4, \n");
  int chk4 = DHT11_4.read11(DHT11_PIND);       
    //Duplicate above when fully debuged...

  if (Change = true) {
    //do something here.  if Change is true, vales have changed from their averages, so update the display info
    Serial.print("\nCHANGE --------------------------------\n");
  }
  
  
  Celcius=0;Humidity=0;    //clear results from each loop
  Serial.println("\n_____________________________________");
  delay(10000);  //delay long enough to see what is going on, not getting the results I expected
}


/*==========================================================
'  chk:  Results returned from measurement command
'  Temp:
'  RHhumidity
'  Sensor:   Which DHT11 #1 to 4
*/
void ShowResults(int chk, double Temp, double RHumidity, int Sensor)
{
 switch (chk)  //Show communication response
  {
    case DHTLIB_OK:  
		Serial.print("OK,\t"); 
		break;
    case DHTLIB_ERROR_CHECKSUM: 
		Serial.print("Checksum error,\t"); 
		break;
    case DHTLIB_ERROR_TIMEOUT: 
		Serial.print("Time out error,\t"); 
		break;
    default: 
		Serial.print("Unknown error,\t"); 
		break;
  }  
  
  
 /* An attempt at caibrating any offsets inherent in each sensor.  HAve 4 sensors, and they are not reading the same absolute temp..
 switch (Sensor)
  {
    case 1: 
      //Serial.print("Case 1\t");
      RHhumidity = RHhumidity + HOffset1;
      Temp = Temp + TOffset1;
      break;
    case 2:
      //Serial.print("Case 2\t");
      RHhumidity = RHhumidity + HOffset2;
      Temp = Temp + TOffset2;
      break;
    case 3:
      // Serial.print("Case 3\t");
      RHhumidity = RHhumidity + HOffset3;
      Temp = Temp + TOffset3;
      break;
  }
*/
  Serial.print("Sensor #");Serial.print(Sensor);Serial.print("\tRH=");
  Serial.print(RHumidity);  Serial.print("%,\tT=");
  Serial.print(Temp);  Serial.print(char(176));  Serial.print("C = ");
  Serial.print((1.8* Temp)+32);  Serial.print(char(176));  Serial.print("F\t\tCalculations{");
  
  /*  The following calculations are experimetal, so ignoret them for now...
  
  DewPoint  =  dewPointFast(Temp, RHumidity); // Computed Value 
  Serial.print(DewPoint);  Serial.print(char(176));  Serial.print("F\tHeat: ");
  Temp = ((Temp*9)/5)+32;    //pass temp in F
  Serial.print(heatIndex(Temp,RHumidity));  Serial.print("\t");
  Serial.print(Temp - ((100.0-RHumidity)/5.0));  Serial.print("\t");
  */
  Serial.print(millis());Serial.println("}");
  //delay(2000); 
}  //=================================================================



/*==========================================================
'  Temp[a][b]  Log of last 5 temp measurements, a=sensor (0-3), b=measurement (0-4)
'  Valu:  Floating point value measured
'  Typp:  0 = Temperature, 1 = Humidity
'  Sensor:   Which DHT11 #0 to 3
*/
int Avg(int sensor,int typp, float Valuu)
{
  float Avgg;
  //   typp=0 is temperatore
  if (typp==0) {  
    //Average the last 5 measurements
    for (int j=0; j<= 4; j++) {
      Avgg = Avgg + Temp[sensor][j];
    }
    Avgg = Avgg/5.0;
    
    // Pop last measurement onto 5 item stack (delete oldest measurement)
    for (int j=1; j <= 4; j++) {
      Temp[sensor][j-1] = Temp[sensor][j];
    }
    Temp[sensor][4]=Valuu;

    Serial.print( "Stack Values: [");
    for (int j=0; j<=4; j++) {
      Serial.print(j);  Serial.print("=");  Serial.print(Temp[sensor][j]); Serial.print("\t");
    }
    Serial.print("]\tCalculated Average =");
    Serial.println(Avgg);
    
} else if (typp==1) {
    Avgg = (Humid[sensor][0]+Humid[sensor][1]+Humid[sensor][2]+Humid[sensor][3]+Humid[sensor][4])/5;
    
    //Average the last 5 measurements
    for (int j=0; j<= 4; j++) {
      Avgg = Avgg + Humid[sensor][j];
    }
    Avgg = Avgg/5.0;

    Serial.print( "Stack Values: [");
    for (int j=0; j<=4; j++) {
      Serial.print(j);  Serial.print("=");  Serial.print(Humid[sensor][j]); Serial.print("\t");
    }
    Serial.print("]\tCalculated Average =");
    Serial.println(Avgg);
    
}
  return (int)Avgg;

}//=================================================================  

//
// END OF FILE
//

The attached file show the results from the serial monitor window…

Anyone have suggestions on what is wrong (obvious to you perhaps, but not to me … so far). Any help is appreciated (of course).

Output.txt (55.2 KB)

I haven't studied your code for long enough to figure out how you are using the stack.

My inclination would be to create a circular buffer (basically an array with an index that increments to the max value and then return to 0). I would read the incoming values straight into the buffer and then figure out the average.

Circular buffers are used, for example, in the Serial library. In that case they have 2 indices - one for reading and one writing. I don't get the impression that you need to take the data out of your buffer - it will be sufficient to overwrite the oldest value.

...R

Here is a circular buffer rolling average function I wrote a while back. Would need to be converted to handle multiple averages and floats. The setup() function has some sample code to demonstrate how the rolling average follows a series of increasing or decreasing input values.

#define CIRCLE_SIZE 16

uint8_t circleData[CIRCLE_SIZE] = {0};
uint8_t circlePointer = 0;
uint16_t circleSum = 0;

void updateRollingAverage(uint8_t value)
{
    circleSum = circleSum - circleData[circlePointer] + value;
    circleData[circlePointer] = value;
    circlePointer++;
    if (circlePointer == CIRCLE_SIZE)
    {
        circlePointer = 0;
    }
}

uint8_t rollingAverage()
{
    return circleSum / CIRCLE_SIZE;
}


#define LOOP_DELAY 60

void setup() 
{

    Serial.begin(115200);
    
    for (byte i = 0; i < 30; i++)
    {
        updateRollingAverage(0);
        Serial.print(0);
        Serial.print("   ");
        Serial.println(rollingAverage());
        delay(LOOP_DELAY);
    }
  
    for (byte i = 0; i < 250; i++)
    {
        updateRollingAverage(i);
        Serial.print(i);
        Serial.print("   ");
        Serial.println(rollingAverage());
        delay(LOOP_DELAY);
    }  
  
    for (byte i = 250; i > 0; i--)
    {
        updateRollingAverage(i);
        Serial.print(i);
        Serial.print("   ");
        Serial.println(rollingAverage());
        delay(LOOP_DELAY);
    }  

}

void loop() 
{

}