Web Thermometer

# include <math.h>

void
setup()
{
  Serial.begin( 115200 );
}

class Circular
{
  double samples[ 200 ];
  long int count;
  double mean_value;
  double standard_deviation;
  double variance;
  enum { COUNT = (sizeof samples / sizeof *samples) };
  
public:
  Circular( void ) { count = 0; }
  void store( double value ) { samples[ count++ % (sizeof samples / sizeof *samples) ] = value; }
  
  void
  calculate_statistics( void )
  {
    double sum = 0;
    int cnt = min( count, COUNT );
    for( int i = 0; i < cnt; i++ )
      sum += samples[ i ];

    mean_value = sum / cnt;

    variance = 0;

    for( int i = 0; i < cnt; i++ )
    {
      double deviation = samples[ i ] - mean_value;
      variance += deviation * deviation;
    }

    variance /= ( cnt - 1 );
    standard_deviation = sqrt( variance );
  }
  
  double mean( void ) { return mean_value; }
  double std_dev( void ) { return standard_deviation; }
  double var( void ) { return variance; }
  int num_samples( void ) { return min( count, COUNT ); }
  int max_samples( void ) { return COUNT; }
};

double CALIBRATION_OFFSET = -0.39444;

class Temperature
{
  int raw_adc;
public:
  int raw( int pin ) { return raw_adc = analogRead( pin ); }
  int raw( void ) { return raw_adc; }
  
  double
  kelvin( void )
  {
    double Temp = log( 10000.0 * ( ( 1024.0 / raw_adc - 1 ) ) ); 
    return 1.0 / ( 0.001129148 + ( 0.000234125
      + ( 0.0000000876741 * Temp * Temp ) ) * Temp ) + CALIBRATION_OFFSET;
  }

  double celsius( void ) { return kelvin() - 273.15; }
  double fahrenheit( void ) { return kelvin() * 1.8 - 459.67; }
};

Circular buffer;
Temperature temperature;

void
loop()
{
  for( int i = 0; i < buffer.max_samples(); i++ )
  {
    temperature.raw( A0 );
    buffer.store( temperature.fahrenheit() );
  }

  buffer.calculate_statistics();

  Serial.print( "<style>h1, h2 { text-align: center }</style>" );
  Serial.print( "<h1>Average: " );
  Serial.print( buffer.mean() );
  Serial.print( " degrees F" );

  Serial.print( " (Standard deviation: " );
  Serial.print( buffer.std_dev() );
  Serial.println( " degrees F)</h1>" );

  double three_nines = (3.290527 * buffer.std_dev()) / 2;
  Serial.print( "<h2>We are 99.9% certain that the temperature is between " );
  Serial.print( buffer.mean() - three_nines );
  Serial.print( " and " );
  Serial.print( buffer.mean() + three_nines );
  Serial.println( " degrees Fahrenheit</h2>" );
 
  delay( 30000 );
}