-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathESP_SHD_Button.cpp
129 lines (111 loc) · 3.73 KB
/
ESP_SHD_Button.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
#include "ESP_SHD_Button.h"
uint8_t ShdButton::numberOfButtons = 0;
ShdButton::ShdButton(uint8_t _pin, bool _lowActive, uint32_t _millisDebounce, uint32_t _millisLongClick, uint32_t _millisMultiClick){
pin = _pin;
lowActive = _lowActive;
numberOfButtons++;
clickCounter = 0;
currentlyClicked = false;
firstClickTime = 0;
lastInterruptTime = 0;
millisDebounce = _millisDebounce;
millisLongClick = _millisLongClick;
millisMultiClick = _millisMultiClick;
pinMode(pin, INPUT_PULLUP);
attachInterrupt(pin, std::bind(&ShdButton::handleInterrupt, this), CHANGE);
snprintf (pubTopic, 50, "%s/Button/%d", name, numberOfButtons);
singleClickCallback = NULL;
doubleClickCallback = NULL;
longClickCallback = NULL;
singleClickObject = NULL;
doubleClickObject = NULL;
longClickObject = NULL;
// debug output:
Serial.print("BTN: New button registered. It publishes to ");
Serial.print(pubTopic);
Serial.println();
}
void ShdButton::handleInterrupt(){
uint32_t currentMillis = millis();
if (digitalRead(pin) != lowActive && currentMillis - lastInterruptTime > millisDebounce) { // Button is now clicked and not in bounce time
lastInterruptTime = currentMillis;
currentlyClicked = true;
clickCounter++;
if (currentMillis - firstClickTime > millisMultiClick) {
firstClickTime = currentMillis;
}
} else {
currentlyClicked = false;
}
}
void ShdButton::timer5msHandler(){
if (clickCounter > 0) {
uint32_t currentMillis = millis();
if (clickCounter == 1 && currentlyClicked == false && currentMillis - firstClickTime > millisMultiClick) {
if (singleClickCallback == NULL) {
if (mqttPublish(pubTopic, "1")) {
#if DEBUG > 1
Serial.print("BTN: Button event has been published to ");
Serial.print(pubTopic);
Serial.print(" at ");
Serial.print(millis());
Serial.print(" value: ");
Serial.println("1");
#endif
}
} else {
singleClickCallback(singleClickObject);
#if DEBUG > 1
#endif
}
clickCounter = 0;
} else if (clickCounter >= 2 && currentlyClicked == false && currentMillis - firstClickTime > millisMultiClick){
if (doubleClickCallback) {
/* code */
}
if (mqttPublish(pubTopic, "2")) {
#if DEBUG > 1
Serial.print("BTN: Button event has been published to ");
Serial.print(pubTopic);
Serial.print(" at ");
Serial.print(millis());
Serial.print(" value: ");
Serial.println("2");
#endif
}
clickCounter = 0;
} else if (clickCounter == 1 && currentlyClicked == true && currentMillis - firstClickTime > millisLongClick) {
if (mqttPublish(pubTopic, "L")) {
#if DEBUG > 1
Serial.print("BTN: Button event has been published to ");
Serial.print(pubTopic);
Serial.print(" at ");
Serial.print(millis());
Serial.print(" value: ");
Serial.println("L");
#endif
}
clickCounter = 0;
}
} else {
return;
}
}
bool ShdButton::handleMqttRequest(char *_topic, unsigned char *_payload, uint16_t _length){
return false;
}
void ShdButton::setSingleClickCallback(void (*_singleClickCallback)(void *), void *_objectPointer) {
singleClickObject = _objectPointer;
singleClickCallback = _singleClickCallback;
}
void ShdButton::setDoubleClickCallback(void (*_doubleClickCallback)(void *), void *_objectPointer) {
doubleClickObject = _objectPointer;
doubleClickCallback = _doubleClickCallback;
}
void ShdButton::setLongClickCallback(void (*_longClickCallback)(void *), void *_objectPointer) {
longClickObject = _objectPointer;
longClickCallback = _longClickCallback;
}
void ShdButton::republish(){
return;
}