Calculate Average Reading from TMP36

Hey All,
I've been working on this all morning and getting nowhere. If you've ever worked with the TMP36 you've probably found it to give unstable readings. I'm trying to address this by averaging several readings, I've read this is what's called a low pass filter. I'm trying to mash together the basic TMP36 sketch from Sparkfun and a low pass script that I found. I've verified the sensor is hooked up correctly but when I try to calculate the average it gives crazy numbers.

How can I calculate and report an average of X number of reads using Arduino and the tmp36.

Thanks
Rich

// Define the number of samples to keep track of. The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input. Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 100;

int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int temperature = 0;
int temperaturePin = A0;

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;
}

void loop() {

// subtract the last reading:
total= total - readings[index];
// read from the sensor:
temperature = getVoltage(temperaturePin); //getting the voltage reading from the temperature sensor
readings[index] = temperature;
// add the reading to the total:
total= total + readings[index];
// advance to the next position in the array:
index = index + 1;

// if we're at the end of the array...
if (index >= numReadings)
// ...wrap around to the beginning:
index = 0;

// calculate the average:
average = total / numReadings;

// average = temperature;
// temperature = getVoltage(temperaturePin); //getting the voltage reading from the temperature sensor
temperature = (temperature - 0.42) * 100; // converting from 10 mv per degree with 500 mV offset
temperature = (((temperature*1.8)+32)-6.5); // convert c to f

// send it to the computer as ASCII digits
Serial.println(average);

Serial.print(temperature); //printing the result
Serial.println(" f");
delay(1000);

}
/*

  • getVoltage() - returns the voltage on the analog input defined by
  • pin
    */
    float getVoltage(int pin){
    return (analogRead(pin) * .004882814); //converting from a 0 to 1023 digital range
    // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
    }

richiep:
temperature = (((temperature*1.8)+32)-6.5); // convert c to f

Example of why you use the CODE tags when trying to post code.

// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 100;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int temperature = 0;
int temperaturePin = A0;

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;          
}

void loop() {
  
  // subtract the last reading:
  total= total - readings[index];        
  // read from the sensor:  
  temperature = getVoltage(temperaturePin);  //getting the voltage reading from the temperature sensor
  readings[index] = temperature;
  // add the reading to the total:
  total= total + readings[index];      
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning:
    index = 0;                          

  // calculate the average:
  average = total / numReadings;        
  
//  average = temperature; 
  // temperature = getVoltage(temperaturePin);  //getting the voltage reading from the temperature sensor
  temperature = (temperature - 0.42) * 100;  // converting from 10 mv per degree with 500 mV offset
  temperature = (((temperature*1.8)+32)-6.5); // convert c to f
  
  // send it to the computer as ASCII digits
  Serial.println(average);  

  Serial.print(temperature);                     //printing the result
  Serial.println(" f");
  delay(1000);   

}
/*
 * getVoltage() - returns the voltage on the analog input defined by
 * pin
 */
float getVoltage(int pin){
 return (analogRead(pin) * .004882814); //converting from a 0 to 1023 digital range
                                        // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
}

[code]

[/code]

How about?

int averageReading = 0;
for (int n = 0; n < numReadings; n++) averageReading += getvoltage(temperaturePin);
averageReading /= numReadings;

Does that make sense? I'd change the getvoltage() function to just return a temp and put the math that converts the voltage into a temp in there.

You're taking 100 readings. Those 100 readings are stored in total, which is an int. An int can only store up to +32,767. That means that if your values average above 327, you're going to have issues.

Either store less readings, or use a long as your total instead of an int.

Arrch is correct. Storing numbers in a memory space too small to fit them means big trouble.

I am always using this simple smoother (low pass filter):

old_value = read_voltage() //or a good value if you know it

in a loop:
new_value = read_voltage()
new_value = A * new_value + B * old_value
..
old_value = new_value
endloop

Where A+B=1.0, the smaller the A the stronger the filtering/smoothing effect.
For example A=0.1, B=0.9
p.