Repository navigation
Expand file tree
/
Copy pathADC.cpp
More file actions
181 lines (152 loc) · 4.23 KB
/
Copy pathADC.cpp
File metadata and controls
181 lines (152 loc) · 4.23 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include "WHSR.h"
// Hier wird der ADC-Wert gespeichert, wenn wir die Arduino-Routinen für Nano 33 BLE nutzen
// (Äquivalent zum ADC-Register des Nano)
volatile int ADCvalue = 0;
/* ************************************************************************************
*
* Init + Interrupt
*
* ************************************************************************************ */
//
// Init ADC
//
void WHSR::initADC(void)
{
#if defined(ARDUINO_AVR_NANO)
ADCPos = 0;
ADMUX = (0<<REFS1) | (1<<REFS0) | // ReferenzSpannung 01 -> Extern
(0<<ADLAR) | // Bit Orientierung 10 Bit in 2 Byte -> Right
(0<<MUX3) | (0<<MUX2) | // Bits zum Selektieren des Channels
(0<<MUX1) | (0<<MUX0); // Channel 0
ADCSRA = (1<<ADEN) | // Enables ADC
(0<<ADSC) | // Start ADC
(0<<ADATE) | // Enable Edge Rise Interrupt
(0<<ADIF) | // Flag Conversion Finished
(1<<ADIE) | // Enables Interrupt
(1<<ADPS2) | (1<<ADPS1) | // Select Prescaler
(1<<ADPS0); // 111 -> 128
// 50KHz < FCPU / Prescaler < 200Khz
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
// The nRF52840 ADC defaults to 12-bit resolution (0-4095).
// All library calculations assume 10-bit (0-1023), so force 10-bit here.
analogReadResolution(10);
// Reference is VDD (3.3V) by default; make it explicit.
analogReference(AR_VDD);
#endif
}
//
// ADC Start Next
// Sobald ein Channel gelesen wurde wird der nächste gestartet
//
void WHSR::ADCStartNext(void)
{
++ADCPos;
if((switchInterruptState & 0b1) == 0
&& ADCPos == SWITCH_ADC) // Switches überspringen
++ADCPos;
if(ADCPos >= MAX_ADC_CHANNELS)
{
ADCPos = 0;
if(switchInterruptState == SWITCH_INTERRUPT_WAIT)
switchInterruptState = SWITCH_INTERRUPT_DO;
ADCBlockPassed = true;
if(ADCMode == ADC_MODE_BLOCK)
return;
}
SetADMUX(ADCPos);
}
//
// ADC Start
// Lese Channel X
//
void WHSR::ADCStart(char Channel)
{
ADCPos = Channel; // % MAX_ADC_CHANNELS;
SetADMUX(ADCPos);
#if defined(ARDUINO_AVR_NANO)
delayMicroseconds(100);
ADCSRA |= (1 << ADSC); // Start ADC
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
ADCvalue = analogRead(ADCPos); // Direkt auslesen
#endif
}
//
// ADC Wait for Block
// Warte bis der komplette Block gelesen wurde
// Block => Alle 9 Kanäle
//
bool WHSR::ADCWaitForBlock(void)
{
if(ADCBlockPassed)
{
ADCBlockPassed = false;
return true;
}
return false;
}
//
// ADC Wait For Conversion
// Für Einzellesungen warten bis ADC beendet ist
//
void WHSR::ADCWaitForConversion(void)
{
#if defined(ARDUINO_AVR_NANO)
while (bit_is_set(ADCSRA, ADSC)) // ADC Status Register ADC Start Conversion ist 1 während Umwandlung
;
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
// Direkt zurückkommen
#endif
}
//
// ADC Interrupt Routine
// Für Einzellesungen warten bis ADC beendet ist
//
void WHSR::ADCInterrupt(void)
{
// Ergebnis der Wandlung im Sensor-Array speichern
#if defined(ARDUINO_AVR_NANO)
mySensorValues[ADCPos] = ADC;
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
mySensorValues[ADCPos] = ADCvalue;
#endif
/*
DebugSerial_print(ADCPos, DEC);
DebugSerial_print(" ");
DebugSerial_println(mySensorValues[ADCPos]);
*/
if(ADCPos == SWITCH_ADC)
switchInterruptState = SWITCH_INTERRUPT_IDLE;
if(ADCMode == ADC_MODE_BLOCK)
ADCStartNext();
}
//
// Setze den AD-Kanal
//
void WHSR::SetADMUX(char pin)
{
#if defined(ARDUINO_AVR_NANO)
if (pin == 0b1000) // 8 -> 14 TODO: Wozu das??
pin = 0b1110;
ADMUX &= 0xf0; // Kanal-Bits auf null setzen
ADMUX |= (pin & 0b1111); // Gewünschten Kanal wählen
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
// Bei der Nano 33 BLE wird der Kanal direkt an analogRead übergeben,
// hier muss nichts eingestellt werden
#endif
}
//
// ADC-Test mit Debug-Ausgabe
//
void WHSR::DoCheckADCMode(char channel)
{
if(ADCMode == ADC_MODE_NONE)
{
ADCStart(channel);
ADCWaitForConversion();
DebugSerial_print(" ");
DebugSerial_print(channel, DEC);
DebugSerial_print(": ");
DebugSerial_print(mySensorValues[channel]);
DebugSerial_print(". ");
}
}