Statistics
| Branch: | Revision:

root / toolbox / current.c @ cbda92cc

History | View | Annotate | Download (1.88 KB)

1
#include "current.h"
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <math.h>
5

    
6
#define CYCLES_PER_SECOND 60 // wall power
7
#define SAMPLES_PER_CYCLE 10
8
#define N_SAMPLES 20
9

    
10
unsigned int samples[N_SAMPLES];
11
int sample_idx;
12

    
13
unsigned int sum;
14
unsigned long sum_sq;
15

    
16
void current_init() {
17

    
18
  /*
19
   * COM0A = 0, disconnect pin
20
   * WGM0 = 2, clear timer on compare
21
   */
22
  TCCR0A |= _BV(WGM01);
23

    
24
  /*
25
   * CS0 = 5, 1024 prescaler
26
   */
27
  TCCR0B |= _BV(CS02) | _BV(CS00);
28

    
29
  OCR0A = F_CPU / 1024 / SAMPLES_PER_CYCLE / CYCLES_PER_SECOND;
30

    
31
  /*
32
   * REFS = 0, Vcc reference (set to 2 for internal 1.1V reference)
33
   * MUX = 8, PB3(ADC8)
34
   */
35
  ADMUX = _BV(MUX3);
36

    
37
  /* TODO reduce power consumption with DIDR* */
38

    
39
  /*
40
   * ADLAR = 0, right adjust result
41
   * ADTS = 3, start on timer 0 compare match A
42
   */
43
  ADCSRB = _BV(ADTS1) | _BV(ADTS0);
44

    
45
  /*
46
   * ADEN = 1, enable
47
   * ADSC = 0, don't start yet
48
   * ADATE = 1, auto trigger
49
   * ADIE = 1, enable interrupt
50
   * ADPS = 4, prescale clock by 16
51
   */
52
  ADCSRA |= _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2);
53
}
54

    
55
ISR(ADC_vect) {
56
  unsigned int old, new;
57

    
58
  new = ADC;
59

    
60
  /* put sample into ring buffer */
61
  old = samples[sample_idx];
62
  samples[sample_idx++] = new;
63
  if (sample_idx == N_SAMPLES)
64
    sample_idx = 0;
65

    
66
  /* keep a running total of samples and samples squared */
67
  sum += new;
68
  sum -= old;
69
  sum_sq += new*new;
70
  sum_sq -= old*old;
71
}
72

    
73
/*unsigned char isqrt(unsigned int x) {
74
  unsigned int sqrt, mulmask;
75
  sqrt = 0;
76
  mulmask = 0x80;
77
  if (x > 0) {
78
    while (mulmask) {
79
      sqrt |= mulmask;
80
      if (sqrt * sqrt > x)
81
        sqrt &= ~mulmask;
82
      mulmask >>= 1;
83
    }
84
  }
85
  return sqrt;
86
}*/
87

    
88
unsigned int current_read() {
89
  unsigned int _sum;
90
  unsigned long _sum_sq;
91

    
92
  cli();
93
  _sum = sum;
94
  _sum_sq = sum_sq;
95
  sei();
96

    
97
  /* calculate the variance using sum and sum_sq */
98
  return (N_SAMPLES*_sum_sq - _sum*_sum) / (N_SAMPLES*(N_SAMPLES-1));
99
}