I have serveral sensors for temperature and humitity. I want to calculate the average of the temperatures and humitities.
Is it possible to use just one function for the average calculations even if it contains arrays? Or will the data of one sensor overwrite the array of another?
I had something in mind like the following loop() and average() functions, as it is just a general question I wont be posting the setup():
Basic loop (I know its not complete):
void loop() {
sensors.requestTemperatures(); // read temperatures of both DS18B20 and DHT
valueDHT = dht[OUTTEMP].readTemperature(); // DHT Out
averageDHT = average(valueDHT);
}//loop
Average() with the corresponding setup():
const int numReadings = 10;
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
float total = 0; // the running total
float average = 0; // the average
void setup() {
// initialize serial communication with computer:
Serial.begin(9600);
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
float average(const float &sensordata)
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = sensordata;
// 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(1); // delay in between reads for stability
return average;
So I would define an array in the other function per sensor. But how would I pass it to the average() function? Would I pass the array and the sensordata seperately?
for example:
average(sensorArray[], sensorData);
What does the function have to look like? Something like this?
float average(const float &array, const float &data){
// instead of "readings" I would put the array? Here the example for the line "read from sensor":
array[readIndex] = data;
There are several hiccups in your code. See if this works:
#define DEBUG // Comment out when done debugging
const int numReadings = 10;
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
float total = 0.0; // the running total
void setup()
{
#ifdef DEBUG
Serial.begin(9600);
#endif
// initialize all the readings to 0:
memset(readings, 0, sizeof(float) * numReadings); // Little faster
}
void loop() {
sensors.requestTemperatures(); // read temperatures of both DS18B20 and DHT
valueDHT = dht[OUTTEMP].readTemperature(); // DHT Out
averageDHT = average(valueDHT);
}//loop
float average(const float &sensordata) // Is this really an lvalue??
{ // Your code doesn't have the opening brace
total -= readings[readIndex]; // subtract the last reading:
readings[readIndex] = sensordata; // Replace with sensor data:
total += sensordata;
if (readIndex < numReadings - 1) {
readIndex++;
} else {
readIndex = 0;
}
#ifdef DEBUG
Serial.print("average = ");
Serial.println(total / (float) numReadings);
delay(1); // delay in between reads for stability
#endif
return total / (float) numReadings;; // Return average
}
The code wasns't fully elaborated, because I was short of time. It was manly to know how to handle the array question while passing variables to a function.
My main goal:
pass the sensor data to the function
store the average in an array to calculate the running average
return the average
Is I heared from PaulS I would have to pass the whole array to the funtion in order to not have a chaos. As I am writing I realize that I probably would better pass the array by value instead of reference to have the function modify it directly or would the function handle several arrays passed by reference as individual arrays and return the according averages?
After that I have understood the array issue I would like to:
have a longtime or total average
seperate daytime and nighttime averages
understand if I can modify or work on an array with another array
moserroger:
As I am writing I realize that I probably would better pass the array by value instead of reference to have the function modify it directly
You have that backwards. The conventional way to pass an array to a function is to pass a pointer to its first element along with the total number of elements it contains. The name of an array is implicitly cast as this pointer when you use it in a function call. The sizeof() compiler directive can help you determine the number of elements:
float myArray[10];
const uint8_t numElements = sizeof(myArray) / sizeof(myArray[0]);
void setup() {
}
void loop() {
myFunction(myArray, numElements);
}
void myFunction(float theArray[], uint8_t arraySize) {
for (uint8_t i=0; i<arraySize; i++) {
// do stuff with array element theArray[i] here
}
}
EDIT:
Of course the above is not at all necessary if the array is global and it's the only array you need the function to operate on.
I dont quite understand how the sizeof compiler directive works. Why is it devided by sizeof(myArray[0])?
Thank for the reply and clarification.
I tried it this way (just a sample code to test the concept):
int total = 0;
int numReadings = 10;
float average = 0.0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // for debugging
float test [numReadings] {2.0, 4.0, 6.0, 8.0, 9.0, 3.0, 4.0, 8.0, 2.0, 7.0 }; // should be 5.3
averageMath(test);
float result = average;
Serial.print("result: ");
Serial.println(result);
}//setup
float averageMath(float Readings[]){
for (int i = 0; i < numReadings; i++){
total = total + Readings[i];
}//for
return average = total / numReadings;
}//averageMath
void loop() {
// put your main code here, to run repeatedly:
}
It seems to work. The only thing is that it returns 5.00 instead of 5.3. Where does this come from? Would this also be an acceptable way of doing it?
I dont quite understand how the sizeof compiler directive works. Why is it devided by sizeof(myArray[0])?
sizeof() returns the number of bytes used by whatever is passed as a parameter, not the number of elements in an array. So using it to find the number of bytes allocated to an array and dividing it by the number of bytes used by one element of the array gives the number of elements in the array.
This will work with any data type even though different data types require different amounts of storage
sizeof tells you how large something is, in bytes. You have an array of ten floats at four bytes apiece so forty bytes. You need to divide by four then if you're trying to get the number of elements in the array. It's a common idiom to use the sizeof the first element in the array so that you don't have to hard code the divisor.
Your average is wrong because total and numReadings are integers, so the division is integer division, so that what should be 5.3 is truncated to 5.0 before you try to store it in a float.
It's important that you understand that the default behavior for passing an array to a function is by reference. That means the function actually receives the starting memory address of where the array is stored. The only way that I can think of to pass an array by value is to put it in a structure and pass the structure...not a common way of working with arrays.