-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathADC.ino
82 lines (69 loc) · 2.47 KB
/
ADC.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
//******************************************************************************************
// Read the internal chip temperature by referencing the 1.1v internal reference voltage
// WARNING >>>> This will only work for ATmega328 types <<<<
//******************************************************************************************
#if defined(USE_ATMEGA328)
int8_t ReadTemp(void)
{
unsigned int wADC;
float t;
// The internal temperature has to be used
// with the internal reference of 1.1V.
// Set the internal reference and mux.
ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
ADCSRA |= _BV(ADEN); // enable the ADC
delay(10); // wait for voltages to become stable.
ADCSRA |= _BV(ADSC); // Start the ADC
// Detect end-of-conversion
while (bit_is_set(ADCSRA,ADSC));
// Reading register "ADCW" takes care of how to read ADCL and ADCH.
wADC = ADCW;
// The offset of 324.31 could be wrong. It is just an indication.
t = (wADC - 324.31 ) / 1.22;
// The returned temperature is in degrees Celcius.
return int8_t(t);
}
#else
int8_t ReadTemp(void)
{
// Create your own ReadTemp function if your are not using an ATMEGA328 chip
return 0;
}
#endif
//******************************************************************************************
// Read the VCC voltage by referencing the 1.1v internal reference
// Useful for checking battery voltage.
// WARNING >>>> This will only work for ATmega328 types <<<<
//******************************************************************************************
#if defined(USE_ATMEGA328)
uint8_t ReadVCC()
{
long result;
long avgmv = 0;
const int reps = 10;
float volts;
// Measure the voltage 10 times and take average
for (int i = 1; i <= reps; i++ )
{
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(10); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Enable the ADC
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
avgmv+=result;
}
// This is the internal voltage in Volts
volts = (avgmv / reps / 1000.0) + VCC_OFFSET;
// Now we have to change it to Horus values and return it
return uint8_t(volts / (5.0 / 256.0));
}
#else
uint8_t ReadVCC()
{
// Create your own ReadVCC function if your are not using an ATMEGA328 chip
return 0;
}
#endif