Statistics
| Branch: | Revision:

root / toolbox / current.c @ db11713d

History | View | Annotate | Download (2.1 KB)

1 10936c07 Tom Mullins
#include "current.h"
2
#include <avr/io.h>
3 cbda92cc Tom Mullins
#include <avr/interrupt.h>
4
#include <math.h>
5
6
#define CYCLES_PER_SECOND 60 // wall power
7 975af07c Tom Mullins
#define SAMPLES_PER_CYCLE 16
8
#define N_SAMPLES 48
9 cbda92cc Tom Mullins
10
unsigned int samples[N_SAMPLES];
11
int sample_idx;
12
13
unsigned int sum;
14
unsigned long sum_sq;
15 10936c07 Tom Mullins
16
void current_init() {
17 cbda92cc Tom Mullins
18 f4df665c Tom Mullins
  /* TODO reduce power consumption with DIDR* */
19 cbda92cc Tom Mullins
20
  /*
21 f4df665c Tom Mullins
   * COM1A = COM1B = 0, disconnect pins
22
   * WGM1 = 4, clear timer on compare A
23 db11713d Tom Mullins
   * CS1 = 1, no prescaler
24 cbda92cc Tom Mullins
   */
25 db11713d Tom Mullins
  TCCR1B = _BV(WGM12) | _BV(CS10);
26 cbda92cc Tom Mullins
27 f4df665c Tom Mullins
  /* Timer is cleared on A, ADC is triggered on B */
28 db11713d Tom Mullins
  OCR1A = F_CPU / SAMPLES_PER_CYCLE / CYCLES_PER_SECOND;
29
  OCR1B = OCR1A;
30 cbda92cc Tom Mullins
31 10936c07 Tom Mullins
  /*
32
   * REFS = 0, Vcc reference (set to 2 for internal 1.1V reference)
33
   * MUX = 8, PB3(ADC8)
34
   */
35
  ADMUX = _BV(MUX3);
36 db11713d Tom Mullins
  DIDR1 |= _BV(ADC8D);
37 cbda92cc Tom Mullins
38 10936c07 Tom Mullins
  /*
39
   * ADLAR = 0, right adjust result
40 f4df665c Tom Mullins
   * ADTS = 5, start on timer 1 compare match B
41 10936c07 Tom Mullins
   */
42 f4df665c Tom Mullins
  ADCSRB = _BV(ADTS2) | _BV(ADTS0);
43 cbda92cc Tom Mullins
44 10936c07 Tom Mullins
  /*
45
   * ADEN = 1, enable
46 cbda92cc Tom Mullins
   * ADSC = 0, don't start yet
47 10936c07 Tom Mullins
   * ADATE = 1, auto trigger
48 cbda92cc Tom Mullins
   * ADIE = 1, enable interrupt
49 db11713d Tom Mullins
   * ADPS = 6, prescale clock by 64
50 10936c07 Tom Mullins
   */
51 db11713d Tom Mullins
  ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1);
52 10936c07 Tom Mullins
}
53
54 cbda92cc Tom Mullins
ISR(ADC_vect) {
55
  unsigned int old, new;
56
57 db11713d Tom Mullins
  /* clear the timer interrupt flag so that the ADC will be triggered again
58
   * next time the timer resets */
59
  TIFR |= _BV(OCF1B);
60
61 cbda92cc Tom Mullins
  new = ADC;
62
63
  /* put sample into ring buffer */
64
  old = samples[sample_idx];
65
  samples[sample_idx++] = new;
66
  if (sample_idx == N_SAMPLES)
67
    sample_idx = 0;
68
69
  /* keep a running total of samples and samples squared */
70
  sum += new;
71
  sum -= old;
72
  sum_sq += new*new;
73
  sum_sq -= old*old;
74
}
75
76
/*unsigned char isqrt(unsigned int x) {
77
  unsigned int sqrt, mulmask;
78
  sqrt = 0;
79
  mulmask = 0x80;
80
  if (x > 0) {
81
    while (mulmask) {
82
      sqrt |= mulmask;
83
      if (sqrt * sqrt > x)
84
        sqrt &= ~mulmask;
85
      mulmask >>= 1;
86
    }
87
  }
88
  return sqrt;
89
}*/
90
91
unsigned int current_read() {
92
  unsigned int _sum;
93
  unsigned long _sum_sq;
94
95
  cli();
96
  _sum = sum;
97
  _sum_sq = sum_sq;
98
  sei();
99
100
  /* calculate the variance using sum and sum_sq */
101 975af07c Tom Mullins
  return (N_SAMPLES*_sum_sq - (unsigned long)_sum*_sum) /
102
    (N_SAMPLES*(N_SAMPLES-1));
103 10936c07 Tom Mullins
}