 enum charger_mode {off, on, bulk, bat_float} charger_state;    // enumerated variable that holds state for charger state machine
 
 void set_pwm_duty(int pwm);
+
+//------------------------------------------------------------------------------------------------------
+// Circular buffer type for ADC averaging filter
+class LowPassBuffer {
+  public:
+    const static int N = 32;
+
+    void Init(void) {
+      data_len = 0;
+      current_pointer = 0;
+    }
+
+    void AddData(int x) {
+      buffer[current_pointer] = x;
+
+      current_pointer++;
+      if (current_pointer >= N) {
+        current_pointer = 0;
+      }
+
+      data_len++;
+      if (data_len > N) {
+        data_len = N;
+      }
+    }
+
+    int GetAverage() {
+      int sum = 0;
+      for (uint8_t i=0; i<data_len;i++) {
+        sum += buffer[i];
+      }
+
+      return (sum / data_len);
+    }
+        
+  private:
+    int buffer[N];
+    uint8_t data_len;
+    uint8_t current_pointer;
+};
+
+LowPassBuffer lpf_in_volts;
+LowPassBuffer lpf_in_amps;
+LowPassBuffer lpf_out_volts;
 
 //------------------------------------------------------------------------------------------------------
 // This routine is automatically called at powerup/reset

#define PWM_MAX             0.9*PWM_FULL  // the value for pwm duty cyle 0-100.0% (Resolution in 
#define PWM_MIN             0.1*PWM_FULL  // the value for pwm duty cyle 0-100.0%
#define PWM_START           0.1*PWM_FULL  // the value for pwm duty cyle 0-100.0%
#define PWM_INC             1             // the value the increment to the pwm value for the ppt algorithm

#define AVG_NUM             8             // number of iterations of the adc routine to average the adc readings
#define SOL_AMPS_SCALE      0.5           // the scaling value for raw adc reading to get solar amps scaled by 100 [(1/(0.005*(3.3k/25))*(5/1023)*100]

// watts from the solar amps times the solar voltage and rounds and scales that by 100 (2 decimal places) also.
//------------------------------------------------------------------------------------------------------
void read_data(void) {

  lpf_in_volts.AddData(  analogRead(ADC_SOL_VOLTS_CHAN) );
  lpf_out_volts.AddData( analogRead(ADC_BAT_VOLTS_CHAN) );
  lpf_in_amps.AddData(   analogRead(ADC_SOL_AMPS_CHAN) );

  power_status.sol_amps =  SOL_AMPS_SCALE * lpf_in_amps.GetAverage();
  power_status.sol_volts = SOL_VOLTS_SCALE * lpf_in_volts.GetAverage();
  power_status.bat_volts = BAT_VOLTS_SCALE * lpf_out_volts.GetAverage();
  power_status.sol_watts = (int)((((long)power_status.sol_amps * (long)power_status.sol_volts) + 50) / 100);    //calculations of solar watts scaled by 10000 divide by 100 to get scaled by 100                 

//  power_status.sol_amps =  SOL_AMPS_SCALE * read_adc(ADC_SOL_AMPS_CHAN) ;// * read_adc(ADC_SOL_AMPS_CHAN); //((read_adc(ADC_SOL_AMPS_CHAN)  * SOL_AMPS_SCALE) + 5) / 10;    //input of solar amps result scaled by 100
//  power_status.sol_volts = SOL_VOLTS_SCALE * read_adc(ADC_SOL_VOLTS_CHAN); //((read_adc(ADC_SOL_VOLTS_CHAN) * SOL_VOLTS_SCALE) + 5) / 10;   //input of solar volts result scaled by 100
//  power_status.bat_volts = BAT_VOLTS_SCALE * read_adc(ADC_BAT_VOLTS_CHAN); // ((read_adc(ADC_BAT_VOLTS_CHAN) * BAT_VOLTS_SCALE) + 5) / 10;   //input of battery volts result scaled by 100
//  power_status.sol_watts = (int)((((long)power_status.sol_amps * (long)power_status.sol_volts) + 50) / 100);    //calculations of solar watts scaled by 10000 divide by 100 to get scaled by 100                 
}
//------------------------------------------------------------------------------------------------------
// This routine is the charger state machine. It has four states on, off, bulk and float.
