Compare Signal to Noise Ratio

enum { LED_ANODE=PIN3, LED_CATHODE=PIN2 };

void
charge_led_capacitance( void )
{
  pinMode( LED_ANODE, OUTPUT );       // Set both pins
  pinMode( LED_CATHODE, OUTPUT );     // to be outputs
  digitalWrite( LED_ANODE, LOW );     // Set one low
  digitalWrite( LED_CATHODE, HIGH );  // and the other high, so LED is reverse-biased (no light)
}

void
set_input_mode( void )
{
  pinMode( LED_CATHODE, INPUT );      // Set the pin to read mode
  digitalWrite( LED_CATHODE, LOW );   // Turn off the internal pull-up resistor on the pin
}

unsigned
read_light_level( void )
{
  charge_led_capacitance();
  set_input_mode();

  unsigned level = 0;
  for( ; level < 30000; level++ )
    if( digitalRead( LED_CATHODE ) == 0 )
      break;
  return level;
}

class Voltage
{
  enum { SENSOR_PIN = A0 };
public:
  float
  read( void )
  {
    return 5.0 * analogRead( SENSOR_PIN ) / 1024;
  }
} voltage;

class Stats
{
  unsigned long n;
  double mean;
  double variance;
  double sum;
public:
  Stats( void )
  {
    n = 0; mean = 0; variance = 0; sum = 0;
  }
  void sample( double s )
  {
    double delta = s - mean;
    n++;
    mean += delta / n;
    sum += delta * delta;
  }
  double get_mean( void ) { return mean; }
  double get_variance( void ) { return sum / n; }
  double get_sd( void ) { return sqrt( sum / n ); }
  double get_snr( void ) { return get_mean() / get_sd(); }
};

Stats digital_stats;
Stats analog_stats;

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

unsigned long x = 0;

void
loop( void )
{
  unsigned digital = read_light_level();
  digital_stats.sample( digital );
  
  float analog = voltage.read();
  analog_stats.sample( analog );

  Serial.print( x++ );
  Serial.print( ":   Digital " );
  Serial.print( digital );
  Serial.print( ", Mean=" );
  Serial.print( digital_stats.get_mean(), 4 );
  Serial.print( ", SD=" );
  Serial.print( digital_stats.get_sd(), 4 );
  Serial.print( ", SNR=" );
  Serial.print( digital_stats.get_snr(), 4 );
  Serial.print( ",    Analog " );
  Serial.print( analog, 3 );
  Serial.print( ", Mean=" );
  Serial.print( analog_stats.get_mean(), 4 );
  Serial.print( ", SD=" );
  Serial.print( analog_stats.get_sd(), 4 );
  Serial.print( ", SNR=" );
  Serial.println( analog_stats.get_snr(), 4 );  
}