I want to calculate the trend of temperature, pressure and humidity. But the original code executes very slowly and Stuck.
Here's original code:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme;
int t_interval = 5000;
float p_ave = 0;
float t_ave = 0;
float h_ave = 0;
int count5 = 60; //60 * 5 sec in 5 min assuming t_interval = 5000msec
//ring buffer to allow trend detection
const int length=30; //size of buffer: 36 places allows a time interval of 36 * 5 min = 3 hours
float data[length]; //buffer array
int put_index=0; //index to array
float t_now, t_was;
float p_now, p_was;//current pressure and old pressure
float h_now, h_was;
float temperature, humidity, pressure, change_P, change_T, change_H;
void setup() {
//initialise array values to zero
for(put_index=0; put_index<length; put_index++){
data[put_index]=0;
}
put_index=0; //reset ready for data entry
int change = 0;
delay(100);
Serial.begin(9600);
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while(1);
}
bme.setSampling(Adafruit_BME280::MODE_NORMAL,
Adafruit_BME280::SAMPLING_X16, // temperature
Adafruit_BME280::SAMPLING_X16, // pressure
Adafruit_BME280::SAMPLING_X16, // humidity
Adafruit_BME280::FILTER_X16,
//Adafruit_BME280::STANDBY_MS_0_5 );
Adafruit_BME280::STANDBY_MS_250 ); //standby to 250msec
}
void loop() {
for (int i = 0; i < count5; i++) {
temperature = bme.readTemperature();
pressure = bme.readPressure() / 100.0F; //bme280
humidity = bme.readHumidity();
delay(t_interval);
t_ave += temperature;
p_ave += pressure;
h_ave += humidity;
}
t_ave /= count5;
p_ave /= count5;
h_ave /= count5;
t_was = put(t_ave);
p_was = put(p_ave);
h_was = put(h_ave);
change_T = t_ave - t_was; //change reading
change_P = p_ave - p_was; //change reading
change_H = h_ave - h_was; //change reading
t_ave = 0; //reset ready for next calculation
p_ave = 0; //reset ready for next calculation
h_ave = 0; //reset ready for next calculation
}
float put(float value){
Serial.print("T-now = ");
Serial.print(value, 2);
data[put_index] = value;
put_index=(put_index+1)% length;
value=data[put_index];
Serial.print(": T-was = ");
Serial.println(value, 2);
Serial.print("P-now = ");
Serial.print(value, 2);
data[put_index] = value;
put_index=(put_index+1)% length;
value=data[put_index];
Serial.print(": P-was = ");
Serial.println(value, 2);
Serial.print("H-now = ");
Serial.print(value, 2);
data[put_index] = value;
put_index=(put_index+1)% length;
value=data[put_index];
Serial.print(": H-was = ");
Serial.println(value, 2);
Serial.print("Change_T = ");
Serial.println(change_T);
Serial.print("Change_P = ");
Serial.println(change_P);
Serial.print("Change_H = ");
Serial.println(change_H);
return(value);
}
Can i replace "delay(t_interval) with millis()? how?
Thanks for your help in advance.
Yes you can.
ddsioj:
how?
I would ask why? There is no advantage at all in rewriting the delay function to use millis(). It will do the same thing, that is will block any running of any other code until it is finished.
It will not speed up anything. Temperature, pressure and humidity don't change very quickly so five seconds is a sensible rate, if you want it faster then just put a smaller number in the declaration of t_interval.
People use millis to write code that appears to multitask.
An illustration of that is in the blink without delay function under the examples menu of the IDE.
Or look here for my take on the topic
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
1 Like
gcjr
June 5, 2022, 10:43am
3
i favor a running avg using leaky integration
avg += (samp - avg) / N;
a running avg would allow updating the output every sample period instead of waiting for 60 5 sec sampling periods
1 Like
Then why use
ddsioj:
delay(t_interval);
where the wait time is
ddsioj:
t_interval = 5000;
which is 5 seconds?
Why is a 5 seconds delay required and what is the purpose of waiting 5 seconds?
Here I collect 60 pressure readings. The pressure readings are collected once every 2 hours and a graph is displayed on a e-ink display. A trend line.
void fProcessAirPressure ( void *pvParemeters )
{
int Ticks = 118; // Tick counter
bool Filled = false; // array has been filled before?
float *ptr = CollectionPressure; // pointer to the array
const int ticksTrigger = 120; // triggered at 1 minute intervals
for (;;)
{
//triggered by BME which is triggered by the 1 minute hardware timer.
xEventGroupWaitBits (eg, evtStoreAirPressure, pdTRUE, pdTRUE, portMAX_DELAY );
xSemaphoreTake( sema_CollectPressure, portMAX_DELAY );
xSemaphoreTake ( sema_eData, portMAX_DELAY );
if ( !Filled )
{
//if array has not been filled before, fill array with the same base value
for ( int j = 0; j < BufferCount; j++ )
{
*( ptr + j ) = x_eData.oPressure;
}
Filled = true;// array has been initially filled
} else {
if ( Ticks == ticksTrigger )
{
//when tick counter reaches the trigger level
//shift contents left and insert new value at the end
for ( int i = 0; i <= BufferCount - 2; i++ )
{
*( ptr + i ) = *( ptr + (i + 1) );
}
}
*( ptr + (BufferCount - 1) ) = x_eData.oPressure;//new value to be inserted
}
// find and store highest and lowest value
if ( x_eData.oPressure > x_eData.PressureH )
{
x_eData.PressureH = x_eData.oPressure;
}
if ( x_eData.oPressure < x_eData.PressureL )
{
x_eData.PressureL = x_eData.oPressure;
}
Ticks++;
if ( Ticks > ticksTrigger )
{
Ticks = 1;
}
//log_i( "ticks %d" , Ticks );
x_eData.cngPress = CalculatePressureFactors( *( ptr + 57), *( ptr + 59) ); // going back 4 hours
xSemaphoreGive( sema_eData );
xSemaphoreGive( sema_CollectPressure );
//
//log_i( " high watermark % d", uxTaskGetStackHighWaterMark( NULL ) );
} //for (;;)
vTaskDelete( NULL );
} //void fStoreAirPressure ( void *pvParemeters )
////
code used to display air pressure trend line.
int BaseLine = (int) * ptr;
int offsetX = 0;
for ( int j = 0; j < BufferCount; j++ )
{
if ( *(ptr + j) != 0.0f )
{
int yAdj = BaseLine - (int) * (ptr + j);
display.setCursor( CurrentX + offsetX, CurrentY + yAdj );
display.print( "-" );
offsetX += 5;
// log_i( "pressure %f item %d", CollectionPressure[j], j );
}
}
But if you just want a running average use suggestion from post#3.
1 Like
system
Closed
December 2, 2022, 11:31am
5
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.