root / toolbox / current.c @ f4df665c
History  View  Annotate  Download (1.94 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 
/* TODO reduce power consumption with DIDR* */

19  
20 
/*

21 
* COM1A = COM1B = 0, disconnect pins

22 
* WGM1 = 4, clear timer on compare A

23 
* CS1 = 5, 1024 prescaler

24 
*/

25 
TCCR1B = _BV(WGM12)  _BV(CS12)  _BV(CS10); 
26  
27 
/* Timer is cleared on A, ADC is triggered on B */

28 
OCR1A = F_CPU / 1024 / SAMPLES_PER_CYCLE / CYCLES_PER_SECOND;

29 
OCR1B = 0;

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 
/*

38 
* ADLAR = 0, right adjust result

39 
* ADTS = 5, start on timer 1 compare match B

40 
*/

41 
ADCSRB = _BV(ADTS2)  _BV(ADTS0); 
42  
43 
/*

44 
* ADEN = 1, enable

45 
* ADSC = 0, don't start yet

46 
* ADATE = 1, auto trigger

47 
* ADIE = 1, enable interrupt

48 
* ADPS = 4, prescale clock by 16

49 
*/

50 
ADCSRA = _BV(ADEN)  _BV(ADATE)  _BV(ADIE)  _BV(ADPS2); 
51 
} 
52  
53 
ISR(ADC_vect) { 
54 
unsigned int old, new; 
55  
56 
new = ADC; 
57  
58 
/* put sample into ring buffer */

59 
old = samples[sample_idx]; 
60 
samples[sample_idx++] = new; 
61 
if (sample_idx == N_SAMPLES)

62 
sample_idx = 0;

63  
64 
/* keep a running total of samples and samples squared */

65 
sum += new; 
66 
sum = old; 
67 
sum_sq += new*new; 
68 
sum_sq = old*old; 
69 
} 
70  
71 
/*unsigned char isqrt(unsigned int x) {

72 
unsigned int sqrt, mulmask;

73 
sqrt = 0;

74 
mulmask = 0x80;

75 
if (x > 0) {

76 
while (mulmask) {

77 
sqrt = mulmask;

78 
if (sqrt * sqrt > x)

79 
sqrt &= ~mulmask;

80 
mulmask >>= 1;

81 
}

82 
}

83 
return sqrt;

84 
}*/

85  
86 
unsigned int current_read() { 
87 
unsigned int _sum; 
88 
unsigned long _sum_sq; 
89  
90 
cli(); 
91 
_sum = sum; 
92 
_sum_sq = sum_sq; 
93 
sei(); 
94  
95 
/* calculate the variance using sum and sum_sq */

96 
return (N_SAMPLES*_sum_sq  _sum*_sum) / (N_SAMPLES*(N_SAMPLES1)); 
97 
} 