-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReadADC.ino
131 lines (114 loc) · 4.39 KB
/
ReadADC.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
#include <avr/io.h>
#include <stdlib.h>
#include "Transistortester.h"
#include "Makefile.h" //J-L
*/
/*
extern struct ADCconfig_t{
uint8_t Samples; // number of ADC samples to take
uint8_t RefFlag; // save Reference type VCC of IntRef
uint16_t U_Bandgap; // Reference Voltage in mV
uint16_t U_AVCC; // Voltage of AVCC
} ADCconfig;
*/
#ifdef INHIBIT_SLEEP_MODE
// #define StartADCwait() ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV; /* enable ADC and start */
#define StartADCwait() ADCSRA = (1<<ADSC)|(1<<ADEN)|(1<<ADIF)|AUTO_CLOCK_DIV; /* Start conversion */\
while (ADCSRA & (1 << ADSC)); /* wait until conversion is done */
#else
#define StartADCwait() ADCSRA = (1<<ADEN) | (1<<ADIF) | (1<<ADIE) | AUTO_CLOCK_DIV; /*enable ADC and Interrupt */\
set_sleep_mode(SLEEP_MODE_ADC);\
sleep_mode(); /* Start ADC, return, if ADC has finished */
#endif
/***********************************************************************************/
/* ReadADC takes ADCconfig.Samples ADC reads and build a sum of the data */
/* One ADC read take a time period about 112us. */
/* So 25 ADC reads take more than 2.8ms time. */
/* for resistor and other measurements 190 ADC reads are done with more than 21ms */
unsigned int ReadADC (uint8_t Probe) {
unsigned int U; /* return value (mV) */
uint8_t samples; /* loop counter */
unsigned long Value; /* ADC value */
Probe |= (1 << REFS0); /* use internal reference anyway */
#ifdef AUTOSCALE_ADC
get_sample:
#endif /* AUTOSCALE_ADC */
#if (PROCESSOR_TYP == 644) || (PROCESSOR_TYP == 1280)
if (Probe & (1 << REFS1)) Probe &= ~(1<<REFS0); /* ATmega640/1280/2560 1.1V Reference with REFS0=0 */
#endif
ADMUX = Probe; /* set input channel and U reference */
#ifdef AUTOSCALE_ADC
/* if voltage reference changes, wait for voltage stabilization */
if ((Probe & (1<<REFS1)) != ADCconfig.RefFlag) {
// Reference is switched, delay depends on NO_AREF_CAP option
ADCconfig.RefFlag = (Probe & (1<<REFS1)); // save new reference state
#ifdef NO_AREF_CAP
wait100us(); /* time for voltage stabilization */
#else
wait_about10ms(); /* time for voltage stabilization */
#endif
// allways do one dummy read of ADC, 112us
StartADCwait(); /* start ADC and wait */
}
#endif /* AUTOSCALE_ADC */
/* * sample ADC readings */
Value = 0UL; /* reset sampling variable */
samples = 0; /* number of samples to take */
while (samples < ADCconfig.Samples) /* take samples */ {
StartADCwait(); /* start ADC and wait */
Value += ADCW; /* add ADC reading */
#ifdef AUTOSCALE_ADC
/* auto-switch voltage reference for low readings */
if ((samples == 4) && (ADCconfig.U_Bandgap > 255) && ((uint16_t)Value < 1024) && !(Probe & (1<<REFS1))) {
Probe |= (1 << REFS1); /* select internal bandgap reference */
goto get_sample; /* re-run sampling */
}
#endif
samples++; /* one more done */
} /* end while */
#ifdef AUTOSCALE_ADC
/* * convert ADC reading to voltage * - single sample: U = ADC reading * U_ref / 1024 */
/* get voltage of reference used */
if (Probe & (1 << REFS1)) U = ADCconfig.U_Bandgap; /* bandgap reference */
else U = ADCconfig.U_AVCC; /* Vcc reference */
#else
U = ADCconfig.U_AVCC; /* Vcc reference */
#endif
/* convert to voltage; */
Value *= U; /* ADC readings * U_ref */
Value /= 1023; /* / 1024 for 10bit ADC */
/* de-sample to get average voltage */
Value /= ADCconfig.Samples;
U = (unsigned int)Value;
return U;
// return ((unsigned int)(Value / (1023 * (unsigned long)ADCconfig.Samples)));
}
unsigned int W5msReadADC (uint8_t Probe) {
wait_about5ms();
return (ReadADC(Probe));
}
unsigned int W10msReadADC (uint8_t Probe) {
wait_about10ms();
return (ReadADC(Probe));
}
unsigned int W20msReadADC (uint8_t Probe) {
wait_about20ms();
return (ReadADC(Probe));
}
uint16_t unsigned_diff(uint16_t v1, uint16_t v2)
{
if (v1 > v2) return (v1 - v2);
else return (0);
}
uint16_t abs_diff(uint16_t v1, uint16_t v2)
{
if (v1 > v2) return (v1 - v2);
else return (v2 - v1);
}
uint16_t vcc_diff(uint16_t v2)
{
return unsigned_diff(ADCconfig.U_AVCC, v2);
// if (ADCconfig.U_AVCC > v2) return (ADCconfig.U_AVCC - v2);
// else return (0);
}