-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSwitch.cpp
140 lines (118 loc) · 3.84 KB
/
Switch.cpp
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
#include "WHSR.h"
// For copy & paste
#if defined(ARDUINO_AVR_NANO)
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
#endif
#define SWITCH_ADC_PULLUP 11 // D11, Pin 14, BINT
#define SWITCH_PIN A2 // A2 = D16 = ADC[2], BUT
// switchInterruptAktiv == 0: Kein Tastendruck erkannt
// switchInterruptAktiv == 2: Tastendruck im Interrupt erkannt, muss noch abgearbeitet werden
// switchInterruptAktiv == 3: Tastendruck im Interrupt erkannt, ist abgearbeitet
volatile unsigned char switchInterruptAktiv = 0;
//
// Initialisiert die Kollisionserkennung
//
void WHSR::initSwitches(void)
{
// Switch-Messschaltung aktivieren
pinMode(SWITCH_ADC_PULLUP, OUTPUT);
digitalWrite(SWITCH_ADC_PULLUP, LOW);
}
//
// Liest die Taster für die Kollisionserkennung aus
//
unsigned char WHSR::readSwitches(void)
{
if(switchInterruptAktiv == 2)
{
switchInterruptAktiv = 3;
return switchValue;
}
else
{
#if defined(ARDUINO_AVR_NANO)
DoCheckADCMode(SWITCH_ADC);
long adcValue = mySensorValues[SWITCH_ADC];
adcValue = adcValue == 0 ? 1 : adcValue; // Don't divide by zero
return (unsigned char)(((10160000L / adcValue - 10000L) * SwitchFactor + 5000L) / 10000);
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
long adcValue = analogRead(SWITCH_ADC);
DebugSerial_print("SWITCH_ADC: ");
DebugSerial_println(adcValue);
adcValue = adcValue == 0 ? 1 : adcValue; // Don't divide by zero
return (unsigned char)(((10160000L / adcValue - 10000L) * SwitchFactor + 5000L) / 10000);
#endif
}
}
//
// Turn On the PinChange Interrupt
//
void WHSR::switchInterruptOn(void)
{
// Messschaltung deaktivieren, SWITCH_PIN wird zum digitalen Eingang
digitalWrite(SWITCH_ADC_PULLUP, HIGH);
delay(2);
#if defined(ARDUINO_AVR_NANO)
byte pin = SWITCH_PIN;
*digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin
PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
// Interrupt for switches
pinMode(SWITCH_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(SWITCH_PIN), SwitchISR, CHANGE);
#endif
SWITCH_INTERRUPT_STATE = SWITCH_INTERRUPT_IDLE;
}
//
// Turn Off the PinChange Interrupt
//
void WHSR::switchInterruptOff(void)
{
// Messschaltung aktivieren, SWITCH_PIN wird zum analogen Eingang
digitalWrite(SWITCH_ADC_PULLUP, LOW);
delay(2);
#if defined(ARDUINO_AVR_NANO)
byte pin = SWITCH_PIN;
PCICR &= ~bit (digitalPinToPCICRbit(pin)); // disable interrupt for the group
#elif defined(ARDUINO_ARDUINO_NANO33BLE)
detachInterrupt(digitalPinToInterrupt(SWITCH_PIN));
#endif
SWITCH_INTERRUPT_STATE = SWITCH_INTERRUPT_NONE;
}
//
// Return true if Switch was pressed
//
bool WHSR::switchAvailable()
{
return switchInterruptAktiv == 2 ? true : false;
}
//
// Pin Change Interrupt Service Routine
//
void WHSR::switchInterrupt(void)
{
// Interrupts sind deaktiviert beim Eintritt in ISR
// Interrupt verhindern wenn
if(switchInterruptAktiv == 3 && digitalRead(SWITCH_PIN) == HIGH)
{
switchInterruptAktiv = 0;
return;
}
if(switchInterruptAktiv != 0 || // Wenn schon einmal ein Button gedrückt wurde oder
digitalRead(SWITCH_PIN) == HIGH) // wenn kein Button gedrückt wurde
return;
++switchInterruptAktiv;
noInterrupts();
// Ausschalten, damit der analoge Wert gelesen werden kann
switchInterruptOff();
switchValue = 0;
//unsigned long startMillis = millis(); //Aktuellen Zeitstempel speichern
//while (switchValue == 0 && (millis() - startMillis < 1000))
switchValue = readSwitches();
// Wieder einschalten
switchInterruptOn();
++switchInterruptAktiv;
interrupts();
// Interrupts werden nach ISR aktiviert
}