use running sum of 1<<6 measurements, and do only one measurement
per loop in order to not disturb other measurements. Also, do not log
timer overruns for ADC, as we do most of the processing in ADC IRQs now.
static uint16_t adc_sum;
static unsigned char sum_shift;
static unsigned char adc_vals;
static uint16_t adc_sum;
static unsigned char sum_shift;
static unsigned char adc_vals;
-static uint16_t adc1_gain20_offset_x16;
+#define ADC1_GAIN20_OFFSET_SHIFT 6
+static uint16_t adc1_gain20_offset;
static void inline setup_mux(unsigned char n)
{
static void inline setup_mux(unsigned char n)
{
break;
case 2: // pwmled 3: 1.1V, ADC4 (PA5), single-ended
ADMUX = _BV(REFS1) | _BV(MUX2);
break;
case 2: // pwmled 3: 1.1V, ADC4 (PA5), single-ended
ADMUX = _BV(REFS1) | _BV(MUX2);
- sum_shift = 2; // 4 measurements
+ sum_shift = 3; // 8 measurements
break;
case 3: // ambient light: 1.1V, ADC5 (PA6), single-ended
ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX0);
break;
case 3: // ambient light: 1.1V, ADC5 (PA6), single-ended
ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX0);
break;
case 5: // gain stage offset: 1.1V, ADC1,1, gain 20
ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);
break;
case 5: // gain stage offset: 1.1V, ADC1,1, gain 20
ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX0);
- sum_shift = 3; // 8 measurements
+ sum_shift = 0; // 1 measurement
;
ADCSRA |= _BV(ADIF); // clear the IRQ flag
;
ADCSRA |= _BV(ADIF); // clear the IRQ flag
- adc1_gain20_offset_x16 = 0;
+ adc1_gain20_offset = 0;
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < (1 << ADC1_GAIN20_OFFSET_SHIFT); i++) {
ADCSRA |= _BV(ADSC);
while ((ADCSRA & _BV(ADIF)) == 0)
;
ADCSRA |= _BV(ADSC);
while ((ADCSRA & _BV(ADIF)) == 0)
;
- adc1_gain20_offset_x16 += ADCW;
+ adc1_gain20_offset += ADCW
+ - (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT);
ADCSRA |= _BV(ADIF); // clear the IRQ flag
}
ADCSRA |= _BV(ADIF); // clear the IRQ flag
}
if (current_adc == ADC1_GAIN20) {
// running average
if (current_adc == ADC1_GAIN20) {
// running average
- adc1_gain20_offset_x16 += adcval
- - (adc1_gain20_offset_x16 >> 4);
+ adc1_gain20_offset += adcval
+ - (adc1_gain20_offset >> ADC1_GAIN20_OFFSET_SHIFT);
} else if (current_adc == 0 || current_adc == 1) {
} else if (current_adc == 0 || current_adc == 1) {
- uint16_t offset = adc1_gain20_offset_x16 >> 4;
- if (adcval >= offset)
- adcval -= offset;
+ uint16_t offset = adc1_gain20_offset
+ >> (ADC1_GAIN20_OFFSET_SHIFT - sum_shift);
+ if (adc_sum > offset)
+ adc_sum -= offset;
}
if (current_adc < N_PWMLEDS)
}
if (current_adc < N_PWMLEDS)
- pwmled_adc(current_adc, adcval);
+ pwmled_adc(current_adc, adc_sum);
if (current_adc == AMBIENT_ADC)
ambient_adc(adcval);
if (current_adc == BATTERY_ADC)
if (current_adc == AMBIENT_ADC)
ambient_adc(adcval);
if (current_adc == BATTERY_ADC)
{
if (current_adc == NUM_ADCS) // Don't start if in progress
start_next_adc();
{
if (current_adc == NUM_ADCS) // Don't start if in progress
start_next_adc();