Analog sensor averaging....?

I am trying to figure what the perfect sensor reading is to set a trigger point in another program so I set up this little bit of code to log the sensor reading every 5 minutes. But it seems like the readings are a little more up and down than they should be.

Right now the program is simply serial printing the sensor reading every 5 minutes. What I would like is have it print the average of 5 minutes of readings sampled every couple of seconds or so.

Thanks

int sensorPin = A0; // select the input pin for LDR

int sensorValue = 0; // variable to store the value coming from the sensor
void setup() {
Serial.begin(9600); //sets serial port for communication
}
void loop() {
sensorValue = analogRead(sensorPin); // read the value from the sensor
Serial.println(sensorValue); //prints the values coming from the sensor on the screen

delay(300000);

How do you calculate an average?

Just make sure you sum the readings into a large enough variable.

Newbie here! Not real sure what you are saying....

al_duino_nano:
I am trying to figure what the perfect sensor reading is to set a trigger point in another program so I set up this little bit of code to log the sensor reading every 5 minutes. But it seems like the readings are a little more up and down than they should be.

Right now the program is simply serial printing the sensor reading every 5 minutes. What I would like is have it print the average of 5 minutes of readings sampled every couple of seconds or so.

Thanks

int sensorPin = A0; // select the input pin for LDR

int sensorValue = 0; // variable to store the value coming from the sensor
void setup() {
Serial.begin(9600); //sets serial port for communication
}
void loop() {
sensorValue = analogRead(sensorPin); // read the value from the sensor
Serial.println(sensorValue); //prints the values coming from the sensor on the screen

delay(300000);

Suppose you take a sample once every 100mS. In 5-minutes there are 3000 100mS periods (300 seconds in 5 minutes x 10 100mS periods/second...)

If your sensor read the maximum for every read you would see a sum of 3000 x 1023 or 3,069,000; you'll need a long or unsigned long to store 5 minutes' worth of readings.

A five minute period of sampling and averaging could be done with something like:

const byte sensorpin = A0;
unsigned long
    sensorSum;
float
    sensorAvg;
    
void setup( void )
{
    Serial.begin(9600);
    pinMode( sensorpin, INPUT );
    sensorSum = 0ul;
    
}//setup

void loop( void )
{
    static unsigned long
        timeSample = 0;
    static int
        numSamples = 0;
    unsigned long
        timeNow;

    timeNow = millis();
    if( timeNow - timeSample >= 100 )
    {
        timeSample = timeNow;
        
        sensorSum = sensorSum + (unsigned long)analogRead( sensorpin );
        numSamples++;
        
        if( numSamples == 3000 )
        {
            sensorAvg = (float)sensorSum / 3000.0;
            Serial.print( "Sensor average: " );
            Serial.println(sensorAvg);
            
            numSamples = 0ul;
             
        }//if
        
    }//if
    
}//loop

I'd be surprised if you really need hundreds or thousands of samples.

Perhaps you could keep a record of the last 30 reads in an array and update once every hundred milliseconds:

#define NUM_SAMPLES     30
#define SAMPLE_PERIOD   100ul

const byte sensorpin = A0;

int
    sensorSum,                      //sum of 30 1023 readings will squeeze into an int
    sensorReading,
    sensorArray[NUM_SAMPLES];
float
    sensorAvg;
    
void setup( void )
{
    Serial.begin(9600);
    pinMode( sensorpin, INPUT );
    
    sensorReading = analogRead( sensorpin );    //initialize the array with the first reading
    for( int i=0; i<NUM_SAMPLES; i++ )
        sensorArray[i] = sensorReading;
    sensorSum = sensorReading * NUM_SAMPLES;    //initial sum will be NUM_SAMPLES x the first reading
    
}//setup

void loop( void )
{
    static unsigned long
        timeSample = 0;
    unsigned long
        timeNow;

    timeNow = millis();
    if( (timeNow - timeSample) >= SAMPLE_PERIOD )
    {
        timeSample = timeNow;
        
        sensorReading = analogRead( sensorpin );            //read the sensor
        
        sensorSum -= sensorArray[0];                        //subtract the value of the oldest table entry about to be removed
        sensorSum += sensorReading;                         //add in the new reading
        sensorAvg = (float)sensorSum / (float)NUM_SAMPLES;  //compute the new average
        
        Serial.print( "Sensor average: " );                 //print it
        Serial.println(sensorAvg);
        
        for( int i=1; i<NUM_SAMPLES; i++ )                  //drop the oldest reading & move every reading down one...
            sensorArray[i-1] = sensorArray[i];
        sensorArray[NUM_SAMPLES-1] = sensorReading;         //...and add the newest reading to the end
        
    }//if
    
}//loop

Blackfin....Thank you Sir!

I am running a few test using your 30 sample option.

The next test will be to implement it in the other code....wish me luck!

Thanks again!
Al

       for( int i=1; i<NUM_SAMPLES; i++ )                  //drop the oldest reading & move every reading down one...
            sensorArray[i-1] = sensorArray[i];
        sensorArray[NUM_SAMPLES-1] = sensorReading;         //...and add the newest reading to the end

It should be said that it is a lot simpler, and a lot less wasteful of processor cycles, to maintain a circular buffer with simple arithmetic of indices, than actually moving readings around memory.

AWOL:

       for( int i=1; i<NUM_SAMPLES; i++ )                  //drop the oldest reading & move every reading down one...

sensorArray[i-1] = sensorArray[i];
        sensorArray[NUM_SAMPLES-1] = sensorReading;        //...and add the newest reading to the end


It should be said that it is a lot simpler, and a lot less wasteful of processor cycles, to maintain a circular buffer with simple arithmetic of indices, than actually moving readings around memory.

A very good point.

Dearest Blackfin or whoever might be code savvy....

Blackfins datalogging code (reposted below) works well....but the data I am looking at is time specific so I have been trying to figure how to use the time.h library to add a time stamp line to the serial print.

I have tried several times but I keep breaking the code with syntax errors and other noob mistakes.

I am trying to add at least the hour and minute of the day to each line....I have edited the original code to return fewer prints per day but that is it.

#define NUM_SAMPLES     30
#define SAMPLE_PERIOD   100ul

const byte sensorpin = A0;

int
    sensorSum,                      //sum of 30 1023 readings will squeeze into an int
    sensorReading,
    sensorArray[NUM_SAMPLES];
   
float
    sensorAvg;
    
void setup( void )
{
    Serial.begin(9600);
    pinMode( sensorpin, INPUT );
    
    sensorReading = analogRead( sensorpin );    //initialize the array with the first reading
    for( int i=0; i<NUM_SAMPLES; i++ )
        sensorArray[i] = sensorReading;
    sensorSum = sensorReading * NUM_SAMPLES;    //initial sum will be NUM_SAMPLES x the first reading
    
}//setup

void loop( void )
{
    static unsigned long
        timeSample = 0;
    unsigned long
        timeNow;

    timeNow = millis();
    if( (timeNow - timeSample) >= SAMPLE_PERIOD )
    {
        timeSample = timeNow;
        
        sensorReading = analogRead( sensorpin );            //read the sensor
        
        sensorSum -= sensorArray[0];                        //subtract the value of the oldest table entry about to be removed
        sensorSum += sensorReading;                         //add in the new reading
        sensorAvg = (float)sensorSum / (float)NUM_SAMPLES;  //compute the new average
        
        Serial.print( "Sensor average: " );                 //print it
        Serial.println(sensorAvg);
       
        delay(172800);
        for( int i=1; i<NUM_SAMPLES; i++ )                  //drop the oldest reading & move every reading down one...
            sensorArray[i-1] = sensorArray[i];
        sensorArray[NUM_SAMPLES-1] = sensorReading;         //...and add the newest reading to the end
        
    }//if
    
}//loop

Are you willing to add a RTC (realtime clock) to the system?

I could...but aren't there apps that will make the clock data from the computer available to the arduino? Or maybe sync to a website?

I understand that an RTC will make it more versatile and portable....but this little system will always be hooked to either my PC or laptop and the data is logged to the serial monitor.

You can also add removal of large discrepancy values i.e. too high and too low.

This helps in removing noisy abnormal readings.