Hi, I am not a programmer but just (an older) self-taught hobbyist, so please excuse my ignorance. I've struggled all evening trying to derive a 30- or N-second running average from an analog pressure sensor. I'm using the RunningAverage.h library but cannot seem to find any instruction for how to accomplish that.
So, I borrowed the below code that I found online. It produces a running average but one that seems verrrry languid and resistant to my attempts to change it. In other words, the average seems to compute over the same (long) period regardless of whether I change RA_HIST_SECONDS from 30 down to 5 or even increase it to 60. I'll add that it's not important whether we take, say, 60 samples per second or a few as 2 or 3; I mention this because I have a feeling the frequency is part of the caper here.
I'd like to be able to adjust RA_HIST_SECONDS up or down to elongate or shorten how long of a running average I'm keeping each time I upload the sketch. I feel like I'm missing something totally basic. I'd appreciate any help you can give a newbie. Thanks!
//pressure vars
int pressure;
int pressureForRA;
int avgPressure = 0;
I looked through the code. I Never used the runningavarage-library.
I'm pretty good in mathematics but I did not get my head around it in some minutes.
So trying to help would mean to go and search for the documentation of the library.
I decided to not take this effort, because it is something you could provide as a link together with some demo-code that is running and you could provide serial output posted as a code-section so the others can see what the output looks like
When you are trying to filter out the vibrations of an airpump, then you need a mechanical damper.
So please tell us: What is your Arduino board ? Which pressure sensor is it ? What is your project ? Are there valves or long tubes and pressure peaks and is it with air or underwater and so on.
Tell us what you will do with the value of the pressure. Why do you need a average ? How much noise does it have ? Is the pressure value stored for a graph or is it only displayed and so on.
Whiles it is recommended of selecting a 'small' value for q does work, it's better to determine the amount of time passed since last calculation and update the q value before calculation. See posted example:
void TrackSun( void * pvParameters )
{
log_i( "Startup TrackSun" );
int64_t EndTime = esp_timer_get_time(); //gets time in uSeconds like Arduino Micros
int64_t StartTime = esp_timer_get_time(); // but rolls over every 207 years.
int Altitude = 1500;
int Azimuth = 900;
int maxAltitudeRange = 2144;
int minAltitudeRange = 900;
int maxAzimuthRange = 2144;
int minAzimuthRange = 900;
float AltitudeThreashold = 10.0f;
float AzimuthThreashold = 10.0f;
float kalmanThreshold = 80.0f;
// initial q value setting as a small value, .01.
SimpleKalmanFilter kfAltitude0( AltitudeThreshold, kalmanThreshold, .01 ); // kalman filter Altitude 0
SimpleKalmanFilter kfAltitude1( AltitudeThreshold, kalmanThreshold, .01 ); // kalman filter Altitude 1
SimpleKalmanFilter kfAzimuth0( AzimuthThreshold, kalmanThreshold, .01 ); // kalman filter Azimuth 0
SimpleKalmanFilter kfAzimuth1( AzimuthThreshold, kalmanThreshold, .01 ); // kalman filter Azimuth 1
float filteredAltitude_0 = 0.0f;
float filteredAltitude_1 = 0.0f;
float filteredAzimuth_0 = 0.0f;
float filteredAzimuth_1 = 0.0f;
uint64_t AzimuthEndTime = esp_timer_get_time();
uint64_t AzimuthStartTime = esp_timer_get_time(); //gets time in uSeconds like Arduino Micros,
uint64_t AltitudeEndTime = esp_timer_get_time();
uint64_t AltitudeStartTime = esp_timer_get_time(); //gets time in uSeconds like Arduino Micros,
int StartupCount = 0;
int TorqueAmmount = 5;
while (1)
{
if ( EnableTracking )
{
//Altitude
AltitudeEndTime = esp_timer_get_time() - AltitudeStartTime; // produce elapsed time for the simpleKalmanFilter
kfAltitude0.setProcessNoise( float(AltitudeEndTime) / 1000000.0f ); //q value being updated
kfAltitude1.setProcessNoise( float(AltitudeEndTime) / 1000000.0f );
filteredAltitude_0 = kfAltitude0.updateEstimate( (float)adc1_get_raw(ADC1_CHANNEL_6) );
filteredAltitude_1 = kfAltitude1.updateEstimate( (float)adc1_get_raw(ADC1_CHANNEL_5) );
if ( (filteredAltitude_0 > filteredAltitude_1) && (abs(filteredAltitude_0 - filteredAltitude_1) > AltitudeThreshold))
{
Altitude -= TorqueAmmount;
if ( Altitude < minAltitudeRange )
{
Altitude = 900;
}
fMoveAltitude( Altitude );
AltitudeStartTime = esp_timer_get_time();
}
if ( (filteredAltitude_0 < filteredAltitude_1) && (abs(filteredAltitude_0 - filteredAltitude_1) > AltitudeThreshold) )
{
Altitude += TorqueAmount;
if ( Altitude >= maxAltitudeRange )
{
Altitude = 900;
}
fMoveAltitude( Altitude );
AltitudeStartTime = esp_timer_get_time();
}
//// AZIMUTH
AzimuthEndTime = esp_timer_get_time() - AzimuthStartTime; // produce elapsed time for the simpleKalmanFilter
kfAzimuth0.setProcessNoise( float(AzimuthEndTime) / 1000000.0f ); //convert time of process to uS, update SimpleKalmanFilter q
kfAzimuth1.setProcessNoise( float(AzimuthEndTime) / 1000000.0f ); //convert time of process to uS, update SimpleKalmanFilter q
filteredAzimuth_0 = kfAzimuth0.updateEstimate( (float)adc1_get_raw(ADC1_CHANNEL_3) );
filteredAzimuth_1 = kfAzimuth1.updateEstimate( (float)adc1_get_raw(ADC1_CHANNEL_0) );
if ( (filteredAzimuth_0 > filteredAzimuth_1) && (abs(filteredAzimuth_0 - filteredAzimuth_1)) > AzimuthThreshold )
{
Azimuth += TorqueAmmount;
if ( Azimuth >= maxAzimuthRange )
{
Azimuth = 900;
}
fMoveAzimuth( Azimuth );
AzimuthStartTime = esp_timer_get_time();
}
if ( (filteredAzimuth_0 < filteredAzimuth_1) && (abs(filteredAzimuth_1 - filteredAzimuth_0)) > AzimuthThreshold )
{
Azimuth -= TorqueAmount; // make new position to torque to
if ( (Azimuth >= maxAzimuthRange) || (Azimuth <= minAzimuthRange) )
{
Azimuth = 900;
}
fMoveAzimuth( Azimuth );
AzimuthStartTime = esp_timer_get_time();
} //azmiuth end
if ( StartupCount < 500 )
{
++StartupCount;
} else {
TorqueAmount = 1;
}
}
vTaskDelay( 65 ); //non blocking delay.
} // while(1)
} //void TrackSun()
Thank you to all for the thoughtful responses. I learned quite a bit working through your suggestions. In the end, it seems like the problem was the serial communication rate! At 9600 the printouts to monitor or plotter were not at all matching the 30-second length of the running average I am trying to keep. At 115200, they sync up perfectly. Any ideas how could I adjust my code so they sync up at 9600? Thanks again to all.