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_SAMPLES1)); 
99 
} 